blob: a6e6e2ae60de6b9d4a1baabe16d923957641f41a [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 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070050@Component(immediate = true, service = { OpenstackSecurityGroupAdminService.class, OpenstackSecurityGroupService.class })
sangho6a9ff0d2017-03-27 11:23:37 +090051public class OpenstackSecurityGroupManager
52 extends ListenerRegistry<OpenstackSecurityGroupEvent, OpenstackSecurityGroupListener>
53 implements OpenstackSecurityGroupAdminService, OpenstackSecurityGroupService {
54
55 protected final Logger log = getLogger(getClass());
56
57 private static final String MSG_SG = "OpenStack security group %s %s";
Hyunsun Moonae51e732017-04-25 17:46:21 +090058 private static final String MSG_SG_RULE = "OpenStack security group rule %s %s";
sangho6a9ff0d2017-03-27 11:23:37 +090059
60 private static final String MSG_CREATED = "created";
61 private static final String MSG_REMOVED = "removed";
62
63 private static final String ERR_NULL_SG = "OpenStack security group cannot be null";
64 private static final String ERR_NULL_SG_ID = "OpenStack security group ID cannot be null";
65 private static final String ERR_NULL_SG_RULE = "OpenStack security group rule cannot be null";
66 private static final String ERR_NULL_SG_RULE_ID = "OpenStack security group rule ID cannot be null";
Hyunsun Moonae51e732017-04-25 17:46:21 +090067 private static final String ERR_NOT_FOUND = "not found";
68 private static final String ERR_DUPLICATE = "already exist";
sangho6a9ff0d2017-03-27 11:23:37 +090069
sanghoe6457a32017-08-24 14:31:19 +090070 private boolean useSecurityGroup = false;
71
Ray Milkeyd84f89b2018-08-17 14:54:17 -070072 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +090073 protected CoreService coreService;
74
Ray Milkeyd84f89b2018-08-17 14:54:17 -070075 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +090076 protected OpenstackSecurityGroupStore osSecurityGroupStore;
77
78 private final OpenstackSecurityGroupStoreDelegate delegate = new InternalSecurityGroupStoreDelegate();
79
80 @Activate
81 protected void activate() {
82 coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
83 osSecurityGroupStore.setDelegate(delegate);
84 log.info("Started");
85 }
86
87 @Deactivate
88 protected void deactivate() {
89 osSecurityGroupStore.unsetDelegate(delegate);
90 log.info("Stopped");
91 }
92
93 @Override
94 public void createSecurityGroup(SecurityGroup sg) {
95 checkNotNull(sg, ERR_NULL_SG);
96 checkArgument(!Strings.isNullOrEmpty(sg.getId()), ERR_NULL_SG_ID);
97
98 osSecurityGroupStore.createSecurityGroup(sg);
99 log.info(String.format(MSG_SG, sg.getId(), MSG_CREATED));
100 }
101
102 @Override
Hyunsun Moonae51e732017-04-25 17:46:21 +0900103 public void updateSecurityGroup(SecurityGroup sg) {
104 checkNotNull(sg, ERR_NULL_SG);
105 checkArgument(!Strings.isNullOrEmpty(sg.getId()), ERR_NULL_SG_ID);
106
107 osSecurityGroupStore.updateSecurityGroup(sg);
108 }
109
110 @Override
sangho6a9ff0d2017-03-27 11:23:37 +0900111 public void removeSecurityGroup(String sgId) {
Jian Li43e066b2018-07-16 17:43:56 +0900112 checkArgument(!Strings.isNullOrEmpty(sgId), ERR_NULL_SG_ID);
sangho6a9ff0d2017-03-27 11:23:37 +0900113
114 osSecurityGroupStore.removeSecurityGroup(sgId);
115 log.info(String.format(MSG_SG, sgId, MSG_REMOVED));
116 }
117
118 @Override
119 public void createSecurityGroupRule(SecurityGroupRule sgRule) {
120 checkNotNull(sgRule, ERR_NULL_SG_RULE);
121 checkArgument(!Strings.isNullOrEmpty(sgRule.getId()), ERR_NULL_SG_RULE_ID);
Hyunsun Moonae51e732017-04-25 17:46:21 +0900122 checkArgument(!Strings.isNullOrEmpty(sgRule.getSecurityGroupId()), ERR_NULL_SG_ID);
sangho6a9ff0d2017-03-27 11:23:37 +0900123
Hyunsun Moonae51e732017-04-25 17:46:21 +0900124 synchronized (this) {
sangho6a9ff0d2017-03-27 11:23:37 +0900125 SecurityGroup sg = securityGroup(sgRule.getSecurityGroupId());
Hyunsun Moonae51e732017-04-25 17:46:21 +0900126 if (sg == null) {
127 final String error = String.format(MSG_SG, sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
128 throw new IllegalStateException(error);
129 }
130 if (sg.getRules().stream().anyMatch(rule -> Objects.equals(rule.getId(), sgRule.getId()))) {
131 final String error = String.format(MSG_SG_RULE,
132 sgRule.getSecurityGroupId(), ERR_DUPLICATE);
133 throw new IllegalStateException(error);
sangho6a9ff0d2017-03-27 11:23:37 +0900134 }
135
Hyunsun Moonae51e732017-04-25 17:46:21 +0900136 // FIXME we cannot add element to extend list
137 List updatedSgRules = sg.getRules();
138 updatedSgRules.add(sgRule);
139 SecurityGroup updatedSg = NeutronSecurityGroup.builder().from(sg).build();
140 osSecurityGroupStore.updateSecurityGroup(updatedSg);
sangho6a9ff0d2017-03-27 11:23:37 +0900141 }
Hyunsun Moonae51e732017-04-25 17:46:21 +0900142
143 log.info(String.format(MSG_SG_RULE, sgRule.getId(), MSG_CREATED));
sangho6a9ff0d2017-03-27 11:23:37 +0900144 }
145
146 @Override
147 public void removeSecurityGroupRule(String sgRuleId) {
Hyunsun Moonae51e732017-04-25 17:46:21 +0900148 checkArgument(!Strings.isNullOrEmpty(sgRuleId), ERR_NULL_SG_RULE_ID);
sangho6a9ff0d2017-03-27 11:23:37 +0900149
Hyunsun Moonae51e732017-04-25 17:46:21 +0900150 synchronized (this) {
151 SecurityGroupRule sgRule = securityGroupRule(sgRuleId);
152 if (sgRule == null) {
153 final String error = String.format(MSG_SG_RULE, sgRuleId, ERR_NOT_FOUND);
154 throw new IllegalStateException(error);
155 }
156
157 SecurityGroup sg = securityGroup(sgRule.getSecurityGroupId());
158 if (sg == null) {
159 final String error = String.format(MSG_SG, sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
160 throw new IllegalStateException(error);
161 }
162
163 if (sg.getRules().stream().noneMatch(rule -> Objects.equals(rule.getId(), sgRule.getId()))) {
164 final String error = String.format(MSG_SG_RULE,
165 sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
166 throw new IllegalStateException(error);
167 }
168
169 // FIXME we cannot handle the element of extend list as a specific class object
170 List updatedSgRules = sg.getRules();
171 updatedSgRules.removeIf(r -> ((SecurityGroupRule) r).getId().equals(sgRuleId));
172 SecurityGroup updatedSg = NeutronSecurityGroup.builder().from(sg).build();
173 osSecurityGroupStore.updateSecurityGroup(updatedSg);
174 }
175
sangho6a9ff0d2017-03-27 11:23:37 +0900176 log.info(String.format(MSG_SG_RULE, sgRuleId, MSG_REMOVED));
177 }
178
179 @Override
Hyunsun Moonae51e732017-04-25 17:46:21 +0900180 public Set<SecurityGroup> securityGroups() {
181 return osSecurityGroupStore.securityGroups();
182 }
183
184 @Override
sangho6a9ff0d2017-03-27 11:23:37 +0900185 public SecurityGroup securityGroup(String sgId) {
186 checkArgument(!Strings.isNullOrEmpty(sgId), ERR_NULL_SG_ID);
187 return osSecurityGroupStore.securityGroup(sgId);
188 }
189
190 @Override
sanghoe6457a32017-08-24 14:31:19 +0900191 public boolean isSecurityGroupEnabled() {
192 return useSecurityGroup;
193 }
194
195 @Override
196 public void setSecurityGroupEnabled(boolean option) {
197 useSecurityGroup = option;
198 }
199
200 @Override
Hyunsun Moonae51e732017-04-25 17:46:21 +0900201 public void clear() {
202 osSecurityGroupStore.clear();
203 }
204
205 private SecurityGroupRule securityGroupRule(String sgRuleId) {
206 return osSecurityGroupStore.securityGroups().stream()
207 .flatMap(sg -> sg.getRules().stream())
208 .filter(sgRule -> Objects.equals(sgRule.getId(), sgRuleId))
209 .findFirst().orElse(null);
sangho6a9ff0d2017-03-27 11:23:37 +0900210 }
211
212 private class InternalSecurityGroupStoreDelegate implements OpenstackSecurityGroupStoreDelegate {
213
214 @Override
215 public void notify(OpenstackSecurityGroupEvent event) {
216 if (event != null) {
217 log.trace("send openstack security group event {}", event);
218 process(event);
219 }
220 }
221 }
222}