Switch to JDT annotations for Nullable and NonNull
[netvirt.git] / coe / impl / src / main / java / org / opendaylight / netvirt / coe / utils / AceNetworkPolicyUtils.java
1 /*
2  * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netvirt.coe.utils;
9
10 import static org.opendaylight.netvirt.coe.utils.AclUtils.DIRECTION_MAP;
11 import static org.opendaylight.netvirt.coe.utils.AclUtils.buildName;
12 import static org.opendaylight.netvirt.coe.utils.NetworkPolicyUtils.PROTOCOL_MAP;
13
14 import java.util.ArrayList;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclBuilder;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntriesBuilder;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceBuilder;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceKey;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.ActionsBuilder;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.MatchesBuilder;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.egress.rule.NetworkPolicyEgressRule;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.egress.rule.network.policy.egress.rule.EgressPorts;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.egress.rule.network.policy.egress.rule.To;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.ingress.rule.NetworkPolicyIngressRule;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.ingress.rule.network.policy.ingress.rule.From;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.ingress.rule.network.policy.ingress.rule.IngressPorts;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.network.policies.NetworkPolicy;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.peer.NetworkPolicyPeer;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.port.NetworkPolicyPort;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.NetworkPolicySpec;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.network.policy.spec.Egress;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.k8s.network.policy.rev181205.network.policy.spec.network.policy.spec.Ingress;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttrBuilder;
49
50 public final class AceNetworkPolicyUtils {
51     private AceNetworkPolicyUtils() {}
52
53     @NonNull
54     public static String getAclNameFromPolicy(@NonNull NetworkPolicy policy) {
55         String aclName = "";
56         if (policy.getUuid() != null) {
57             aclName = policy.getUuid().getValue();
58         }
59         return aclName;
60     }
61
62     // TODO map empty rules:
63     // ingress:empty - no incoming allowed
64     // egress:empty - no outgoing allowed
65     @NonNull
66     public static Acl buildAcl(@NonNull NetworkPolicy policy, boolean isDeleted) {
67         String aclName = getAclNameFromPolicy(policy);
68         ArrayList<Ace> aceList = new ArrayList<>();
69
70         if (policy.getNetworkPolicySpec() != null) {
71             NetworkPolicySpec spec = policy.getNetworkPolicySpec();
72             if (spec.getIngress() != null) {
73                 for (Ingress ingress : spec.getIngress()) {
74                     NetworkPolicyIngressRule rule = ingress.getNetworkPolicyIngressRule();
75                     if (rule.getIngressPorts() != null) {
76                         for (IngressPorts port : rule.getIngressPorts()) {
77                             if (port.getNetworkPolicyPort() != null) {
78                                 Ace ace = buildPortAce(isDeleted, aclName,
79                                     DirectionIngress.class, port.getNetworkPolicyPort());
80                                 aceList.add(ace);
81                             }
82                         }
83                     }
84                     if (rule.getFrom() != null) {
85                         for (From from: rule.getFrom()) {
86                             if (from.getNetworkPolicyPeer() != null) {
87                                 Ace ace = buildPolicyAce(isDeleted, aclName,
88                                     DirectionIngress.class, from.getNetworkPolicyPeer());
89                                 aceList.add(ace);
90                             }
91                         }
92                     }
93                 }
94             }
95
96             if (spec.getEgress() != null) {
97                 for (Egress egress : spec.getEgress()) {
98                     NetworkPolicyEgressRule rule = egress.getNetworkPolicyEgressRule();
99                     if (rule.getEgressPorts() != null) {
100                         for (EgressPorts port : rule.getEgressPorts()) {
101                             if (port.getNetworkPolicyPort() != null) {
102                                 Ace ace = buildPortAce(isDeleted, aclName,
103                                     DirectionEgress.class, port.getNetworkPolicyPort());
104                                 aceList.add(ace);
105                             }
106                         }
107                     }
108                     if (rule.getTo() != null) {
109                         for (To to: rule.getTo()) {
110                             if (to.getNetworkPolicyPeer() != null) {
111                                 Ace ace = buildPolicyAce(isDeleted, aclName,
112                                     DirectionEgress.class, to.getNetworkPolicyPeer());
113                                 aceList.add(ace);
114                             }
115                         }
116                     }
117                 }
118             }
119         }
120
121         AccessListEntriesBuilder accessListEntriesBuilder = new AccessListEntriesBuilder();
122         accessListEntriesBuilder.setAce(aceList);
123
124         AclBuilder aclBuilder = new AclBuilder();
125         aclBuilder.setAclName(aclName);
126         aclBuilder.setAclType(Ipv4Acl.class);
127         aclBuilder.setAccessListEntries(accessListEntriesBuilder.build());
128         aclBuilder.withKey(new AclKey(aclBuilder.getAclName(), aclBuilder.getAclType()));
129         return aclBuilder.build();
130     }
131
132     @NonNull
133     public static AceBuilder getAceBuilder(boolean isDeleted, String ruleName,
134                                            @NonNull Class<? extends DirectionBase> direction,
135                                            @NonNull AceIpBuilder aceIpBuilder) {
136         MatchesBuilder matchesBuilder = new MatchesBuilder();
137         matchesBuilder.setAceType(aceIpBuilder.build());
138         ActionsBuilder actionsBuilder = new ActionsBuilder();
139         actionsBuilder.setPacketHandling(new PermitBuilder().setPermit(true).build());
140
141         AceBuilder aceBuilder = new AceBuilder();
142         aceBuilder.setRuleName(ruleName);
143         aceBuilder.withKey(new AceKey(aceBuilder.getRuleName()));
144         aceBuilder.setMatches(matchesBuilder.build());
145         aceBuilder.setActions(actionsBuilder.build());
146
147         SecurityRuleAttrBuilder securityRuleAttrBuilder = new SecurityRuleAttrBuilder();
148         securityRuleAttrBuilder.setDeleted(isDeleted);
149         securityRuleAttrBuilder.setDirection(direction);
150         aceBuilder.addAugmentation(SecurityRuleAttr.class, securityRuleAttrBuilder.build());
151         return aceBuilder;
152     }
153
154     @NonNull
155     public static Ace buildPortAce(boolean isDeleted, @NonNull String aclName,
156                                    @NonNull Class<? extends DirectionBase> direction,
157                                    @NonNull NetworkPolicyPort port) {
158         AceIpBuilder aceIpBuilder = new AceIpBuilder();
159         String ruleName = AclUtils.buildName(aclName, DIRECTION_MAP.get(direction), "port");
160         if (port.getProtocol() != null) {
161             aceIpBuilder.setProtocol(PROTOCOL_MAP.get(port.getProtocol()));
162             ruleName = buildName(ruleName, port.getProtocol().toString());
163         }
164
165         // TODO: map a named port
166         if (port.getPort() != null) {
167             DestinationPortRangeBuilder portRangeBuilder = new DestinationPortRangeBuilder();
168             PortNumber portNumber = new PortNumber(Integer.parseInt(port.getPort()));
169             portRangeBuilder.setLowerPort(portNumber);
170             portRangeBuilder.setUpperPort(portNumber);
171             aceIpBuilder.setDestinationPortRange(portRangeBuilder.build());
172             ruleName = buildName(ruleName, portNumber.getValue().toString());
173         }
174
175         AceBuilder aceBuilder = getAceBuilder(isDeleted, ruleName, direction, aceIpBuilder);
176
177         return aceBuilder.build();
178     }
179
180     @NonNull
181     public static Ace buildPolicyAce(boolean isDeleted, @NonNull String aclName,
182                                      @NonNull Class<? extends DirectionBase> direction,
183                                      @NonNull NetworkPolicyPeer peer) {
184         AceIpBuilder aceIpBuilder = new AceIpBuilder();
185         String ruleName = AclUtils.buildName(aclName, DIRECTION_MAP.get(direction), "peer");
186
187         if (peer.getIpBlock() != null) {
188             // TODO handle except
189             String  cidr = peer.getIpBlock().getCidr();
190             ruleName = AclUtils.buildName(ruleName, "cidr", cidr);
191             AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
192             if (direction == DirectionIngress.class) {
193                 aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(cidr));
194             } else {
195                 aceIpv4Builder.setDestinationIpv4Network(new Ipv4Prefix(cidr));
196             }
197             aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
198         }
199         // TODO handle pod-selector and namespace-selector
200
201         AceBuilder aceBuilder = getAceBuilder(isDeleted, ruleName, direction, aceIpBuilder);
202
203         return aceBuilder.build();
204     }
205 }