e46f53ebf552e9f8b8307fc1717d1b0d85af2f78
[honeycomb.git] / v3po / v3po2vpp / src / main / java / io / fd / honeycomb / translate / v3po / interfaces / acl / IetfAclWriter.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.translate.v3po.interfaces.acl;
18
19 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
20 import io.fd.honeycomb.translate.write.WriteContext;
21 import io.fd.honeycomb.translate.write.WriteFailedException;
22 import java.util.Optional;
23 import java.util.stream.Stream;
24 import javax.annotation.Nonnull;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * Writer customizer responsible for Access Control Lists management. Does not send any messages to VPP. All the config
37  * data are stored in HC and used when acl is assigned/unassigned to/from an interface.
38  *
39  * ACLs that are currently assigned to an interface cannot be updated/deleted.
40  */
41 public class IetfAclWriter implements ListWriterCustomizer<Acl, AclKey> {
42
43     public static final InstanceIdentifier<AccessLists> ACL_ID =
44         InstanceIdentifier.create(AccessLists.class);
45
46     private static final Logger LOG = LoggerFactory.getLogger(IetfAclWriter.class);
47
48     @Override
49     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataAfter,
50                                        @Nonnull final WriteContext writeContext) throws WriteFailedException {
51         LOG.debug("Creating ACL: iid={} dataAfter={}", id, dataAfter);
52
53         // no vpp call, just updates DataTree
54     }
55
56     @Override
57     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
58                                         @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext)
59         throws WriteFailedException {
60         LOG.debug("Updating ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter);
61
62         if (isAssigned(dataAfter, writeContext)) {
63             throw new WriteFailedException(id,
64                 String.format("Failed to update data at %s: acl %s is already assigned", id, dataAfter));
65         }
66
67         LOG.debug("Updating unassigned ACL: iid={} dataBefore={} dataAfter={}", id, dataBefore, dataAfter);
68
69         // no vpp call, just updates DataTree
70     }
71
72     @Override
73     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
74                                         @Nonnull final WriteContext writeContext) throws WriteFailedException {
75         LOG.debug("Deleting ACL: iid={} dataBefore={}", id, dataBefore);
76
77         if (isAssigned(dataBefore, writeContext)) {
78             throw new WriteFailedException(id,
79                 String.format("Failed to delete data at %s: acl %s is already assigned", id, dataBefore));
80         }
81
82         LOG.debug("Deleting unassigned ACL: iid={} dataBefore={}", id, dataBefore);
83
84         // no vpp call, just updates DataTree
85     }
86
87     private static boolean isAssigned(@Nonnull final Acl acl,
88                                       @Nonnull final WriteContext writeContext) {
89         final String aclName = acl.getAclName();
90         final Class<? extends AclBase> aclType = acl.getAclType();
91         final Interfaces interfaces = writeContext.readAfter(InstanceIdentifier.create(Interfaces.class)).get();
92
93         return interfaces.getInterface().stream()
94             .map(i -> Optional.ofNullable(i.getAugmentation(VppInterfaceAugmentation.class))
95                 .map(aug -> aug.getIetfAcl())
96                 .map(ietfAcl -> ietfAcl.getIngress())
97                 .map(ingress -> ingress.getAccessLists())
98                 .map(accessLists -> accessLists.getAcl())
99             )
100             .flatMap(iacl -> iacl.isPresent()
101                 ? iacl.get().stream()
102                 : Stream.empty())
103             .filter(assignedAcl -> aclName.equals(assignedAcl.getName()) && aclType.equals(assignedAcl.getType()))
104             .findFirst().isPresent();
105     }
106 }