blob: 1ae751313d20c479ab5957f3a00a98b8ddd824f3 [file] [log] [blame]
sangho6a9ff0d2017-03-27 11:23:37 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
sangho6a9ff0d2017-03-27 11:23:37 +09003 *
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 */
16package org.onosproject.openstacknetworking.impl;
17
sangho6a9ff0d2017-03-27 11:23:37 +090018import com.google.common.base.Strings;
sangho6a9ff0d2017-03-27 11:23:37 +090019import org.onosproject.core.CoreService;
20import org.onosproject.event.ListenerRegistry;
21import org.onosproject.openstacknetworking.api.Constants;
22import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupAdminService;
23import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupEvent;
24import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupListener;
25import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
26import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupStore;
27import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupStoreDelegate;
28import org.openstack4j.model.network.SecurityGroup;
29import org.openstack4j.model.network.SecurityGroupRule;
30import org.openstack4j.openstack.networking.domain.NeutronSecurityGroup;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070031import org.osgi.service.component.annotations.Activate;
32import org.osgi.service.component.annotations.Component;
33import org.osgi.service.component.annotations.Deactivate;
34import org.osgi.service.component.annotations.Reference;
35import org.osgi.service.component.annotations.ReferenceCardinality;
sangho6a9ff0d2017-03-27 11:23:37 +090036import org.slf4j.Logger;
37
38import java.util.List;
Hyunsun Moonae51e732017-04-25 17:46:21 +090039import java.util.Objects;
40import java.util.Set;
sangho6a9ff0d2017-03-27 11:23:37 +090041
42import static com.google.common.base.Preconditions.checkArgument;
43import static com.google.common.base.Preconditions.checkNotNull;
44import static org.slf4j.LoggerFactory.getLogger;
45
46/**
Hyunsun Moonae51e732017-04-25 17:46:21 +090047 * Provides implementation of administering and interfacing OpenStack security
sangho6a9ff0d2017-03-27 11:23:37 +090048 * groups.
sangho6a9ff0d2017-03-27 11:23:37 +090049 */
Jian Li5ecfd1a2018-12-10 11:41:03 +090050@Component(
51 immediate = true,
52 service = { OpenstackSecurityGroupAdminService.class, OpenstackSecurityGroupService.class }
53)
sangho6a9ff0d2017-03-27 11:23:37 +090054public class OpenstackSecurityGroupManager
55 extends ListenerRegistry<OpenstackSecurityGroupEvent, OpenstackSecurityGroupListener>
56 implements OpenstackSecurityGroupAdminService, OpenstackSecurityGroupService {
57
58 protected final Logger log = getLogger(getClass());
59
60 private static final String MSG_SG = "OpenStack security group %s %s";
Hyunsun Moonae51e732017-04-25 17:46:21 +090061 private static final String MSG_SG_RULE = "OpenStack security group rule %s %s";
sangho6a9ff0d2017-03-27 11:23:37 +090062
63 private static final String MSG_CREATED = "created";
64 private static final String MSG_REMOVED = "removed";
65
Jian Li5ecfd1a2018-12-10 11:41:03 +090066 private static final String ERR_NULL_SG =
67 "OpenStack security group cannot be null";
68 private static final String ERR_NULL_SG_ID =
69 "OpenStack security group ID cannot be null";
70 private static final String ERR_NULL_SG_RULE =
71 "OpenStack security group rule cannot be null";
72 private static final String ERR_NULL_SG_RULE_ID =
73 "OpenStack security group rule ID cannot be null";
Hyunsun Moonae51e732017-04-25 17:46:21 +090074 private static final String ERR_NOT_FOUND = "not found";
75 private static final String ERR_DUPLICATE = "already exist";
sangho6a9ff0d2017-03-27 11:23:37 +090076
sanghoe6457a32017-08-24 14:31:19 +090077 private boolean useSecurityGroup = false;
78
Ray Milkeyd84f89b2018-08-17 14:54:17 -070079 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +090080 protected CoreService coreService;
81
Ray Milkeyd84f89b2018-08-17 14:54:17 -070082 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +090083 protected OpenstackSecurityGroupStore osSecurityGroupStore;
84
Jian Li5ecfd1a2018-12-10 11:41:03 +090085 private final OpenstackSecurityGroupStoreDelegate
86 delegate = new InternalSecurityGroupStoreDelegate();
sangho6a9ff0d2017-03-27 11:23:37 +090087
88 @Activate
89 protected void activate() {
90 coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
91 osSecurityGroupStore.setDelegate(delegate);
92 log.info("Started");
93 }
94
95 @Deactivate
96 protected void deactivate() {
97 osSecurityGroupStore.unsetDelegate(delegate);
98 log.info("Stopped");
99 }
100
101 @Override
102 public void createSecurityGroup(SecurityGroup sg) {
103 checkNotNull(sg, ERR_NULL_SG);
104 checkArgument(!Strings.isNullOrEmpty(sg.getId()), ERR_NULL_SG_ID);
105
106 osSecurityGroupStore.createSecurityGroup(sg);
107 log.info(String.format(MSG_SG, sg.getId(), MSG_CREATED));
108 }
109
110 @Override
Hyunsun Moonae51e732017-04-25 17:46:21 +0900111 public void updateSecurityGroup(SecurityGroup sg) {
112 checkNotNull(sg, ERR_NULL_SG);
113 checkArgument(!Strings.isNullOrEmpty(sg.getId()), ERR_NULL_SG_ID);
114
115 osSecurityGroupStore.updateSecurityGroup(sg);
116 }
117
118 @Override
sangho6a9ff0d2017-03-27 11:23:37 +0900119 public void removeSecurityGroup(String sgId) {
Jian Li43e066b2018-07-16 17:43:56 +0900120 checkArgument(!Strings.isNullOrEmpty(sgId), ERR_NULL_SG_ID);
sangho6a9ff0d2017-03-27 11:23:37 +0900121
122 osSecurityGroupStore.removeSecurityGroup(sgId);
123 log.info(String.format(MSG_SG, sgId, MSG_REMOVED));
124 }
125
126 @Override
127 public void createSecurityGroupRule(SecurityGroupRule sgRule) {
128 checkNotNull(sgRule, ERR_NULL_SG_RULE);
129 checkArgument(!Strings.isNullOrEmpty(sgRule.getId()), ERR_NULL_SG_RULE_ID);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900130 checkArgument(!Strings.isNullOrEmpty(sgRule.getSecurityGroupId()), ERR_NULL_SG_ID);
sangho6a9ff0d2017-03-27 11:23:37 +0900131
Hyunsun Moonae51e732017-04-25 17:46:21 +0900132 synchronized (this) {
sangho6a9ff0d2017-03-27 11:23:37 +0900133 SecurityGroup sg = securityGroup(sgRule.getSecurityGroupId());
Hyunsun Moonae51e732017-04-25 17:46:21 +0900134 if (sg == null) {
Jian Li5ecfd1a2018-12-10 11:41:03 +0900135 final String error = String.format(MSG_SG,
136 sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900137 throw new IllegalStateException(error);
138 }
Jian Li5ecfd1a2018-12-10 11:41:03 +0900139 if (sg.getRules().stream().anyMatch(rule ->
140 Objects.equals(rule.getId(), sgRule.getId()))) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900141 final String error = String.format(MSG_SG_RULE,
142 sgRule.getSecurityGroupId(), ERR_DUPLICATE);
143 throw new IllegalStateException(error);
sangho6a9ff0d2017-03-27 11:23:37 +0900144 }
145
Hyunsun Moonae51e732017-04-25 17:46:21 +0900146 // FIXME we cannot add element to extend list
147 List updatedSgRules = sg.getRules();
148 updatedSgRules.add(sgRule);
149 SecurityGroup updatedSg = NeutronSecurityGroup.builder().from(sg).build();
150 osSecurityGroupStore.updateSecurityGroup(updatedSg);
sangho6a9ff0d2017-03-27 11:23:37 +0900151 }
Hyunsun Moonae51e732017-04-25 17:46:21 +0900152
153 log.info(String.format(MSG_SG_RULE, sgRule.getId(), MSG_CREATED));
sangho6a9ff0d2017-03-27 11:23:37 +0900154 }
155
156 @Override
157 public void removeSecurityGroupRule(String sgRuleId) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900158 checkArgument(!Strings.isNullOrEmpty(sgRuleId), ERR_NULL_SG_RULE_ID);
sangho6a9ff0d2017-03-27 11:23:37 +0900159
Hyunsun Moonae51e732017-04-25 17:46:21 +0900160 synchronized (this) {
161 SecurityGroupRule sgRule = securityGroupRule(sgRuleId);
162 if (sgRule == null) {
163 final String error = String.format(MSG_SG_RULE, sgRuleId, ERR_NOT_FOUND);
164 throw new IllegalStateException(error);
165 }
166
167 SecurityGroup sg = securityGroup(sgRule.getSecurityGroupId());
168 if (sg == null) {
Jian Li5ecfd1a2018-12-10 11:41:03 +0900169 final String error = String.format(MSG_SG,
170 sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900171 throw new IllegalStateException(error);
172 }
173
Jian Li5ecfd1a2018-12-10 11:41:03 +0900174 if (sg.getRules().stream().noneMatch(rule ->
175 Objects.equals(rule.getId(), sgRule.getId()))) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900176 final String error = String.format(MSG_SG_RULE,
177 sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
178 throw new IllegalStateException(error);
179 }
180
181 // FIXME we cannot handle the element of extend list as a specific class object
182 List updatedSgRules = sg.getRules();
183 updatedSgRules.removeIf(r -> ((SecurityGroupRule) r).getId().equals(sgRuleId));
184 SecurityGroup updatedSg = NeutronSecurityGroup.builder().from(sg).build();
185 osSecurityGroupStore.updateSecurityGroup(updatedSg);
186 }
187
sangho6a9ff0d2017-03-27 11:23:37 +0900188 log.info(String.format(MSG_SG_RULE, sgRuleId, MSG_REMOVED));
189 }
190
191 @Override
Hyunsun Moonae51e732017-04-25 17:46:21 +0900192 public Set<SecurityGroup> securityGroups() {
193 return osSecurityGroupStore.securityGroups();
194 }
195
196 @Override
sangho6a9ff0d2017-03-27 11:23:37 +0900197 public SecurityGroup securityGroup(String sgId) {
198 checkArgument(!Strings.isNullOrEmpty(sgId), ERR_NULL_SG_ID);
199 return osSecurityGroupStore.securityGroup(sgId);
200 }
201
202 @Override
sanghoe6457a32017-08-24 14:31:19 +0900203 public boolean isSecurityGroupEnabled() {
204 return useSecurityGroup;
205 }
206
207 @Override
208 public void setSecurityGroupEnabled(boolean option) {
209 useSecurityGroup = option;
210 }
211
212 @Override
Hyunsun Moonae51e732017-04-25 17:46:21 +0900213 public void clear() {
214 osSecurityGroupStore.clear();
215 }
216
217 private SecurityGroupRule securityGroupRule(String sgRuleId) {
218 return osSecurityGroupStore.securityGroups().stream()
219 .flatMap(sg -> sg.getRules().stream())
220 .filter(sgRule -> Objects.equals(sgRule.getId(), sgRuleId))
221 .findFirst().orElse(null);
sangho6a9ff0d2017-03-27 11:23:37 +0900222 }
223
Jian Li5ecfd1a2018-12-10 11:41:03 +0900224 private class InternalSecurityGroupStoreDelegate
225 implements OpenstackSecurityGroupStoreDelegate {
sangho6a9ff0d2017-03-27 11:23:37 +0900226
227 @Override
228 public void notify(OpenstackSecurityGroupEvent event) {
229 if (event != null) {
230 log.trace("send openstack security group event {}", event);
231 process(event);
232 }
233 }
234 }
235}