예제 #1
0
 def _mounts(self):
     for i in range(30):
         command = [
             'efs', 'describe-file-systems', '--region', self.region,
             '--creation-token', self.token
         ]
         file_systems = bin_aws(command, key='FileSystems', max=1)
         if file_systems[0]['LifeCycleState'] == 'available':
             command = [
                 'efs', 'describe-mount-targets', '--region', self.region,
                 '--file-system-id', self.id
             ]
             mount_targets = bin_aws(command, key='MountTargets')
             for this in self.subnets:
                 if not must.find.dict_in_list(key='SubnetId',
                                               needle=this,
                                               haystack=mount_targets):
                     command = [
                         'efs', 'create-mount-target', '--region',
                         self.region, '--file-system-id', self.id,
                         '--subnet-id', this, '--security-groups'
                     ]
                     command.extend(self.groups)
                     bin_aws(command, decode_output=False)
                     print('Made {0}'.format(command))  # TODO: Log(...)
             return True
         else:
             print('Waiting for EFS {0} to be available'.format(self.id))
             sleep(1)
     raise TimeoutError
예제 #2
0
 def _create(self):
     """
     Create a VPC
     IPv6 Error:
     "An error occurred (InvalidParameter) when calling the CreateVpc operation:
         The parameter amazon-provided-ipv6-cidr-block is not recognized"
     means IPv6 is not yet available in the region given.
     https://github.com/aws/aws-cli/issues/2343
     :return:
     """
     command = [
         'ec2',
         'create-vpc',
         '--region',
         self.region,
         '--cidr-block',
         self.cidr,
     ]
     if self.ipv6:
         command.append('--amazon-provided-ipv6-cidr-block')
     result = bin_aws(command)
     print('Created {0}'.format(command))  # TODO: Log(...)
     self.id = result['Vpc']['VpcId']
     command = [
         'ec2', 'create-tags', '--region', self.region, '--resources',
         self.id, '--tags', 'Key=Name,Value={0}'.format(self.name)
     ]
     bin_aws(command, decode_output=False)
     print('Named {0}'.format(command))  # TODO: Log(...)
     return True
예제 #3
0
 def _get(self):
     """
     Get information about VPC from AWS and update self
     :return: Bool
     """
     command = [
         'ec2', 'describe-tags', '--region', self.region, '--filter',
         'Name=resource-type,Values=vpc',
         'Name=value,Values={0}'.format(self.name)
     ]
     result = bin_aws(command, key='Tags', max=1)
     if not result:
         return False
     self.id = result[0]['ResourceId']
     command = [
         'ec2', 'describe-vpcs', '--region', self.region, '--vpc-ids',
         self.id
     ]
     result = bin_aws(command, key='Vpcs', max=1)
     self.cidr = result[0]['CidrBlock']
     self.id = result[0]['VpcId']
     if 'Ipv6CidrBlockAssociationSet' in result[0]:
         self.ipv6 = True
     else:
         self.ipv6 = False
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #4
0
 def _create(self):
     if self.instance:
         command = [
             'ec2', 'describe-instances', '--region', self.region,
             '--instance-ids', self.instance
         ]
         reservations = bin_aws(command, key='Reservations')
         # Force correct AZ
         self.zone = reservations[0]['Instances'][0]['Placement'][
             'AvailabilityZone']
     if not self.zone:
         raise MissingArgument(
             '{0}: param "zone" required if "instance" not provided'.format(
                 self.name))
     command = [
         'ec2', 'create-volume', '--region', self.region, '--size',
         self.size, '--volume-type', self.kind, '--availability-zone',
         self.zone
     ]
     result = bin_aws(command)
     self.id = result['VolumeId']
     print('Created {0}'.format(command))  # TODO: Log(...)
     command = [
         'ec2', 'create-tags', '--region', self.region, '--resources',
         self.id, '--tags', 'Key=Name,Value={0}'.format(self.name)
     ]
     bin_aws(command, decode_output=False)
     print('Named {0}'.format(command))  # TODO: Log(...)
     return True
