From 0539ffdfd3ed5b509fc4eb818dda93efb61e89a1 Mon Sep 17 00:00:00 2001 From: Rick Kilcoyne Date: Mon, 25 Jan 2021 08:50:55 -0500 Subject: [PATCH] Added AWS Subnet Blueprint to create/delete subnets [Delivers DEV-17756] --- blueprints/aws_subnet/aws_subnet.json | 45 +++++ blueprints/aws_subnet/aws_subnet_1mCgJw9.png | Bin 0 -> 10146 bytes .../aws_subnet/build_subnet/build_subnet.json | 135 +++++++++++++ ...plugin_1605664239999382_ocUIYRM_Rtj6rXs.py | 183 ++++++++++++++++++ ...plugin_1605666168750486_WIucDJx_HgkL5JW.py | 25 +++ .../delete_subnet/delete_subnet.json | 10 + 6 files changed, 398 insertions(+) create mode 100644 blueprints/aws_subnet/aws_subnet.json create mode 100644 blueprints/aws_subnet/aws_subnet_1mCgJw9.png create mode 100644 blueprints/aws_subnet/build_subnet/build_subnet.json create mode 100644 blueprints/aws_subnet/build_subnet/cb_plugin_1605664239999382_ocUIYRM_Rtj6rXs.py create mode 100644 blueprints/aws_subnet/delete_subnet/cb_plugin_1605666168750486_WIucDJx_HgkL5JW.py create mode 100644 blueprints/aws_subnet/delete_subnet/delete_subnet.json diff --git a/blueprints/aws_subnet/aws_subnet.json b/blueprints/aws_subnet/aws_subnet.json new file mode 100644 index 00000000..a1531e00 --- /dev/null +++ b/blueprints/aws_subnet/aws_subnet.json @@ -0,0 +1,45 @@ +{ + "any-group-can-deploy": true, + "auto-historical-resources": false, + "build-items": [ + { + "action-name": "Build Subnet", + "continue-on-failure": false, + "deploy-seq": 1, + "description": null, + "execute-in-parallel": false, + "name": "Build Subnet", + "run-on-scale-up": true, + "show-on-order-form": true, + "type": "plugin" + } + ], + "description": "Create a subnet in a VPC associated with an existing CloudBolt Environment.", + "favorited": false, + "icon": "aws_subnet_1mCgJw9.png", + "is-orderable": true, + "management-actions": [], + "name": "AWS Subnet", + "resource-name-template": "AWS Subnet 000X", + "resource-type": { + "icon": "", + "label": "AWS Subnet", + "lifecycle": "ACTIVE", + "list-view-columns": [], + "name": "aws_subnet", + "plural-label": "AWS Subnets" + }, + "sequence": 0, + "show-recipient-field-on-order-form": false, + "teardown-items": [ + { + "action-name": "Delete Subnet", + "continue-on-failure": false, + "deploy-seq": -1, + "description": null, + "execute-in-parallel": false, + "name": "Delete Subnet", + "type": "teardown_plugin" + } + ] +} \ No newline at end of file diff --git a/blueprints/aws_subnet/aws_subnet_1mCgJw9.png b/blueprints/aws_subnet/aws_subnet_1mCgJw9.png new file mode 100644 index 0000000000000000000000000000000000000000..ef0dc6bbd0f9e28ec0d6b66313fc7b2502249bb2 GIT binary patch literal 10146 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 literal 0 HcmV?d00001 diff --git a/blueprints/aws_subnet/build_subnet/build_subnet.json b/blueprints/aws_subnet/build_subnet/build_subnet.json new file mode 100644 index 00000000..467c15a4 --- /dev/null +++ b/blueprints/aws_subnet/build_subnet/build_subnet.json @@ -0,0 +1,135 @@ +{ + "action-inputs": [ + { + "available-all-servers": false, + "description": "The Availability Zone or Local Zone for the subnet.\r\n\r\nDefault: AWS selects one for you. If you create more than one subnet in your VPC, we do not necessarily select a different zone for each subnet.", + "field-dependency-controlling-set": [ + { + "controlling-field": { + "name": "AWS_ENV_ID_a192" + }, + "custom-field-options": [], + "dependency-type": "REGENOPTIONS", + "dependent-field": { + "name": "AWS_AVAIL_ZONE_a192" + }, + "maximum": null, + "minimum": null, + "regex": "" + } + ], + "field-dependency-dependent-set": [ + { + "controlling-field": { + "name": "AWS_AVAIL_ZONE_a192" + }, + "custom-field-options": [], + "dependency-type": "REGENOPTIONS", + "dependent-field": { + "name": "AWS_VPC_CIDR_a192" + }, + "maximum": null, + "minimum": null, + "regex": "" + } + ], + "global-options": [], + "hide-if-default-value": false, + "label": "Availability Zone", + "name": "AWS_AVAIL_ZONE", + "relevant-osfamilies": [], + "required": true, + "show-as-attribute": false, + "show-on-servers": false, + "type": "STR" + }, + { + "available-all-servers": false, + "description": "", + "field-dependency-controlling-set": [], + "field-dependency-dependent-set": [ + { + "controlling-field": { + "name": "AWS_ENV_ID_a192" + }, + "custom-field-options": [], + "dependency-type": "REGENOPTIONS", + "dependent-field": { + "name": "AWS_AVAIL_ZONE_a192" + }, + "maximum": null, + "minimum": null, + "regex": "" + } + ], + "global-options": [], + "hide-if-default-value": false, + "label": "AWS Environment", + "name": "AWS_ENV_ID", + "relevant-osfamilies": [], + "required": true, + "show-as-attribute": false, + "show-on-servers": false, + "type": "STR" + }, + { + "available-all-servers": false, + "description": "The IPv4 network range for the subnet, in CIDR notation. For example, 10.0.0.0/24 . We modify the specified CIDR block to its canonical form; for example, if you specify 100.68.0.18/18 , we modify it to 100.68.0.0/18 .", + "field-dependency-controlling-set": [], + "field-dependency-dependent-set": [], + "global-options": [], + "hide-if-default-value": false, + "label": "Subnet IPv4 CIDR Address", + "name": "AWS_SUBNET_CIDR", + "regex-constraint": "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(3[0-2]|[1-2][0-9]|[0-9]))$", + "relevant-osfamilies": [], + "required": true, + "show-as-attribute": false, + "show-on-servers": false, + "type": "STR" + }, + { + "available-all-servers": false, + "description": "This is the CIDR address associated with the selected VPC, and is for informational purposes only.", + "field-dependency-controlling-set": [ + { + "controlling-field": { + "name": "AWS_AVAIL_ZONE_a192" + }, + "custom-field-options": [], + "dependency-type": "REGENOPTIONS", + "dependent-field": { + "name": "AWS_VPC_CIDR_a192" + }, + "maximum": null, + "minimum": null, + "regex": "" + } + ], + "field-dependency-dependent-set": [], + "global-options": [], + "hide-if-default-value": false, + "label": "VPC IPv4 CIDR Address", + "name": "AWS_VPC_CIDR", + "relevant-osfamilies": [], + "required": true, + "show-as-attribute": false, + "show-on-servers": false, + "type": "STR" + } + ], + "action-inputs-sequence": [ + "AWS_ENV_ID", + "AWS_VPC_CIDR", + "AWS_AVAIL_ZONE", + "AWS_SUBNET_CIDR" + ], + "description": "", + "max-retries": 0, + "name": "Build Subnet", + "resource-technologies": [], + "script-filename": "cb_plugin_1605664239999382_ocUIYRM_Rtj6rXs.py", + "shared": "False", + "target-os-families": [], + "type": "CloudBolt Plug-in" +} \ No newline at end of file diff --git a/blueprints/aws_subnet/build_subnet/cb_plugin_1605664239999382_ocUIYRM_Rtj6rXs.py b/blueprints/aws_subnet/build_subnet/cb_plugin_1605664239999382_ocUIYRM_Rtj6rXs.py new file mode 100644 index 00000000..bbfd1249 --- /dev/null +++ b/blueprints/aws_subnet/build_subnet/cb_plugin_1605664239999382_ocUIYRM_Rtj6rXs.py @@ -0,0 +1,183 @@ +from common.methods import set_progress +from infrastructure.models import CustomField, Environment +from resourcehandlers.aws.models import AWSHandler +from utilities.logger import ThreadLogger + +logger = ThreadLogger(__name__) + +AWS_ENVIRONMENT_ID = int('{{AWS_ENV_ID}}') +AWS_SUBNET_CIDR = str('{{AWS_SUBNET_CIDR}}') +AWS_AVAILABILITY_ZONE = str('{{AWS_AVAIL_ZONE}}') +AWS_VPC_CIDR = str('{{AWS_VPC_CIDR}}') + + +def generate_options_for_AWS_ENV_ID( + profile, + **kwargs): + envs = Environment.objects_for_profile(profile) + aws_envs = filter( + lambda e: e.resource_handler and e.resource_handler.type_slug == 'aws', + envs) + + options = [] + for env in list(aws_envs): + options.append( + (env.id, env.name), + ) + + return options + + +def generate_options_for_AWS_VPC_CIDR( + control_field=None, + form_data=None, form_prefix=None, + **kwargs): + options = [] + + if not control_field: + return options + + _, env_id = get_value_from_form_data( + form_data=form_data, + form_prefix=form_prefix, + field_name='AWS_ENV_ID') + + try: + env = Environment.objects.get(id=env_id) + ec2_client = get_boto3_for_env(env) + response = ec2_client.describe_vpcs(VpcIds=[env.vpc_id]) + if 'Vpcs' in response and len(response['Vpcs']) > 0: + cidr = response['Vpcs'][0]['CidrBlock'] + options.append((cidr, cidr), ) + except Exception as ex: + logger.error(ex) + options.append(('not available', 'not available'), ) + + return options + + +def get_value_from_form_data( + form_data=None, + form_prefix=None, + field_name=None): + field_key = None + field_value = None + if 'form_prefix' in form_data and not form_prefix: + form_prefix = form_data.get('form_prefix', None) + if not form_prefix: + # Nothing can be found + return field_key, field_value + for key_name in form_data: + if form_prefix + "-" + field_name + "_a" in key_name: + field_key = key_name + field_value = form_data[key_name] if \ + isinstance(form_data[key_name], str) else \ + form_data[key_name][0] + break + return field_key, field_value + + +def generate_options_for_AWS_AVAIL_ZONE( + control_field=None, + control_value=None, + **kwargs): + if not control_field: + return [] + + availability_zones = [ + ('default', 'Default'), + ] + + try: + env = Environment.objects.get(id=control_value) + region = env.aws_region + rh = AWSHandler.objects.get(id=env.resource_handler.id) + ec2_client = rh.get_boto3_client(region_name=region) + + response = ec2_client.describe_availability_zones() + if response.get('AvailabilityZones'): + for zone in response['AvailabilityZones']: + availability_zones.append( + (zone['ZoneName'], zone['ZoneName'],), + ) + except Exception as ex: + logger.error(ex) + + return availability_zones + + +def run(resource, profile, **kwargs): + cf_subnet_id, _ = CustomField.objects.get_or_create( + name="bp_aws_subnet_id", + label="Subnet ID", + type="STR", + show_as_attribute=True + ) + cf_subnet_cidr, _ = CustomField.objects.get_or_create( + name="bp_aws_subnet_cidr", + label="IPv4 CIDR Address", + type="STR", + show_as_attribute=True + ) + cf_env_id, _ = CustomField.objects.get_or_create( + name="bp_aws_subnet_env_id", + label="CB Environment ID", + type="INT", + show_as_attribute=False + ) + + env = Environment.objects.get(id=AWS_ENVIRONMENT_ID) + vpc_id = env.vpc_id + region = env.aws_region + rh = env.resource_handler.cast() + ec2_client = rh.get_boto3_client(region_name=region) + + try: + response = ec2_client.create_subnet( + AvailabilityZone='' if AWS_AVAILABILITY_ZONE.lower() == 'default' + else AWS_AVAILABILITY_ZONE, + CidrBlock=AWS_SUBNET_CIDR, + VpcId=vpc_id, + ) + subnet_id = response['Subnet']['SubnetId'] + + response = ec2_client.create_tags( + Resources=[subnet_id], + Tags=[ + { + "Key": "Name", + "Value": f"{resource.name}" + }, + { + "Key": "cb_resource_id", + "Value": f"{resource.id}" + }, + { + "Key": "cb_env_id", + "Value": f"{AWS_ENVIRONMENT_ID}" + }, + { + "Key": "cb_rh_id", + "Value": f"{rh.id}" + }, + ] + ) + + resource.update_cf_value(cf_subnet_id, subnet_id, profile) + resource.update_cf_value(cf_subnet_cidr, AWS_SUBNET_CIDR, profile) + resource.update_cf_value(cf_env_id, env.id, profile) + + set_progress(f"Subnet ID: {subnet_id}") + set_progress(f"Subnet IPv4 CIDR: {AWS_SUBNET_CIDR}") + set_progress(f"CB Environment ID: {env.id}") + except Exception as ex: + logger.error(ex) + return "FAILURE", "", str(ex) + + return "SUCCESS", "", "" + + +def get_boto3_for_env(env): + region = env.aws_region + rh = env.resource_handler.cast() + return rh.get_boto3_client(region_name=region) \ No newline at end of file diff --git a/blueprints/aws_subnet/delete_subnet/cb_plugin_1605666168750486_WIucDJx_HgkL5JW.py b/blueprints/aws_subnet/delete_subnet/cb_plugin_1605666168750486_WIucDJx_HgkL5JW.py new file mode 100644 index 00000000..a57becdb --- /dev/null +++ b/blueprints/aws_subnet/delete_subnet/cb_plugin_1605666168750486_WIucDJx_HgkL5JW.py @@ -0,0 +1,25 @@ +from common.methods import set_progress +from infrastructure.models import Environment +from resourcehandlers.aws.models import AWSHandler +from utilities.logger import ThreadLogger + +logger = ThreadLogger(__name__) + + +def run(job, resource, profile, **kwargs): + set_progress("Delete Customer Subnet") + + env_id = resource.bp_aws_subnet_env_id + subnet_id = resource.bp_aws_subnet_id + + try: + env = Environment.objects.get(id=env_id) + rh = env.resource_handler.cast() + ec2_client = rh.get_boto3_client(region_name=env.aws_region) + response = ec2_client.delete_subnet(SubnetId=subnet_id) + except Exception as ex: + logger.error(str(ex)) + return "WARNING", "", f"Unable to remove subnet: {subnet_id}. " \ + f"Manual clean-up in AWS may be necessary." + + return "SUCCESS", "", "" \ No newline at end of file diff --git a/blueprints/aws_subnet/delete_subnet/delete_subnet.json b/blueprints/aws_subnet/delete_subnet/delete_subnet.json new file mode 100644 index 00000000..b309ceb8 --- /dev/null +++ b/blueprints/aws_subnet/delete_subnet/delete_subnet.json @@ -0,0 +1,10 @@ +{ + "description": "", + "max-retries": 0, + "name": "Delete Subnet", + "resource-technologies": [], + "script-filename": "cb_plugin_1605666168750486_WIucDJx_HgkL5JW.py", + "shared": "False", + "target-os-families": [], + "type": "CloudBolt Plug-in" +} \ No newline at end of file