예제 #1
0
    def _add_ingress_rule(self, args, security_group):
        """ Add a local -> PostgreSQL ingress rule to a security group """
        ec2 = self._get_aws_client('ec2', args)
        ip = args.public_ip if args.public_ip else\
            '{}/32'.format(get_my_ip())
        port = args.db_port or 5432
        IpRanges = []

        ip = ip.split(',')
        for i in ip:
            IpRanges.append({
                'CidrIp': i,
                'Description': 'pgcloud client {}'.format(i)
            })
        try:
            output({'Adding': 'Adding ingress rule for: {}...'.format(ip)})
            debug(args, 'Adding ingress rule for: {}...'.format(ip))
            ec2.authorize_security_group_ingress(GroupId=security_group,
                                                 IpPermissions=[
                                                     {
                                                         'FromPort': port,
                                                         'ToPort': port,
                                                         'IpProtocol': 'tcp',
                                                         'IpRanges': IpRanges
                                                     },
                                                 ])
        except Exception as e:
            error(args, e)
예제 #2
0
    def _create_firewall_rule(self, args):
        """ Create a firewall rule on an instance """
        firewall_rules = []
        postgresql_client = self._get_azure_client('postgresql')
        ip = args.public_ips if args.public_ips else get_my_ip()
        ip_list = ip.split(',')
        for ip in ip_list:
            ip = ip.strip()
            if '-' in ip:
                start_ip = ip.split('-')[0]
                end_ip = ip.split('-')[1]
            else:
                start_ip = ip
                end_ip = ip
            name = 'pgacloud_{}_{}_{}'.format(args.name, ip.replace('.', '-'),
                                              get_random_id())

            # Provision the rule and wait for completion
            debug('Adding ingress rule for: {0} - {1} ...'.format(
                start_ip, end_ip))
            poller = postgresql_client.firewall_rules.begin_create_or_update(
                resource_group_name=args.resource_group,
                server_name=args.name,
                firewall_rule_name=name,
                parameters=FirewallRule(start_ip_address=start_ip,
                                        end_ip_address=end_ip))

            firewall_rule = poller.result()

            firewall_rules.append(firewall_rule.__dict__)
        return firewall_rules
예제 #3
0
    def _delete_security_group(self, args, id):
        """ Delete a security group """
        ec2 = self._get_aws_client('ec2', args)

        debug(args, 'Deleting security group: {}...'.format(id))
        try:
            ec2.delete_security_group(GroupId=id)
        except Exception as e:
            error(args, str(e))
예제 #4
0
    def _delete_azure_instance(self, args):
        """ Delete an Azure instance """
        # Obtain the management client object
        postgresql_client = self._get_azure_client('postgresql')

        # Delete the server and wait for the result
        debug('Deleting Azure instance: {}...'.format(args.name))
        try:
            poller = postgresql_client.servers.begin_delete(
                args.resource_group, args.name)
        except Exception as e:
            error(str(e))

        poller.result()
예제 #5
0
    def _create_resource_group(self, args):
        """ Create the Resource Group if it doesn't exist """
        resource_client = self._get_azure_client('resource')

        group_list = resource_client.resource_groups.list()
        for group in list(group_list):
            if group.name == args.resource_group:
                debug('Resource group already exist with name: {}...'.format(
                    args.resource_group))
                return group.__dict__
        debug('Creating resource group with name: {}...'.format(
            args.resource_group))
        result = resource_client.resource_groups.create_or_update(
            args.resource_group, {"location": args.region})
        return result.__dict__
예제 #6
0
    def _create_azure_instance(self, args):
        """ Create an Azure instance """
        # Obtain the management client object
        postgresql_client = self._get_azure_client('postgresql')
        # Check if the server already exists
        svr = None
        try:
            svr = postgresql_client.servers.get(args.resource_group, args.name)
        except ResourceNotFoundError:
            pass
        except Exception as e:
            error(str(e))

        if svr is not None:
            error('Azure Database for PostgreSQL instance {} already '
                  'exists.'.format(args.name))

        db_password = self._database_pass if self._database_pass is not None \
            else args.db_password

        # Provision the server and wait for the result
        debug('Creating Azure instance: {}...'.format(args.name))

        try:
            poller = postgresql_client.servers.begin_create(
                resource_group_name=args.resource_group,
                server_name=args.name,
                parameters=Server(
                    sku=Sku(name=args.instance_type,
                            tier=SkuTier(args.instance_tier_type)),
                    high_availability=HighAvailability(
                        mode=args.high_availability),
                    administrator_login=args.db_username,
                    administrator_login_password=db_password,
                    version=args.db_major_version,
                    storage=Storage(storage_size_gb=args.storage_size),
                    location=args.region,
                    create_mode=CreateMode("Default")))
        except Exception as e:
            error(str(e))

        server = poller.result()

        return server.__dict__
예제 #7
0
    def _create_security_group(self, args):
        """ Create a new security group for the instance """
        ec2 = self._get_aws_client('ec2', args)
        ip = args.public_ip if args.public_ip else get_my_ip()
        ip = ip.split(',')

        # Deploy the security group
        try:
            name = 'pgacloud_{}_{}_{}'.format(args.name,
                                              ip[0].replace('.', '-'),
                                              get_random_id())
            debug(args, 'Creating security group: {}...'.format(name))
            output({'Creating': 'Creating security group: {}...'.format(name)})
            response = ec2.create_security_group(
                Description='Inbound access for {} to RDS instance {}'.format(
                    ip[0], args.name),
                GroupName=name)
        except Exception as e:
            error(args, str(e))

        return response['GroupId']