예제 #5
0
 def _groups(self, groups):
     command = [
         'elb', 'apply-security-groups-to-load-balancer', '--region',
         self.region, '--load-balancer-name', self.name, '--security-groups'
     ]
     command.extend(groups)
     bin_aws(command, decode_output=False)
     print('Applied {0}'.format(command))  # TODO: Log(...)
예제 #6
0
 def _rm_zone(self, zone):
     command = [
         'elb', 'disable-availability-zones-for-load-balancer', '--region',
         self.region, '--load-balancer-name', self.name,
         '--availability-zones', zone
     ]
     bin_aws(command)
     self.zones.remove(zone)
     print('Disabled {0}'.format(command))  # TODO: Log(...)
     return True
예제 #7
0
 def _detach(self, instances):
     if not instances:
         return False
     command = [
         'elb', 'deregister-instances-from-load-balancer', '--region',
         self.region, '--load-balancer-name', self.name, '--instances'
     ]
     command.extend(instances)
     bin_aws(command, decode_output=False)
     print('Detached {0}'.format(command))  # TODO: Log(...)
예제 #8
0
 def _rm_listener(self, listener):
     command = [
         'elb', 'delete-load-balancer-listeners', '--region', self.region,
         '--load-balancer-name', self.name, '--load-balancer-ports',
         str(listener['LoadBalancerPort'])
     ]
     bin_aws(command)
     self.listeners.remove(listener)
     print('Removed {0}'.format(command))  # TODO: Log(...)
     return True
예제 #9
0
 def _add_listener(self, listener):
     command = [
         'elb', 'create-load-balancer-listeners', '--region', self.region,
         '--load-balancer-name', self.name, '--listeners',
         str(listener).replace("'", '"')
     ]
     bin_aws(command)
     self.listeners.append(listener)
     print('Added {0}'.format(command))  # TODO: Log(...)
     return True
예제 #10
0
 def _rm_instance(self, instances):
     instances = must.be_list(instances)
     command = [
         'elb', 'deregister-instances-from-load-balancer', '--region',
         self.region, '--load-balancer-name', self.name, '--instances'
     ]
     command.extend(instances)
     bin_aws(command)
     for this in instances:
         if this in self.instances:
             self.instances.remove(this)
     print('Deregistered {0}'.format(command))  # TODO: Log(...)
     return True
예제 #11
0
 def _add_instance(self, instances):
     instances = must.be_list(instances)
     command = [
         'elb', 'register-instances-with-load-balancer', '--region',
         self.region, '--load-balancer-name', self.name, '--instances'
     ]
     command.extend(instances)
     bin_aws(command)
     for this in instances:
         if this not in self.instances:
             self.instances.append(this)
     print('Registered {0}'.format(command))  # TODO: Log(...)
     return True
예제 #12
0
 def _attach(self):
     if not self.instance and not self.device:
         return False
     if not self.instance or not self.device:
         raise MissingArgument(
             '{0}: device and instance are both required, else omit both'.
             format(self.name))
     self._wait_for_volume()
     self._wait_for_instance()
     command = [
         'ec2', 'attach-volume', '--region', self.region, '--volume-id',
         self.id, '--instance-id', self.instance, '--device', self.device
     ]
     bin_aws(command)
     print('Attached {0}'.format(command))  # TODO: Log(...)
예제 #13
0
 def _create(self):
     command = [
         'efs', 'create-file-system', '--region', self.region,
         '--creation-token', self.token, '--performance-mode', self.kind
     ]
     result = bin_aws(command)
     self.id = result['FileSystemId']
     print('Created {0}'.format(command))  # TODO: Log(...)
     command = [
         'efs', 'create-tags', '--region', self.region, '--file-system-id',
         self.id, '--tags', 'Key=Name,Value={0}'.format(self.name)
     ]
     bin_aws(command, decode_output=False)
     print('Named {0}'.format(command))  # TODO: Log(...)
     return True
