Source code for cloudmesh_client.cloud.secgroup

from __future__ import print_function

import requests

from cloudmesh_client.shell.console import Console
from cloudmesh_client.common.Printer import Printer
from cloudmesh_client.db import CloudmeshDatabase
from cloudmesh_client.cloud.iaas.CloudProvider import CloudProvider
from cloudmesh_client.cloud.ListResource import ListResource
from cloudmesh_client.common.LibcloudDict import LibcloudDict
from cloudmesh_client.common.dotdict import dotdict
from pprint import pprint
from cloudmesh_client.common.ConfigDict import ConfigDict
from cloudmesh_client.default import Default

requests.packages.urllib3.disable_warnings()


[docs]class SecGroup(ListResource): cm = CloudmeshDatabase() """ NOT USED @classmethod def convert_list_to_dict(cls, os_result): d = {} for i, obj in enumerate(os_result): d[i] = {} d[i]["Id"] = obj.id d[i]["Name"] = obj.name d[i]["Description"] = obj.description return d """ # noinspection PyPep8
[docs] @classmethod def convert_rules_to_dict(cls, os_result): d = {} for i, obj in enumerate(os_result): if obj["ip_range"]["cidr"]: ip_range = obj["ip_range"]["cidr"] else: ip_range = "0.0.0.0/0" d[i] = { "IP Protocol": obj["ip_protocol"], "From Port": obj["from_port"], "To Port": obj["to_port"], "IP Range": ip_range } return d
[docs] @classmethod def refresh(cls, cloud): """ This method would refresh the secgroup list by first clearing the database, then inserting new data :param cloud: the cloud name """ return cls.cm.refresh('secgroup', cloud)
[docs] @classmethod def add_rule_to_db(cls, group=None, name=None, from_port=None, to_port=None, protocol=None, cidr=None): cls.delete_rule_from_db(group=group, name=name) try: rule = { "category": "general", "kind": "secgrouprule", "group": group, "name": name, 'protocol': protocol, 'fromPort': from_port, 'toPort': to_port, 'cidr': cidr } cls.cm.add(rule, replace=False) except Exception as ex: Console.error("Problem adding rule")
[docs] @classmethod def delete_rule_from_db(cls, group=None, name=None): old_rule = { "category": "general", "kind": "secgrouprule", "name": name, "group": group } cls.cm.delete(**old_rule)
[docs] @classmethod def upload(cls, cloud=None, group=None): if cloud is None or cloud=='all': clouds = ConfigDict("cloudmesh.yaml")["cloudmesh"]["active"] else: clouds = [cloud] if group is None: rules = cls.list(output='dict') groups = set() for g in rules: r = rules[g] groups.add(r["group"]) groups = list(groups) else: groups = [group] for cloud in clouds: Console.msg("Uploading the groups/rules to cloud - {}...".format(cloud)) for g in groups: cls.delete_all_rules_cloud(cloud, g) group = cls.get(name=g, cloud=cloud) group_cloud = cls.get_group_cloud(cloud, g) if not group_cloud: cls.add_group_cloud(cloud, g) rules = cls.list_rules(group=g, output="dict") if rules: for ruleid in rules: rule = rules[ruleid] rulename = rule["name"] cls.add_rule_cloud(cloud, g, rulename) ''' SecGroup.delete(category=c, group=g) uuid = SecGroup.create(category=c, group=g) for key in rules: r = rules[key] if r["group"] == g: SecGroup.add_rule(c,uuid,r["fromPort"],r["toPort"] , r['protocol'],r['cidr']) # create group ''' Console.msg("...done") Console.info("All completed")
[docs] @classmethod def create(cls, group=None, category=None): """ Method creates a new security group in database & returns the uuid of the created group :param group: :param category: :return: """ # Create the security group in given cloud try: cloud_provider = CloudProvider(category).provider secgroup = cloud_provider.create_secgroup(group) if secgroup: uuid = secgroup.id return uuid else: print("Failed to create security group, {}".format(secgroup)) except Exception as e: print( "Exception creating security group in cloud, {}".format(e)) return None
[docs] @classmethod def list(cls, group=None, name=None, category='general', output='table', scope='all'): """ This method queries the database to fetch list of secgroups filtered by cloud. :param cloud: :return: """ query = dotdict({ "kind": "secgrouprule", "scope": "all" }) if category is "general": if group is not None: query.group = group if name is not None: query.name = name query.category = category elements = cls.cm.find(**query) else: elements = CloudProvider(category).provider.list_secgroup_rules(category) if elements is None: return None else: # pprint(elements) # # BUG this should not depend on cloud, but on "general" # # (order, header) = CloudProvider(cloud).get_attributes("secgroup") order = ['name', 'group', 'fromPort', 'toPort', 'cidr', 'protocol'] header = None return Printer.write(elements, order=order, header=header, output=output)
[docs] @classmethod def list_rules(cls, group=None, output='table'): """ This method gets the security group rules from the cloudmesh database :param uuid: :return: """ try: if group is None: rules = cls.cm.find(kind="secgrouprule") else: args = { "group": group } rules = cls.cm.find(kind="secgrouprule", **args) # check if rules exist if rules is None: return "No rules for security group={} in the database. Try cm secgroup refresh.".format(group) # return table return (Printer.write(rules, order=["user", "group", "category", "name", "fromPort", "toPort", "protocol", "cidr"], output=output)) except Exception as ex: Console.error("Listing Security group rules") return None
[docs] @classmethod def enable_ssh(cls, secgroup_name='default', cloud="general"): ret = False if cloud in LibcloudDict.Libcloud_category_list: Console.info("Creating and adding security group for libcloud") cloud_provider = CloudProvider(cloud).provider cloud_provider.create_sec_group(cloud, secgroup_name) cloud_provider.enable_ssh(cloud, secgroup_name) else: cloud_provider = CloudProvider(cloud).provider.provider secgroups = cloud_provider.security_groups.list() for asecgroup in secgroups: if asecgroup.name == secgroup_name: rules = asecgroup.rules rule_exists = False # structure of a secgroup rule: # {u'from_port': 22, u'group': {}, u'ip_protocol': u'tcp', u'to_port': 22, u'parent_group_id': u'UUIDHERE', u'ip_range': {u'cidr': u'0.0.0.0/0'}, u'id': u'UUIDHERE'} for arule in rules: if arule["from_port"] == 22 and \ arule["to_port"] == 22 and \ arule["ip_protocol"] == 'tcp' and \ arule["ip_range"] == {'cidr': '0.0.0.0/0'}: # print (arule["id"]) rule_exists = True break if not rule_exists: cloud_provider.security_group_rules.create( asecgroup.id, ip_protocol='tcp', from_port=22, to_port=22, cidr='0.0.0.0/0') # else: # print ("The rule allowing ssh login did exist!") ret = True break # print ("*" * 80) # d = SecGroup.convert_list_to_dict(secgroups) # print (d) return ret
[docs] @classmethod def get(cls, name=None, cloud="general"): """ This method queries the database to fetch secgroup with given name filtered by cloud. :param name: :param cloud: :return: """ try: args = { "name": name, 'scope': 'fisrt', 'kind': "secgroup", "output": "object", } if cloud is not None and cloud is not 'general': args["category"] = cloud secgroup = cls.cm.find(**args) if secgroup is None: return None else: return secgroup[0] except Exception as ex: Console.error("get secgroup") return None
[docs] @classmethod def add_rule(cls, cloud, secgroup_uuid, from_port, to_port, protocol, cidr): try: # Get the nova client object cloud_provider = CloudProvider(cloud).provider # Create add secgroup rules to the cloud args = { 'uuid': secgroup_uuid, 'protocol': protocol, 'from_port': from_port, 'to_port': to_port, 'cidr': cidr } rule_id = cloud_provider.add_secgroup_rule(**args) # create local db record rule = {"kind": "secgrouprule", "uuid": str(rule_id), "category": cloud, "fromPort": from_port, "toPort": to_port, "protocol": protocol, "cidr": cidr} """ cls.cm.add(**rule) cls.cm.save() """ Console.ok("Added rule {category} {uuid} {fromPort} {toPort} {protocol} {cidr}" .format(**rule)) except Exception as ex: if "This rule already exists" in ex.message: Console.ok("Rule already exists. Added rule.") return else: Console.error(ex.message, ex) return
[docs] @classmethod def reset_defaults(cls): #secgroup = "{}-default".format(Default.user) secgroup = "default" Default.set_secgroup(secgroup) # nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0 SecGroup.add_rule_to_db(group=secgroup, name="ssh", from_port="22", to_port="22", protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="http", from_port="80", to_port="80", protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="https", from_port="443", to_port="443", protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="icmp", from_port="-1", to_port="-1", protocol="icmp", cidr="0.0.0.0/0")
[docs] @classmethod def delete(cls, category='general', group=None, name=None): # name is anme of the rule if category=='general': if name is None and group is not None: # delete the entire group cls.cm.delete(kind="secgrouprule", group=group) elif name is not None and group is not None: # delete specific rule cls.cm.delete(name=name, kind="secgrouprule", group=group) elif name is None and group is None: # delete all groups cls.cm.delete(kind="secgrouprule") if group == Default.secgroup or Default.secgroup is None: cls.reset_defaults() else: provider = CloudProvider(category).provider # delete on cloud if group is not None: provider.delete_secgroup(name) # delete the entire group elif group is None: # delete all groups pass
[docs] @classmethod def delete_secgroup(cls, name=None, cloud=None): try: # Find the secgroup from the cloud cloud_provider = CloudProvider(cloud).provider result = cloud_provider.delete_secgroup(name) return result except Exception as ex: Console.error("delete group")
[docs] @classmethod def delete_rule(cls, cloud, secgroup, from_port, to_port, protocol, cidr): try: args = { "group": secgroup["uuid"], "fromPort": from_port, "toPort": to_port, "protocol": protocol, "cidr": cidr } rule = cls.cm.find(kind="secgrouprule", output="object", scope="first", **args) if rule is not None: # get the nova client for cloud cloud_provider = CloudProvider(cloud).provider # delete the rule from the cloud cloud_provider.delete_secgroup_rule(rule.uuid) # delete the local db record cls.cm.delete(rule) return "Rule [{fromPort} | {toPort} | {protocol} | {cidr}] deleted" \ .format(**args) else: return None except Exception as ex: Console.error("delete rule") return
[docs] @classmethod def delete_all_rules(cls, secgroup): try: args = { "group": secgroup["uuid"] } rules = cls.cm.find(kind="secgrouprule", output="object", **args) if rules is not None: for rule in rules: cls.cm.delete(rule) Console.ok("Rule [{fromPort} | {toPort} | {protocol} | {cidr}] deleted" .format(**rule)) else: pass except Exception as ex: Console.error("delete all rules") return
# new methods moved from the test_secgroup:3 # the operations are from the perspective on the cloud # and does not make any change on local db #
[docs] @classmethod def add_group_cloud(cls, cloud, groupname): provider = CloudProvider(cloud).provider return provider.create_secgroup(groupname)
[docs] @classmethod def delete_group_cloud(cls, cloud, groupname): provider = CloudProvider(cloud).provider return provider.delete_secgroup(groupname)
[docs] @classmethod def add_rule_cloud(cls, cloud, groupname, rulename): ret = None provider = CloudProvider(cloud).provider # fetch rule from db db_rule = cls.cm.find(kind="secgrouprule", category="general", group=groupname, name=rulename, scope='first', output='dict') kwargs = {} kwargs["protocol"] = db_rule["protocol"] kwargs["cidr"] = db_rule["cidr"] kwargs["from_port"] = db_rule["fromPort"] kwargs["to_port"] = db_rule["toPort"] group = cls.get_group_cloud(cloud, groupname) if group: groupid = group["id"] kwargs["uuid"] = groupid ret = provider.add_secgroup_rule(**kwargs) return ret
[docs] @classmethod def delete_rule_cloud(cls, cloud, groupname, rulename): ret = None provider = CloudProvider(cloud).provider ruleid = cls.get_rule_cloud(cloud, groupname, rulename) if ruleid: ret = provider.delete_secgroup_rule(ruleid) #else: # Console.error("Rule does not exist - Rule:{}, Group:{}"\ # .format(rulename, groupname), traceflag=False) return ret
[docs] @classmethod def delete_all_rules_cloud(cls, cloud, groupname): rules = cls.list_rules_cloud(cloud, groupname) provider = CloudProvider(cloud).provider if rules: for rule in rules: ruleid = rule['id'] # only refresh those defined with a protocol # This leaves the default rule defined by # allowing the same secgroup untouched if rule['ip_protocol']: provider.delete_secgroup_rule(ruleid) return
[docs] @classmethod def list_groups_cloud(cls, cloud): provider = CloudProvider(cloud).provider groups = provider.list_secgroup(cloud) return groups
[docs] @classmethod def get_group_cloud(cls, cloud, groupname): provider = CloudProvider(cloud).provider groups = provider.list_secgroup(cloud) ret = None for groupkey in groups: group = groups[groupkey] if group["name"] == groupname: ret = group break return ret
[docs] @classmethod def list_rules_cloud(cls, cloud, groupname): provider = CloudProvider(cloud).provider groups = provider.list_secgroup(cloud) for id in groups: group = groups[id] if groupname == group["name"]: return group["rules"] return None
[docs] @classmethod def get_rule_cloud(cls, cloud, groupname, rulename): rules = cls.list_rules_cloud(cloud, groupname) # find properties for db rule db_rule = cls.cm.find(kind="secgrouprule", category="general", group=groupname, name=rulename, scope='first', output='dict') ruleid = None for rule in rules: if 'cidr' in rule['ip_range']: if (db_rule["fromPort"] == str(rule['from_port']) and db_rule["toPort"] == str(rule['to_port']) and db_rule["protocol"] == rule['ip_protocol'] and db_rule["cidr"] == rule['ip_range']['cidr'] ): ruleid = rule['id'] #uuid for the rule return ruleid
if __name__ == '__main__': nova = CloudProvider.set("kilo") # groups = nova.security_groups.list() # print(groups) # print("\n\n") # d = SecGroup.convert_list_to_dict(groups) # print(d) # security_group = nova.security_groups.create(name="oct17_secgroup", description="Created by Gourav") print("Created sec group\n") # rule = nova.security_group_rules.create(security_group.id, ip_protocol="icmp", # from_port=-1, to_port=-1, cidr="0.0.0.0/0") print("Created sec group rules\n") # print(rule) security_group = nova.security_groups.find(name="oct17_secgroup") rules = security_group.rules print(rules) d = SecGroup.convert_rules_to_dict(rules) print(d) nova.security_group_rules.delete('6220f8a4-e4fb-4340-bfe7-ffa028a7c6af') print("Deleted Sec Group Rule")