예제 #8
0
    def _delete_rds_instance(self, args, name):
        """ Delete an RDS instance """
        rds = self._get_aws_client('rds', args)

        debug(args, 'Deleting RDS instance: {}...'.format(name))
        try:
            rds.delete_db_instance(DBInstanceIdentifier=name,
                                   SkipFinalSnapshot=True,
                                   DeleteAutomatedBackups=True)
        except Exception as e:
            error(args, str(e))

        # Wait for completion
        while True:
            try:
                rds.describe_db_instances(DBInstanceIdentifier=args.name)
            except rds.exceptions.DBInstanceNotFoundFault:
                return
            except Exception as e:
                error(args, str(e))

            time.sleep(5)
예제 #9
0
    def _create_rds_instance(self, args, security_group):
        """ Create an RDS instance """
        ec2 = self._get_aws_client('ec2', args)
        rds = self._get_aws_client('rds', args)

        db_password = self._database_pass if self._database_pass is not None\
            else args.db_password

        try:
            debug(args, 'Creating RDS instance: {}...'.format(args.name))
            rds.create_db_instance(DBInstanceIdentifier=args.name,
                                   AllocatedStorage=args.storage_size,
                                   DBName=args.db_name,
                                   Engine='postgres',
                                   Port=args.db_port,
                                   EngineVersion=args.db_version,
                                   StorageType=args.storage_type,
                                   StorageEncrypted=True,
                                   Iops=args.storage_iops,
                                   AutoMinorVersionUpgrade=True,
                                   MultiAZ=False,
                                   MasterUsername=args.db_username,
                                   MasterUserPassword=db_password,
                                   DBInstanceClass=args.instance_type,
                                   VpcSecurityGroupIds=[
                                       security_group,
                                   ])

        except rds.exceptions.DBInstanceAlreadyExistsFault as e:
            try:
                debug(args, DEL_SEC_GROUP_MSG.format(security_group))
                ec2.delete_security_group(GroupId=security_group)
            except Exception:
                pass
            error(args, 'RDS instance {} already exists.'.format(args.name))
        except Exception as e:
            try:
                debug(args, DEL_SEC_GROUP_MSG.format(security_group))
                ec2.delete_security_group(GroupId=security_group)
            except Exception:
                pass
            error(args, str(e))

        # Wait for completion
        running = True
        while running:
            response = rds.describe_db_instances(
                DBInstanceIdentifier=args.name)

            db_instance = response['DBInstances'][0]
            status = db_instance['DBInstanceStatus']

            if status != 'creating' and status != 'backing-up':
                running = False

            if running:
                time.sleep(5)

        return response['DBInstances']
예제 #10
0
    def get_instance_status(self, instance_id):
        """ Get the biganimal cluster status """

        running = True
        status = None
        while running:
            _url = "{0}/{1}/{2}".format(self.BASE_URL, 'clusters', instance_id)
            _headers = {
                "accept": "application/json",
                'authorization': 'Bearer {0}'.format(self._access_key)
            }

            cluster_resp = requests.get(_url, headers=_headers)

            if cluster_resp.status_code == 200 and cluster_resp.content:
                cluster_info = json.loads(cluster_resp.content)

                self._cluster_info = cluster_info[0]

                if self._cluster_info['instance'] != 0 and\
                    self._cluster_info['phase'] not in [
                    'Cluster creation request received',
                    'Setting up primary',
                    'Creating CNP cluster'
                ]:
                    running = False

                if status != self._cluster_info['phase']:
                    status = self._cluster_info['phase']
                    debug('BigAnimal cluster status: {}...'.format(status))
            else:
                running = False
                error(str(cluster_resp.text))

            if running:
                time.sleep(5)

        return self._cluster_info
예제 #11
0
    def cmd_create_instance(self, args):
        """ Create a biganimal cluster """

        try:
            private_network = True if args.private_network == '1' else False
            ip = args.public_ip if args.public_ip else '0.0.0.0/0'
            ip_ranges = []

            ip = ip.split(',')
            for i in ip:
                ip_ranges.append([i, 'pgcloud client {}'.format(i)])

            debug('Creating BigAnimal cluster: {}...'.format(args.name))

            _url = "{0}/{1}".format(self.BASE_URL, 'clusters')
            _headers = {
                "content-type": "application/json",
                "accept": "application/json",
                'authorization': 'Bearer {0}'.format(self._access_key)
            }

            _data = {
                'clusterName': args.name,
                'instanceTypeId': args.instance_type,
                'password': self._database_pass,
                'postgresTypeId': args.db_type,
                'postgresVersion': args.db_version,
                'privateNetworking': private_network,
                'providerId': 'azure',
                'regionId': args.region,
                'replicas': 3,
                'volumePropertiesId': args.volume_properties,
                'volumeTypeId': args.volume_type,
                'clusterArch': {
                    'id': args.cluster_arch,
                    'nodes': int(args.nodes)
                },
                'pgConfigMap': [],
            }

            if not private_network:
                _data['allowIpRangeMap'] = ip_ranges

            cluster_resp = requests.post(_url,
                                         headers=_headers,
                                         data=json.dumps(_data))

            if cluster_resp.status_code == 202 and cluster_resp.content:
                cluster_info = json.loads(cluster_resp.content)
                instance_id = cluster_info['pgId']
                instance = self.get_instance_status(instance_id)
                data = {
                    'instance': {
                        'ImageName':
                        instance['imageName'],
                        'Database Type':
                        instance['pgType']['name'],
                        'Hostname':
                        instance['clusterConnectionInfo']['serviceName'],
                        'Port':
                        instance['clusterConnectionInfo']['port'],
                        'Database':
                        instance['clusterConnectionInfo']['databaseName'],
                        'Username':
                        instance['clusterConnectionInfo']['username']
                    }
                }

                output(data)
            else:
                error(str(cluster_resp.text))

        except Exception as e:
            debug(str(e))