예제 #14
0
 def _create(self):
     """
     Create a Security Group
     :return:
     """
     # AWS grants all new SGs this default outbound rule "This is pro-human & anti-machine behavior."
     default_egress = {
         'Ipv6Ranges': [],
         'PrefixListIds': [],
         'IpRanges': [{
             'CidrIp': '0.0.0.0/0'
         }],
         'UserIdGroupPairs': [],
         'IpProtocol': '-1'
     }
     command = [
         'ec2', 'create-security-group', '--region', self.region,
         '--group-name', self.name, '--description', self.description,
         '--vpc-id', self.vpc
     ]
     try:
         self.id = bin_aws(command, key='GroupId')
     except AWSDuplicate:
         return False  # OK if it already exists.
     print('Created {0}'.format(command))  # TODO: Log(...)
     self.IpPermissions = []
     self.IpPermissionsEgress = [default_egress]
     self.changed = True
     return True
예제 #15
0
 def _create(self, zones, groups, scheme, listeners):
     command = [
         'elb', 'create-load-balancer', '--region', self.region,
         '--load-balancer-name', self.name
     ]
     if scheme is not None:
         command.append('--scheme')
         command.append(scheme)
     if groups is not None:
         command.append('--security-groups')
         command.extend(groups)
     if zones is not None:
         command.append('--availability-zones')
         command.extend(zones)
     command.append('--listeners')
     for listen in listeners:
         command.append(str(listen).replace(
             "'", '"'))  # Convert Dictionaries to Strings for JSON
     result = bin_aws(command)
     self.dns = result['DNSName']
     self.zones = zones
     self.groups = groups
     self.listeners = listeners
     print('Created {0}'.format(command))  # TODO: Log(...)
     return True
예제 #16
0
 def _get(self):
     command = [
         'ec2', 'describe-tags', '--region', self.region, '--filter',
         'Name=resource-type,Values=instance',
         'Name=value,Values={0}'.format(self.name)
     ]
     result = bin_aws(command)['Tags']
     if not result:
         self.deficit = self.count  # Result is []. Deficit is 100%.
         return False
     command = [
         'ec2', 'describe-instances', '--region', self.region,
         '--instance-ids'
     ]
     for this in result:
         command.append(this['ResourceId'])
     # This does not filter the way we expected it to.
     # It looks like if any of the instance Ids are not all placed in self.zone then NotFound is raised for all.
     # if self.zone:
     #     command.append('--filter',)
     #     command.append('Name=availability-zone,Values={0}'.format(self.zone))
     reservations = bin_aws(command, key='Reservations')
     all_instances = [
     ]  # Will become list() of ALL instances (even terminated) as dict()s
     for this in reservations:  # Extract Instances from each Reservation and merge them into a list()
         all_instances.extend(this['Instances'])
     for this in all_instances:
         if this['State']['Code'] in [0, 16]:  # "Pending, Running"
             if self.zone is None or self.zone == this['Placement'][
                     'AvailabilityZone']:
                 self.zones.add(this['Placement']['AvailabilityZone'])
                 self.id.add(this['InstanceId'])
                 if 'PrivateIpAddress' in this:
                     self.private_ips.add(this['PrivateIpAddress'])
                 if 'PublicIpAddress' in this:
                     self.public_ips.add(this['PublicIpAddress'])
                 if 'SubnetId' in this:
                     self.subnets.add(this['SubnetId'])
     running_count = len(self.id)
     need_running = self.count
     if running_count != need_running:
         self.deficit = need_running - running_count
         return False
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #17
0
 def _add_rule(self, ip_permissions, egress):
     """
     :param ip_permissions: Dict of IP Permissions
     :param egress: Bool
     :return: Bool
     """
     direction = 'authorize-security-group-ingress'
     if egress:
         direction = 'authorize-security-group-egress'
     command = [
         'ec2', direction, '--region', self.region, '--group-id', self.id,
         '--ip-permissions',
         str(ip_permissions).replace("'", '"')
     ]
     bin_aws(command)
     print('Authorized: {0}'.format(ip_permissions))  # TODO: Log(...)
     self.changed = True
     return True
