diff --git a/ecl/network/v2/_proxy.py b/ecl/network/v2/_proxy.py index fa1d988..848ce88 100755 --- a/ecl/network/v2/_proxy.py +++ b/ecl/network/v2/_proxy.py @@ -13,6 +13,7 @@ from ecl.network.v2 import physical_port as _physical_port from ecl.network.v2 import quota as _quota from ecl.network.v2 import reserved_address as _reserved_address +from ecl.network.v2 import security_group as _security_group from ecl.network.v2 import firewall as _firewall from ecl.network.v2 import firewall_interface as _firewall_if from ecl.network.v2 import firewall_plan as _firewall_plan @@ -496,6 +497,90 @@ def get_reserved_address(self, reserved_address): """ return self._get(_reserved_address.ReservedAddress, reserved_address) + def security_groups(self, **query): + """ List all visible security-groups. + + :param query: Query parameters to select results + :return: A list of security-group objects + :rtype: :class:`~ecl.network.v2.security_group.SecurityGroup` + """ + return list(self._list(_security_group.SecurityGroup, + paginated=False, **query)) + + def create_security_group(self, description=None, name=None, tags=None, + tenant_id=None): + """Create security-group. + + :param string description: Security group description. + :param string name: Security group name. + :param dict tags: Security Group tags. + :param string tenant_id: The owner name of security group. + :returns: The results of security-group creation + :rtype: :class:`~ecl.network.v2.security_group.SecurityGroup` + """ + body = dict() + if description: + body["description"] = description + if name: + body["name"] = name + if tags: + body["tags"] = tags + if tenant_id: + body["tenant_id"] = tenant_id + + return self._create(_security_group.SecurityGroup, **body) + + def get_security_group(self, security_group): + """Show details for security-group. + + :param security_group: The value can be the ID of a security-group or + a :class:`~ecl.network.v2.security_group.SecurityGroup` instance. + :returns: One :class:`~ecl.network.v2.security_group.SecurityGroup` + :raises: :class:`~ecl.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_security_group.SecurityGroup, security_group) + + def update_security_group(self, security_group, **params): + """Update security-group. + + :param security_group: Either the id of a security-group or + a :class:`~ecl.network.v2.security_group.SecurityGroup` instance. + :param kwargs params: Parameters for security-group update. + + * string description: Security group description. + * string name: Security group name. + * dict tags: Security Group tags. + + :returns: The updated security-group + :rtype: :class:`~ecl.network.v2.security_group.SecurityGroup` + """ + if not isinstance(security_group, _security_group.SecurityGroup): + # security_group is the ID + security_group = self._get_resource(_security_group.SecurityGroup, + security_group) + security_group._body.clean() + + return self._update(_security_group.SecurityGroup, + security_group, **params) + + def delete_security_group(self, security_group, ignore_missing=False): + """Delete security-group. + + :param security_group: The value can be either the ID of + a security-group or + a :class:`~ecl.network.v2.port.Port` instance. + :param bool ignore_missing: When set to ``False`` :class: + `~ecl.exceptions.ResourceNotFound` will + be raised when the security-group does + not exist. When set to ``True``, + no exception will be set when attempting + to delete a nonexistent security-group. + :returns: ``None`` + """ + self._delete(_security_group.SecurityGroup, security_group, + ignore_missing=ignore_missing) + def firewalls(self, **query): """ List all visible firewalls. diff --git a/ecl/network/v2/security_group.py b/ecl/network/v2/security_group.py new file mode 100644 index 0000000..2e13deb --- /dev/null +++ b/ecl/network/v2/security_group.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +from ecl.network import network_service +from ecl import resource2 + + +class SecurityGroup(resource2.Resource): + """SecurityGroup Resource""" + resource_key = 'security_group' + resources_key = 'security_groups' + service = network_service.NetworkService("v2.0") + base_path = '/' + service.version + '/security-groups' + + # capabilities + allow_list = True + allow_create = True + allow_get = True + allow_update = True + allow_delete = True + + # Properties + # Security group description. + description = resource2.Body('description') + # Security group unique id. + id = resource2.Body('id') + # Security group name. + name = resource2.Body('name') + # Security group status. + status = resource2.Body('status') + # Security Group tags. + tags = resource2.Body('tags') + # The owner name of security group. + tenant_id = resource2.Body('tenant_id') + # Security group rules + security_group_rules = resource2.Body('security_group_rules', type=list) diff --git a/ecl/tests/unit/network/v2/test_security_group.py b/ecl/tests/unit/network/v2/test_security_group.py new file mode 100644 index 0000000..cd77239 --- /dev/null +++ b/ecl/tests/unit/network/v2/test_security_group.py @@ -0,0 +1,59 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import testtools + +from ecl.network.v2.security_group import SecurityGroup + +IDENTIFIER = 'IDENTIFIER' +EXAMPLE = { + "description": '1', + "id": IDENTIFIER, + "name": '2', + "status": '3', + "tags": { + 'tag1': '4', + 'tag2': '5' + }, + "tenant_id": IDENTIFIER, + "security_group_rules": [ + { + 'rule1': '6', + 'rule2': '7' + } + ] +} + + +class TestSecurityGroup(testtools.TestCase): + + def test_basic(self): + sot = SecurityGroup() + self.assertEqual('security_group', sot.resource_key) + self.assertEqual('security_groups', sot.resources_key) + self.assertEqual('/v2.0/security-groups', sot.base_path) + self.assertEqual('network', sot.service.service_type) + self.assertTrue(sot.allow_list) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_get) + self.assertTrue(sot.allow_update) + self.assertTrue(sot.allow_delete) + + def test_make_it(self): + sot = SecurityGroup(**EXAMPLE) + self.assertEqual(EXAMPLE['description'], sot.description) + self.assertEqual(EXAMPLE['id'], sot.id) + self.assertEqual(EXAMPLE['name'], sot.name) + self.assertEqual(EXAMPLE['status'], sot.status) + self.assertEqual(EXAMPLE['tags'], sot.tags) + self.assertEqual(EXAMPLE['tenant_id'], sot.tenant_id) + self.assertEqual(EXAMPLE['security_group_rules'], sot.security_group_rules)