diff options
author | Morgan Fainberg <m@metacloud.com> | 2013-02-06 15:39:54 -0800 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2013-02-19 01:50:51 +0000 |
commit | 59aaf1dff97aa25a71d317300b8255f4c59391a9 (patch) | |
tree | 6c5614d8cdd8b3963e5abacbf0939f1772deaad9 /nova/db | |
parent | 30c2a8f66edb9f9601a519fb525a46cc4486ab2a (diff) | |
download | nova-59aaf1dff97aa25a71d317300b8255f4c59391a9.tar.gz nova-59aaf1dff97aa25a71d317300b8255f4c59391a9.tar.xz nova-59aaf1dff97aa25a71d317300b8255f4c59391a9.zip |
Default SG rules for the Security Group "Default"
Added in the API os-security-group-default-rules
This allows create, delete, list, and get (of individual rules) for
rules that will be pre-populated into the Security Group "default"
that is populated in all projects on creation.
These rules will not be applied retroactively, as it is designed
to allow the creation of a "reasonable" base-line set of sg rules.
The new rules live in a separate table that mirrors the relevant
structures of the security_group_rules table.
Added unit tests/API samples for the new API calls
Related to bp default-rules-for-default-security-group
DocImpact
Change-Id: I7ab51e68aff562bb869538197a0eca158fc3220c
Diffstat (limited to 'nova/db')
-rw-r--r-- | nova/db/api.py | 22 | ||||
-rw-r--r-- | nova/db/sqlalchemy/api.py | 60 | ||||
-rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/157_add_security_group_default_rules.py | 61 | ||||
-rw-r--r-- | nova/db/sqlalchemy/models.py | 9 |
4 files changed, 152 insertions, 0 deletions
diff --git a/nova/db/api.py b/nova/db/api.py index 6ec0b3a95..969cf494a 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1206,6 +1206,28 @@ def security_group_rule_count_by_group(context, security_group_id): ################### +def security_group_default_rule_get(context, security_group_rule_default_id): + return IMPL.security_group_default_rule_get(context, + security_group_rule_default_id) + + +def security_group_default_rule_destroy(context, + security_group_rule_default_id): + return IMPL.security_group_default_rule_destroy( + context, security_group_rule_default_id) + + +def security_group_default_rule_create(context, values): + return IMPL.security_group_default_rule_create(context, values) + + +def security_group_default_rule_list(context): + return IMPL.security_group_default_rule_list(context) + + +################### + + def provider_fw_rule_create(context, rule): """Add a firewall rule at the provider level (all hosts & instances).""" return IMPL.provider_fw_rule_create(context, rule) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 375a3884b..66fc24355 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3180,6 +3180,16 @@ def security_group_ensure_default(context, session=None): 'project_id': context.project_id} default_group = security_group_create(context, values, session=session) + for default_rule in security_group_default_rule_list(context): + # This is suboptimal, it should be programmatic to know + # the values of the default_rule + rule_values = {'protocol': default_rule.protocol, + 'from_port': default_rule.from_port, + 'to_port': default_rule.to_port, + 'cidr': default_rule.cidr, + 'parent_group_id': default_group.id, + } + security_group_rule_create(context, rule_values) return (False, default_group) @@ -3280,6 +3290,56 @@ def security_group_rule_count_by_group(context, security_group_id): ################### +def _security_group_rule_get_default_query(context, session=None): + return model_query(context, models.SecurityGroupIngressDefaultRule, + session=session) + + +@require_context +def security_group_default_rule_get(context, security_group_rule_default_id, + session=None): + result = _security_group_rule_get_default_query(context, session=session).\ + filter_by(id=security_group_rule_default_id).\ + first() + + if not result: + raise exception.SecurityGroupDefaultRuleNotFound( + rule_id=security_group_rule_default_id) + + return result + + +@require_admin_context +def security_group_default_rule_destroy(context, + security_group_rule_default_id): + session = get_session() + with session.begin(): + count = _security_group_rule_get_default_query(context, + session=session).\ + filter_by(id=security_group_rule_default_id).\ + soft_delete() + if count == 0: + raise exception.SecurityGroupDefaultRuleNotFound( + rule_id=security_group_rule_default_id) + + +@require_admin_context +def security_group_default_rule_create(context, values): + security_group_default_rule_ref = models.SecurityGroupIngressDefaultRule() + security_group_default_rule_ref.update(values) + security_group_default_rule_ref.save() + return security_group_default_rule_ref + + +@require_context +def security_group_default_rule_list(context, session=None): + return _security_group_rule_get_default_query(context, session=session).\ + all() + + +################### + + @require_admin_context def provider_fw_rule_create(context, rule): fw_rule_ref = models.ProviderFirewallRule() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/157_add_security_group_default_rules.py b/nova/db/sqlalchemy/migrate_repo/versions/157_add_security_group_default_rules.py new file mode 100644 index 000000000..5dcfdbb90 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/157_add_security_group_default_rules.py @@ -0,0 +1,61 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# +# 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. + +from sqlalchemy import Column, DateTime, Integer, MetaData, String, Table +from nova.db.sqlalchemy import types + +from nova.openstack.common import log as logging + +LOG = logging.getLogger(__name__) + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + security_group_default_rules = Table('security_group_default_rules', meta, + Column('created_at', DateTime), + Column('updated_at', DateTime), + Column('deleted_at', DateTime), + Column('deleted', Integer, default=0), + Column('id', Integer, primary_key=True, nullable=False), + Column('protocol', String(length=5)), + Column('from_port', Integer), + Column('to_port', Integer), + Column('cidr', types.CIDR()), + mysql_engine='InnoDB', + mysql_charset='utf8', + ) + + try: + security_group_default_rules.create() + except Exception: + msg = "Exception while creating table 'security_group_default_rules" + LOG.exception(msg) + raise + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + security_group_default_rules = Table('security_group_default_rules', + meta, + autoload=True) + try: + security_group_default_rules.drop() + except Exception: + msg = "Exception while droppping table 'security_group_default_rules'" + LOG.exception(msg) + raise diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 28d8f0882..f0dcd3307 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -541,6 +541,15 @@ class SecurityGroupIngressRule(BASE, NovaBase): 'SecurityGroupIngressRule.deleted == 0)') +class SecurityGroupIngressDefaultRule(BASE, NovaBase): + __tablename__ = 'security_group_default_rules' + id = Column(Integer, primary_key=True) + protocol = Column(String(5)) # "tcp", "udp" or "icmp" + from_port = Column(Integer) + to_port = Column(Integer) + cidr = Column(types.CIDR()) + + class ProviderFirewallRule(BASE, NovaBase): """Represents a rule in a security group.""" __tablename__ = 'provider_fw_rules' |