From e81a68e5cb6cca154c4bcb754e073e7f8728280d Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Mon, 29 Mar 2021 22:35:36 +0100 Subject: [PATCH 1/8] add inbound IP configuration for aws provider New config param `instances.parameters.inboundIp`. Allows users to specify an inbound IP address or range, which is then used to whitelist all ports, including 22, in the instance's security group. By default this is set to 0.0.0.0/0 and therefore not whitelisted. --- .../cfn_templates/instance/data/template.yaml | 10 +------- .../aws/cfn_templates/instance/template.py | 25 ++++++++----------- .../providers/aws/config/instance_config.py | 6 ++++- spotty/providers/aws/config/validation.py | 1 + 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/spotty/providers/aws/cfn_templates/instance/data/template.yaml b/spotty/providers/aws/cfn_templates/instance/data/template.yaml index b999b4b..2e492d0 100644 --- a/spotty/providers/aws/cfn_templates/instance/data/template.yaml +++ b/spotty/providers/aws/cfn_templates/instance/data/template.yaml @@ -88,15 +88,7 @@ Resources: IpProtocol: -1 FromPort: 0 ToPort: 65535 - SecurityGroupIngress: - - CidrIp: 0.0.0.0/0 - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - - CidrIpv6: ::/0 - IpProtocol: tcp - FromPort: 22 - ToPort: 22 + SecurityGroupIngress: [] PreparingInstanceSignal: Type: AWS::CloudFormation::WaitCondition diff --git a/spotty/providers/aws/cfn_templates/instance/template.py b/spotty/providers/aws/cfn_templates/instance/template.py index f46afc2..3201914 100644 --- a/spotty/providers/aws/cfn_templates/instance/template.py +++ b/spotty/providers/aws/cfn_templates/instance/template.py @@ -20,6 +20,7 @@ from spotty.providers.aws.config.instance_config import InstanceConfig from spotty.providers.aws.config.ebs_volume import EbsVolume from spotty.providers.aws.helpers.logs import get_logs_s3_path +from netaddr import IPNetwork def prepare_instance_template(ec2, instance_config: InstanceConfig, docker_commands: DockerCommands, @@ -56,20 +57,16 @@ def prepare_instance_template(ec2, instance_config: InstanceConfig, docker_comma }] del template['Resources']['InstanceLaunchTemplate']['Properties']['LaunchTemplateData']['SecurityGroupIds'] - # add ports to the security group - for port in instance_config.ports: - if port != 22: - template['Resources']['InstanceSecurityGroup']['Properties']['SecurityGroupIngress'] += [{ - 'CidrIp': '0.0.0.0/0', - 'IpProtocol': 'tcp', - 'FromPort': port, - 'ToPort': port, - }, { - 'CidrIpv6': '::/0', - 'IpProtocol': 'tcp', - 'FromPort': port, - 'ToPort': port, - }] + # add ports to the security group for the user-defined inbound IP + ipnetwork = IPNetwork(instance_config.instance_inbound_ip) + cidr_ip = 'CidrIpv6' if ipnetwork.version == 6 else 'CidrIp' + for port in [22] + instance_config.ports: + template['Resources']['InstanceSecurityGroup']['Properties']['SecurityGroupIngress'] += [{ + cidr_ip: str(ipnetwork), + 'IpProtocol': 'tcp', + 'FromPort': port, + 'ToPort': port, + }] if instance_config.is_spot_instance: # set maximum price diff --git a/spotty/providers/aws/config/instance_config.py b/spotty/providers/aws/config/instance_config.py index fca01fc..e21dee4 100644 --- a/spotty/providers/aws/config/instance_config.py +++ b/spotty/providers/aws/config/instance_config.py @@ -75,7 +75,11 @@ def max_price(self) -> float: @property def managed_policy_arns(self) -> list: return self._params['managedPolicyArns'] - + @property def instance_profile_arn(self) -> str: return self._params['instanceProfileArn'] + + @property + def inbound_ip(self) -> str: + return self._params['inboundIp'] diff --git a/spotty/providers/aws/config/validation.py b/spotty/providers/aws/config/validation.py index 5b3eb2b..639ac5a 100644 --- a/spotty/providers/aws/config/validation.py +++ b/spotty/providers/aws/config/validation.py @@ -30,6 +30,7 @@ def validate_instance_parameters(params: dict): ), Optional('managedPolicyArns', default=[]): [str], Optional('instanceProfileArn', default=None): str, + Optional('inboundIp', default="0.0.0.0/0"): str } volumes_checks = [ From 9c10188ee45b86c891a08a7560a8ff9049bf6b6c Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Mon, 29 Mar 2021 23:09:31 +0100 Subject: [PATCH 2/8] validate inboundIp param using netaddr netaddr.IPNetwork used as part of the schema validation and type for inbound_ip param. --- spotty/providers/aws/cfn_templates/instance/template.py | 7 +++---- spotty/providers/aws/config/validation.py | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/spotty/providers/aws/cfn_templates/instance/template.py b/spotty/providers/aws/cfn_templates/instance/template.py index 3201914..d1a561b 100644 --- a/spotty/providers/aws/cfn_templates/instance/template.py +++ b/spotty/providers/aws/cfn_templates/instance/template.py @@ -20,7 +20,6 @@ from spotty.providers.aws.config.instance_config import InstanceConfig from spotty.providers.aws.config.ebs_volume import EbsVolume from spotty.providers.aws.helpers.logs import get_logs_s3_path -from netaddr import IPNetwork def prepare_instance_template(ec2, instance_config: InstanceConfig, docker_commands: DockerCommands, @@ -58,11 +57,11 @@ def prepare_instance_template(ec2, instance_config: InstanceConfig, docker_comma del template['Resources']['InstanceLaunchTemplate']['Properties']['LaunchTemplateData']['SecurityGroupIds'] # add ports to the security group for the user-defined inbound IP - ipnetwork = IPNetwork(instance_config.instance_inbound_ip) - cidr_ip = 'CidrIpv6' if ipnetwork.version == 6 else 'CidrIp' + inbound_ip = instance_config.inbound_ip + cidr_ip = 'CidrIpv6' if inbound_ip == 6 else 'CidrIp' for port in [22] + instance_config.ports: template['Resources']['InstanceSecurityGroup']['Properties']['SecurityGroupIngress'] += [{ - cidr_ip: str(ipnetwork), + cidr_ip: str(inbound_ip), 'IpProtocol': 'tcp', 'FromPort': port, 'ToPort': port, diff --git a/spotty/providers/aws/config/validation.py b/spotty/providers/aws/config/validation.py index 639ac5a..9bf7dd5 100644 --- a/spotty/providers/aws/config/validation.py +++ b/spotty/providers/aws/config/validation.py @@ -1,5 +1,6 @@ import os from schema import Schema, Optional, And, Regex, Or, Use +from netaddr import IPNetwork from spotty.config.validation import validate_config, get_instance_parameters_schema, has_prefix @@ -30,7 +31,8 @@ def validate_instance_parameters(params: dict): ), Optional('managedPolicyArns', default=[]): [str], Optional('instanceProfileArn', default=None): str, - Optional('inboundIp', default="0.0.0.0/0"): str + Optional('inboundIp', default="0.0.0.0/0"): Use(IPNetwork, error='"inboundIp" should be a valid IP ' + 'address or CIDR range') } volumes_checks = [ From bb09c15997eef679f73998626f334442698320cd Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Mon, 29 Mar 2021 23:11:12 +0100 Subject: [PATCH 3/8] add netaddr to packages --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index a633101..4bfc484 100644 --- a/setup.py +++ b/setup.py @@ -49,6 +49,7 @@ def get_description(): 'cfn_flip', # to work with CloudFormation templates 'schema', 'chevron', + 'netaddr' # validates configuration IP addresses ], tests_require=['moto'], test_suite='tests', From 74ea22051c8f67756884f08a2a5faadebcd594e0 Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Mon, 29 Mar 2021 23:11:37 +0100 Subject: [PATCH 4/8] add default value for inboundIp to test --- tests/providers/aws/config/instance_config_validation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/providers/aws/config/instance_config_validation.py b/tests/providers/aws/config/instance_config_validation.py index 29e1d64..2752ff6 100644 --- a/tests/providers/aws/config/instance_config_validation.py +++ b/tests/providers/aws/config/instance_config_validation.py @@ -28,6 +28,7 @@ def test_default_configuration(self): 'spotInstance': False, 'subnetId': '', 'volumes': [], + 'inboundIp': "0.0.0.0/0" } self.assertEqual(expected_params, validate_instance_parameters(required_params)) From 4fb6d742a9009db3060e40bfcf5107cf272e29be Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Mon, 29 Mar 2021 23:22:51 +0100 Subject: [PATCH 5/8] add inboundIp param to params documentation --- .../docs/providers/aws/instance-parameters.md | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/docs/source/docs/providers/aws/instance-parameters.md b/docs/source/docs/providers/aws/instance-parameters.md index 7dd93d2..8a4544a 100644 --- a/docs/source/docs/providers/aws/instance-parameters.md +++ b/docs/source/docs/providers/aws/instance-parameters.md @@ -1,84 +1,87 @@ # Instance Parameters -Instance parameters are part of the [configuration file], but for each provider they are different. +Instance parameters are part of the [configuration file], but for each provider they are different. Here you can find parameters for an AWS instance: - __`containerName`__ _(optional)_ - a name of the container from the `containers` section. Default value: `default`. -- __`region`__ - AWS region where to run an instance (you can use command `spotty aws spot-prices` to find the +- __`region`__ - AWS region where to run an instance (you can use command `spotty aws spot-prices` to find the cheapest region). -- __`availabilityZone`__ _(optional)_ - AWS availability zone where to run an instance. If a zone is not specified, it +- __`availabilityZone`__ _(optional)_ - AWS availability zone where to run an instance. If a zone is not specified, it will be chosen automatically. -- __`subnetId`__ _(optional)_ - AWS subnet ID. If this parameter is set, the "availabilityZone" parameter should be +- __`subnetId`__ _(optional)_ - AWS subnet ID. If this parameter is set, the "availabilityZone" parameter should be set as well. If it's not specified, a default subnet will be used. -- __`instanceType`__ - a type of the instance to run. You can find more information about -types of GPU instances here: +- __`instanceType`__ - a type of the instance to run. You can find more information about +types of GPU instances here: [Recommended GPU Instances](https://docs.aws.amazon.com/dlami/latest/devguide/gpu.html). - __`spotInstance`__ _(optional)_ - if set to `true`, runs a Spot instance instead of an On-demand instance, -- __`amiName`__ _(optional)_ - a name of the AMI with NVIDIA Docker (default value is "SpottyAMI"). Use the +- __`amiName`__ _(optional)_ - a name of the AMI with NVIDIA Docker (default value is "SpottyAMI"). Use the `spotty aws create-ami` command to create it. This AMI will be used to run your application inside the Docker container. -- __`amiId`__ _(optional)_ - ID of the AMI with NVIDIA Docker. This parameter can be used to run an instance using a +- __`amiId`__ _(optional)_ - ID of the AMI with NVIDIA Docker. This parameter can be used to run an instance using a shared Spotty AMI. -- __`maxPrice`__ _(optional)_ - the maximum price per hour that you are willing to pay for a Spot Instance. By default, -it's the On-demand price for the chosen instance type. Read more here: +- __`maxPrice`__ _(optional)_ - the maximum price per hour that you are willing to pay for a Spot Instance. By default, +it's the On-demand price for the chosen instance type. Read more here: [Spot Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html). -- __`rootVolumeSize`__ _(optional)_ - size of the root volume in GB. The root volume will be destroyed once +- __`rootVolumeSize`__ _(optional)_ - size of the root volume in GB. The root volume will be destroyed once the instance is terminated. Use attached volumes to store the data you need to keep (see "volumes" parameter below). -- __`dockerDataRoot`__ _(optional)_ - directory where Docker will store all downloaded and built images. +- __`dockerDataRoot`__ _(optional)_ - directory where Docker will store all downloaded and built images. Read more: [Caching Docker Image on an EBS Volume]. - __`volumes`__ _(optional)_ - the list of volumes to attach to the instance: - - __`name`__ - a name of the volume. This name should match one of the container's `volumeMounts` to have this + - __`name`__ - a name of the volume. This name should match one of the container's `volumeMounts` to have this volume attached to the container's filesystem. - __`parameters`__ _(optional)_ - parameters of the volume: - - __`type`__ _(optional)_ - the volume type. Supported types: "__gp2__", "__sc1__", "__st1__" - and "__standard__". The default value is "gp2". Read more here: + - __`type`__ _(optional)_ - the volume type. Supported types: "__gp2__", "__sc1__", "__st1__" + and "__standard__". The default value is "gp2". Read more here: [Amazon EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). - - - __`size`__ _(optional)_ - size of the volume in GB. Size of the volume cannot be less than the size of + + - __`size`__ _(optional)_ - size of the volume in GB. Size of the volume cannot be less than the size of the existing snapshot but can be increased. - - __`deletionPolicy`__ _(optional)_ - what to do with the volume once the instance is terminated using the - `spotty stop` command. Possible values include: "__Retain__" _(value by default)_, "__CreateSnapshot__", + - __`deletionPolicy`__ _(optional)_ - what to do with the volume once the instance is terminated using the + `spotty stop` command. Possible values include: "__Retain__" _(value by default)_, "__CreateSnapshot__", "__UpdateSnapshot__" and "__Delete__". Read more here: [EBS Volumes and Deletion Policies]. - - __`volumeName`__ _(optional)_ - name of the EBS volume. The default name is + - __`volumeName`__ _(optional)_ - name of the EBS volume. The default name is "{project_name}-{instance_name}-{volume_name}". - - __`mountDir`__ _(optional)_ - directory where the volume will be mounted on the instance. The default + - __`mountDir`__ _(optional)_ - directory where the volume will be mounted on the instance. The default directory is "/mnt/{ebs_volume_name}". - __`ports`__ _(optional)_ - list of ports to open on the instance. For example: ```yaml ports: [6006, 8888] ``` - It will open ports 6006 for TensorBoard and 8888 for Jupyter Notebook. + It will open ports 6006 for TensorBoard and 8888 for Jupyter Notebook. + +-__`inboundIp`__ _(optional)_ - an IP address or CIDR range to use as a whitelist for all ports provided +to the security group. The default is to not use a whitelist. -- __`localSshPort`__ _(optional)_ - if this parameter is set, all the Spotty commands will create SSH connections -with the instance using the IP address __127.0.0.1__ and the specified port. This can be useful in case when an +- __`localSshPort`__ _(optional)_ - if this parameter is set, all the Spotty commands will create SSH connections +with the instance using the IP address __127.0.0.1__ and the specified port. This can be useful in case when an instance doesn't have a public IP address and a jump-server is used for tunneling. -- __`managedPolicyArns`__ _(optional)_ - a list of Amazon Resource Names (ARNs) of the IAM managed policies that -you want to attach to the instance role. Read more about Managed Policies +- __`managedPolicyArns`__ _(optional)_ - a list of Amazon Resource Names (ARNs) of the IAM managed policies that +you want to attach to the instance role. Read more about Managed Policies [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html). - __`instanceProfileArn`__ _(optional)_ - an Amazon Resource Name (ARN) of the IAM Instance Profile that you'd like to attach to the instance. Read more about Instance Profiles [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html). -- __`commands`__ _(optional)_ - commands that should be run on the host OS before the container is started. -For example, you could login to Amazon ECR to pull a Docker image from there +- __`commands`__ _(optional)_ - commands that should be run on the host OS before the container is started. +For example, you could login to Amazon ECR to pull a Docker image from there ([Deep Learning Containers Images](https://docs.aws.amazon.com/dlami/latest/devguide/deep-learning-containers-images.html)): ```yaml commands: | From ffa79c83127351b212d64eda00836596093dc7fb Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Wed, 31 Mar 2021 09:22:59 +0100 Subject: [PATCH 6/8] fix check for IPv6 addresses Forgot to call the .version on the IPNetwork object --- spotty/providers/aws/cfn_templates/instance/template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spotty/providers/aws/cfn_templates/instance/template.py b/spotty/providers/aws/cfn_templates/instance/template.py index d1a561b..ddf9094 100644 --- a/spotty/providers/aws/cfn_templates/instance/template.py +++ b/spotty/providers/aws/cfn_templates/instance/template.py @@ -58,7 +58,7 @@ def prepare_instance_template(ec2, instance_config: InstanceConfig, docker_comma # add ports to the security group for the user-defined inbound IP inbound_ip = instance_config.inbound_ip - cidr_ip = 'CidrIpv6' if inbound_ip == 6 else 'CidrIp' + cidr_ip = 'CidrIpv6' if inbound_ip.version == 6 else 'CidrIp' for port in [22] + instance_config.ports: template['Resources']['InstanceSecurityGroup']['Properties']['SecurityGroupIngress'] += [{ cidr_ip: str(inbound_ip), From ae749de862ecbaa50d48e000dac57c9d4a49e333 Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Wed, 31 Mar 2021 09:34:10 +0100 Subject: [PATCH 7/8] Revert "add inboundIp param to params documentation" This reverts commit 4fb6d742a9009db3060e40bfcf5107cf272e29be. This re-introduces spaces at the end of each markdown line --- .../docs/providers/aws/instance-parameters.md | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/source/docs/providers/aws/instance-parameters.md b/docs/source/docs/providers/aws/instance-parameters.md index 8a4544a..e8d5a1a 100644 --- a/docs/source/docs/providers/aws/instance-parameters.md +++ b/docs/source/docs/providers/aws/instance-parameters.md @@ -1,87 +1,87 @@ # Instance Parameters -Instance parameters are part of the [configuration file], but for each provider they are different. +Instance parameters are part of the [configuration file], but for each provider they are different. Here you can find parameters for an AWS instance: - __`containerName`__ _(optional)_ - a name of the container from the `containers` section. Default value: `default`. -- __`region`__ - AWS region where to run an instance (you can use command `spotty aws spot-prices` to find the +- __`region`__ - AWS region where to run an instance (you can use command `spotty aws spot-prices` to find the cheapest region). -- __`availabilityZone`__ _(optional)_ - AWS availability zone where to run an instance. If a zone is not specified, it +- __`availabilityZone`__ _(optional)_ - AWS availability zone where to run an instance. If a zone is not specified, it will be chosen automatically. -- __`subnetId`__ _(optional)_ - AWS subnet ID. If this parameter is set, the "availabilityZone" parameter should be +- __`subnetId`__ _(optional)_ - AWS subnet ID. If this parameter is set, the "availabilityZone" parameter should be set as well. If it's not specified, a default subnet will be used. -- __`instanceType`__ - a type of the instance to run. You can find more information about -types of GPU instances here: +- __`instanceType`__ - a type of the instance to run. You can find more information about +types of GPU instances here: [Recommended GPU Instances](https://docs.aws.amazon.com/dlami/latest/devguide/gpu.html). - __`spotInstance`__ _(optional)_ - if set to `true`, runs a Spot instance instead of an On-demand instance, -- __`amiName`__ _(optional)_ - a name of the AMI with NVIDIA Docker (default value is "SpottyAMI"). Use the +- __`amiName`__ _(optional)_ - a name of the AMI with NVIDIA Docker (default value is "SpottyAMI"). Use the `spotty aws create-ami` command to create it. This AMI will be used to run your application inside the Docker container. -- __`amiId`__ _(optional)_ - ID of the AMI with NVIDIA Docker. This parameter can be used to run an instance using a +- __`amiId`__ _(optional)_ - ID of the AMI with NVIDIA Docker. This parameter can be used to run an instance using a shared Spotty AMI. -- __`maxPrice`__ _(optional)_ - the maximum price per hour that you are willing to pay for a Spot Instance. By default, -it's the On-demand price for the chosen instance type. Read more here: +- __`maxPrice`__ _(optional)_ - the maximum price per hour that you are willing to pay for a Spot Instance. By default, +it's the On-demand price for the chosen instance type. Read more here: [Spot Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html). -- __`rootVolumeSize`__ _(optional)_ - size of the root volume in GB. The root volume will be destroyed once +- __`rootVolumeSize`__ _(optional)_ - size of the root volume in GB. The root volume will be destroyed once the instance is terminated. Use attached volumes to store the data you need to keep (see "volumes" parameter below). -- __`dockerDataRoot`__ _(optional)_ - directory where Docker will store all downloaded and built images. +- __`dockerDataRoot`__ _(optional)_ - directory where Docker will store all downloaded and built images. Read more: [Caching Docker Image on an EBS Volume]. - __`volumes`__ _(optional)_ - the list of volumes to attach to the instance: - - __`name`__ - a name of the volume. This name should match one of the container's `volumeMounts` to have this + - __`name`__ - a name of the volume. This name should match one of the container's `volumeMounts` to have this volume attached to the container's filesystem. - __`parameters`__ _(optional)_ - parameters of the volume: - - __`type`__ _(optional)_ - the volume type. Supported types: "__gp2__", "__sc1__", "__st1__" - and "__standard__". The default value is "gp2". Read more here: + - __`type`__ _(optional)_ - the volume type. Supported types: "__gp2__", "__sc1__", "__st1__" + and "__standard__". The default value is "gp2". Read more here: [Amazon EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). - - - __`size`__ _(optional)_ - size of the volume in GB. Size of the volume cannot be less than the size of + + - __`size`__ _(optional)_ - size of the volume in GB. Size of the volume cannot be less than the size of the existing snapshot but can be increased. - - __`deletionPolicy`__ _(optional)_ - what to do with the volume once the instance is terminated using the - `spotty stop` command. Possible values include: "__Retain__" _(value by default)_, "__CreateSnapshot__", + - __`deletionPolicy`__ _(optional)_ - what to do with the volume once the instance is terminated using the + `spotty stop` command. Possible values include: "__Retain__" _(value by default)_, "__CreateSnapshot__", "__UpdateSnapshot__" and "__Delete__". Read more here: [EBS Volumes and Deletion Policies]. - - __`volumeName`__ _(optional)_ - name of the EBS volume. The default name is + - __`volumeName`__ _(optional)_ - name of the EBS volume. The default name is "{project_name}-{instance_name}-{volume_name}". - - __`mountDir`__ _(optional)_ - directory where the volume will be mounted on the instance. The default + - __`mountDir`__ _(optional)_ - directory where the volume will be mounted on the instance. The default directory is "/mnt/{ebs_volume_name}". - __`ports`__ _(optional)_ - list of ports to open on the instance. For example: ```yaml ports: [6006, 8888] ``` - It will open ports 6006 for TensorBoard and 8888 for Jupyter Notebook. + It will open ports 6006 for TensorBoard and 8888 for Jupyter Notebook. -__`inboundIp`__ _(optional)_ - an IP address or CIDR range to use as a whitelist for all ports provided -to the security group. The default is to not use a whitelist. +to the security group. The default is to not use a whitelist. -- __`localSshPort`__ _(optional)_ - if this parameter is set, all the Spotty commands will create SSH connections -with the instance using the IP address __127.0.0.1__ and the specified port. This can be useful in case when an +- __`localSshPort`__ _(optional)_ - if this parameter is set, all the Spotty commands will create SSH connections +with the instance using the IP address __127.0.0.1__ and the specified port. This can be useful in case when an instance doesn't have a public IP address and a jump-server is used for tunneling. -- __`managedPolicyArns`__ _(optional)_ - a list of Amazon Resource Names (ARNs) of the IAM managed policies that -you want to attach to the instance role. Read more about Managed Policies +- __`managedPolicyArns`__ _(optional)_ - a list of Amazon Resource Names (ARNs) of the IAM managed policies that +you want to attach to the instance role. Read more about Managed Policies [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html). - __`instanceProfileArn`__ _(optional)_ - an Amazon Resource Name (ARN) of the IAM Instance Profile that you'd like to attach to the instance. Read more about Instance Profiles [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html). -- __`commands`__ _(optional)_ - commands that should be run on the host OS before the container is started. -For example, you could login to Amazon ECR to pull a Docker image from there +- __`commands`__ _(optional)_ - commands that should be run on the host OS before the container is started. +For example, you could login to Amazon ECR to pull a Docker image from there ([Deep Learning Containers Images](https://docs.aws.amazon.com/dlami/latest/devguide/deep-learning-containers-images.html)): ```yaml commands: | From ef95afa91229b969ad6ed3f2df0c4f96b8c417cb Mon Sep 17 00:00:00 2001 From: Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> Date: Wed, 31 Mar 2021 09:38:53 +0100 Subject: [PATCH 8/8] fix code style formatting Single quotes for strings Trailing commas for multiline arrays --- spotty/providers/aws/config/validation.py | 4 ++-- tests/providers/aws/config/instance_config_validation.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spotty/providers/aws/config/validation.py b/spotty/providers/aws/config/validation.py index 9bf7dd5..beaeb8b 100644 --- a/spotty/providers/aws/config/validation.py +++ b/spotty/providers/aws/config/validation.py @@ -31,8 +31,8 @@ def validate_instance_parameters(params: dict): ), Optional('managedPolicyArns', default=[]): [str], Optional('instanceProfileArn', default=None): str, - Optional('inboundIp', default="0.0.0.0/0"): Use(IPNetwork, error='"inboundIp" should be a valid IP ' - 'address or CIDR range') + Optional('inboundIp', default='0.0.0.0/0'): Use(IPNetwork, error='"inboundIp" should be a valid IP ' + 'address or CIDR range'), } volumes_checks = [ diff --git a/tests/providers/aws/config/instance_config_validation.py b/tests/providers/aws/config/instance_config_validation.py index 2752ff6..0d7aec2 100644 --- a/tests/providers/aws/config/instance_config_validation.py +++ b/tests/providers/aws/config/instance_config_validation.py @@ -28,7 +28,7 @@ def test_default_configuration(self): 'spotInstance': False, 'subnetId': '', 'volumes': [], - 'inboundIp': "0.0.0.0/0" + 'inboundIp': '0.0.0.0/0', } self.assertEqual(expected_params, validate_instance_parameters(required_params))