예제 #18
0
 def _get(self):
     command = ['ec2', 'describe-key-pairs', '--region', self.region,
                '--key-names', self.name]
     result = bin_aws(command)
     if not result:
         return False
     self.fingerprint = result['KeyPairs'][0]['KeyFingerprint']
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #19
0
 def _delete(self):
     """
     Delete myself by my own id.
     As of 20170114 no other methods call me. You must do `foo._delete()`
     :return:
     """
     command = [
         'ec2',
         'delete-security-group',
         '--region',
         self.region,
         # '--dry-run',
         '--group-id',
         self.id
     ]
     bin_aws(command, decode_output=False)
     print('Deleted {0}'.format(command))  # TODO: Log(...)
     return True
예제 #20
0
 def _get(self):
     command = [
         'efs', 'describe-file-systems', '--region', self.region,
         '--creation-token', self.token
     ]
     file_systems = bin_aws(command, key='FileSystems', max=1)
     if not file_systems:
         return False
     self.id = file_systems[0]['FileSystemId']
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #21
0
 def _create(self):
     if not self.cidr:
         raise MissingArgument('Subnet {0} not found and cannot create new one without cidr'.format(self.name))
     command = ['ec2', 'create-subnet', '--region', self.region,
                '--vpc-id', self.vpc,
                '--cidr-block', self.cidr,
                ]
     if self.zone:
         command.append('--availability-zone')
         command.append(must.be_string(self.zone))
     result = bin_aws(command)
     print('Created {0}'.format(command))  # TODO: Log(...)
     self.id = result['Subnet']['SubnetId']
     command = ['ec2', 'create-tags',
                '--region', self.region,
                '--resources', self.id,
                '--tags', 'Key=Name,Value={0}'.format(self.name)
                ]
     bin_aws(command, decode_output=False)
     print('Named {0}'.format(command))  # TODO: Log(...)
     return True
예제 #22
0
 def _create(self):
     if self.deficit < 1:
         # This should never usually happen but is possible if the User changes the count to a lower
         # number after the original instance(s) were created.
         raise TooMany('Cannot create {0} instances of {1}'.format(
             self.deficit, self.name))
     command = [
         'ec2', 'run-instances', '--region', self.region, '--instance-type',
         self.size, '--count',
         str(self.deficit), '--key-name', self.key, '--image-id',
         self.image, '--security-group-ids'
     ]
     command.extend(self.groups)
     if not self.public:
         command.append('--no-associate-public-ip-address')
     if self.zone:
         placement = {
             "AvailabilityZone": self.zone,
             "GroupName": "",
             "Tenancy": "default",
         }
         command.append('--placement')
         command.append(str(placement).replace("'", '"'))
     if self.script:
         command.append('--user-data')
         command.append('file://{0}'.format(self.script))
     instances = bin_aws(command, key='Instances')
     print('Created {0}'.format(command))  # TODO: Log(...)
     for this in instances:
         self.id.add(this['InstanceId'])
         command = [
             'ec2', 'create-tags', '--region', self.region, '--resources',
             this['InstanceId'], '--tags',
             'Key=Name,Value={0}'.format(self.name)
         ]
         bin_aws(command, decode_output=False)
         print('Named {0}'.format(command))  # TODO: Log(...)
     self.deficit = 0
     return True
예제 #23
0
 def _wait_for_volume(self):
     for i in range(30):
         sleep(1)
         command = [
             'ec2', 'describe-volumes', '--region', self.region,
             '--volume-ids', self.id
         ]
         volumes = bin_aws(command, key='Volumes', max=1)
         if volumes[0]['State'] == 'available':
             return True
         else:
             print('Waiting for volume {0} to be available'.format(self.id))
     raise TimeoutError
예제 #24
0
 def _create(self):
     command = [
         'rds', 'create-db-instance', '--region', self.region,
         '--db-instance-identifier', self.name, '--db-name', self.name,
         '--db-instance-class', self.size, '--engine', self.engine,
         '--master-username', self.username, '--master-user-password',
         self.password, '--availability-zone', self.zone,
         '--allocated-storage',
         must.be_string(self.gb), '--vpc-security-group-ids'
     ]
     command.extend(self.groups)
     result = bin_aws(command)
     pprint(result)
     print('Created {0}'.format(command))  # TODO: Log(...)
     return True
예제 #25
0
 def _get(self):
     command = [
         'ec2',
         'describe-volumes',
         '--region',
         self.region,
         '--filters',
         'Name=attachment.device,Values={0}'.format(self.device),
         'Name=attachment.instance-id,Values={0}'.format(self.instance),
     ]
     result = bin_aws(command, key='Volumes', max=1)
     if not result:
         return False
     self.id = result[0]['VolumeId']
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #26
0
 def _get(self):
     command = ['ec2', 'describe-subnets', '--region', self.region,
                '--filter',
                'Name=vpc-id,Values={0}'.format(self.vpc),
                ]
     if self.cidr:
         command.append('Name=cidrBlock,Values={0}'.format(self.cidr))  # Prefer to search by CIDR
     else:
         command.append('Name=tag:Name,Values={0}'.format(self.name))  # Else by name if User doesnt know the CIDR
     result = bin_aws(command, key='Subnets', max=1)
     if not result:
         return False
     print('Got {0}'.format(command))  # TODO: Log(...)
     self.id = result[0]['SubnetId']
     self.zone = result[0]['AvailabilityZone']
     self.cidr = result[0]['CidrBlock']
     return True
예제 #27
0
 def _get(self):
     """
     Get information about Security Group from AWS and update self
     :return: Bool
     """
     command = [
         'ec2', 'describe-security-groups', '--region', self.region,
         '--group-names', self.name
     ]
     result = bin_aws(command, key='SecurityGroups',
                      max=1)  # will raise NotFound if empty
     me = result[0]
     self.id = me['GroupId']
     self.owner = me['OwnerId']
     self.IpPermissions = self._break_out(me['IpPermissions'])
     self.IpPermissionsEgress = self._break_out(me['IpPermissionsEgress'])
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #28
0
 def _get(self):
     command = ['rds', 'describe-db-instances', '--region', self.region]
     result = bin_aws(command)['DBInstances']
     found = must.find.dict_in_list(key='DBName',
                                    needle=self.name,
                                    haystack=result)
     if not found:
         return False
     self.id = found['DbiResourceId']
     self.engine = found['Engine']
     self.groups = found['DBSecurityGroups']
     self.zone = found['AvailabilityZone']
     self.gb = found['AllocatedStorage']
     self.username = found['MasterUsername']
     if 'Endpoint' in found:
         self.dns = found['Endpoint']['Address']
     self.public = found['PubliclyAccessible']
     print('Got {0}'.format(command))  # TODO: Log(...)
     return True
예제 #29
0
 def _create(self):
     path_to_key = os.path.join(self.directory, '{0}.pem'.format(self.name))
     try:
         private_key = fileasobj.FileAsObj(path_to_key)
     except FileNotFoundError:
         private_key = fileasobj.FileAsObj()
         private_key.filename = path_to_key
     if private_key.contents:
         raise AWSDuplicate('Non-empty file {0} already exists.'.format(path_to_key))
     private_key.save()  # Make sure we can write to the file before starting work.
     command = ['ec2', 'create-key-pair', '--region', self.region,
                '--key-name', self.name,
                '--query', 'KeyMaterial',
                '--output', 'text']
     result = bin_aws(command, decode_output=False)
     private_key.add(result)
     private_key.save()
     print('Created {0}'.format(command))  # TODO: Log(...)
     return True
예제 #30
0
 def _wait_for_instance(self):
     for i in range(30):
         command = [
             'ec2', 'describe-instances', '--region', self.region,
             '--instance-ids', self.instance
         ]
         reservations = bin_aws(command, key='Reservations')
         instances = reservations[0]['Instances']
         state = instances[0]['State']
         if state['Code'] == 0:  # Pending
             print('Waiting for instance {0} to be available'.format(
                 self.instance))
             sleep(2)
         elif state['Code'] == 16:  # Running
             return True
         else:
             print('Instance {0} in unexpected state {1}'.format(
                 self.instance, state['Name']))
             sleep(1)
     raise TimeoutError