示例#1
0
def get_client(module):
    # Retrieve creds file variables
    creds_file_loaded_vars = dict()

    credentials_path = module.params.get('credentials_path')

    if credentials_path is not None:
        try:
            with open(credentials_path, "r") as creds:
                for line in creds:
                    eq_index = line.find('=')
                    var_name = line[:eq_index].strip()
                    string_value = line[eq_index + 1:].strip()
                    creds_file_loaded_vars[var_name] = string_value
        except IOError:
            pass
    # End of creds file retrieval

    token = module.params.get('token')
    if not token:
        token = creds_file_loaded_vars.get("token")

    account = module.params.get('account_id')
    if not account:
        account = creds_file_loaded_vars.get("account")

    client = spotinst.SpotinstClient(auth_token=token, print_output=False)

    if account is not None:
        client = spotinst.SpotinstClient(auth_token=token,
                                         account_id=account,
                                         print_output=False)

    return client
示例#2
0
def launcher(api_token, account_id, group_id, app_name, deployment_group_name,
             timeout, github_repo, commit_id):

    unique_id = get_uuid()[2:-1]
    spot_client = spotinst_sdk.SpotinstClient(auth_token=api_token,
                                              account_id=account_id)

    green_tag = spotinst_blue_green_deployment.Tag()
    green_tag.tag_key = 'GreenIdentifier'
    green_tag.tag_value = unique_id

    deployment_group = spotinst_blue_green_deployment.DeploymentGroup()
    deployment_group.deployment_group_name = deployment_group_name
    deployment_group.application_name = app_name

    deployment = spotinst_blue_green_deployment.BlueGreenDeployment(
        tags=[green_tag],
        deployment_groups=[deployment_group],
        timeout=timeout)
    pre_deployment_count = len(
        spot_client.get_elastigroup_active_instances(group_id))
    spot_client.create_blue_green_deployment(group_id, deployment)

    git_loc = gitHubLocation(github_repo, commit_id)

    revision = Revision('GitHub', git_loc)
    tags = Tags(Key='GreenIdentifier', Value=unique_id, Type='KEY_AND_VALUE')
    tag_filters = tagFilters([tags])
    bg = BlueGreenDeployment(applicationName=app_name,
                             deploymentGroupName=deployment_group_name,
                             revision=revision,
                             targetInstances=tag_filters)

    post_deployment_count = 0
    while pre_deployment_count > post_deployment_count:
        print('Waiting for Green Deployment Instances')
        time.sleep(30)
        post_deployment_count = len(
            spot_client.get_elastigroup_active_instances(group_id))

    print('Waiting for Green Deployment Instances Readiness')
    wait_ec2readiness(tags)

    codedeploy_client = boto3.client('codedeploy')
    codedeploy_client.create_deployment(
        applicationName=bg.applicationName,
        deploymentGroupName=bg.deploymentGroupName,
        revision=todict(bg.revision),
        targetInstances=todict(bg.targetInstances))

    spot_deployment_state = spot_client.get_blue_green_deployment(group_id)

    print("Launcher function complete")
示例#3
0
def connection(token_type):
    '''
    Initialize connection with Spotinst API
    '''
    try:
        account = netrc.netrc().authenticators(token_type)[0]
        token =  netrc.netrc().authenticators(token_type)[2]

    except:
        netrc.NetrcParseError( "No authenticators for %s" %token_type)
        print ("Can't find .netrc file. Exiting")
        sys.exit(1)
    
    spotinst_client = spotinst_sdk.SpotinstClient(auth_token=token, account_id=account)
    return spotinst_client
示例#4
0
def main():
    fields = dict(
        account_id=dict(type='str'),
        availability_vs_cost=dict(type='str', required=True),
        availability_zones=dict(type='list', required=True),
        block_device_mappings=dict(type='list'),
        chef=dict(type='dict'),
        credentials_path=dict(type='path', default="~/.spotinst/credentials"),
        do_not_update=dict(default=[], type='list'),
        down_scaling_policies=dict(type='list'),
        draining_timeout=dict(type='int'),
        ebs_optimized=dict(type='bool'),
        ebs_volume_pool=dict(type='list'),
        ecs=dict(type='dict'),
        elastic_beanstalk=dict(type='dict'),
        elastic_ips=dict(type='list'),
        fallback_to_od=dict(type='bool'),
        id=dict(type='str'),
        health_check_grace_period=dict(type='int'),
        health_check_type=dict(type='str'),
        health_check_unhealthy_duration_before_replacement=dict(type='int'),
        iam_role_arn=dict(type='str'),
        iam_role_name=dict(type='str'),
        image_id=dict(type='str', required=True),
        key_pair=dict(type='str'),
        kubernetes=dict(type='dict'),
        lifetime_period=dict(type='int'),
        load_balancers=dict(type='list'),
        max_size=dict(type='int', required=True),
        mesosphere=dict(type='dict'),
        min_size=dict(type='int', required=True),
        monitoring=dict(type='str'),
        multai_load_balancers=dict(type='list'),
        multai_token=dict(type='str'),
        name=dict(type='str', required=True),
        network_interfaces=dict(type='list'),
        on_demand_count=dict(type='int'),
        on_demand_instance_type=dict(type='str'),
        opsworks=dict(type='dict'),
        persistence=dict(type='dict'),
        product=dict(type='str', required=True),
        rancher=dict(type='dict'),
        right_scale=dict(type='dict'),
        risk=dict(type='int'),
        roll_config=dict(type='dict'),
        scheduled_tasks=dict(type='list'),
        security_group_ids=dict(type='list', required=True),
        shutdown_script=dict(type='str'),
        signals=dict(type='list'),
        spin_up_time=dict(type='int'),
        spot_instance_types=dict(type='list', required=True),
        state=dict(default='present', choices=['present', 'absent']),
        tags=dict(type='list'),
        target=dict(type='int', required=True),
        target_group_arns=dict(type='list'),
        tenancy=dict(type='str'),
        terminate_at_end_of_billing_hour=dict(type='bool'),
        token=dict(type='str'),
        unit=dict(type='str'),
        user_data=dict(type='str'),
        utilize_reserved_instances=dict(type='bool'),
        uniqueness_by=dict(default='name', choices=['name', 'id']),
        up_scaling_policies=dict(type='list'),
        target_tracking_policies=dict(type='list'),
        wait_for_instances=dict(type='bool', default=False),
        wait_timeout=dict(type='int'))

    module = AnsibleModule(argument_spec=fields)

    if not HAS_SPOTINST_SDK:
        module.fail_json(
            msg=
            "the Spotinst SDK library is required. (pip install spotinst_sdk)")

    # Retrieve creds file variables
    creds_file_loaded_vars = dict()

    credentials_path = module.params.get('credentials_path')

    try:
        with open(credentials_path, "r") as creds:
            for line in creds:
                eq_index = line.find('=')
                var_name = line[:eq_index].strip()
                string_value = line[eq_index + 1:].strip()
                creds_file_loaded_vars[var_name] = string_value
    except IOError:
        pass
    # End of creds file retrieval

    token = module.params.get('token')
    if not token:
        token = os.environ.get('SPOTINST_TOKEN')
    if not token:
        token = creds_file_loaded_vars.get("token")

    account = module.params.get('account_id')
    if not account:
        account = os.environ.get('SPOTINST_ACCOUNT_ID') or os.environ.get(
            'ACCOUNT')
    if not account:
        account = creds_file_loaded_vars.get("account")

    client = spotinst.SpotinstClient(auth_token=token, print_output=False)

    if account is not None:
        client = spotinst.SpotinstClient(auth_token=token,
                                         print_output=False,
                                         account_id=account)

    group_id, message, has_changed = handle_elastigroup(client=client,
                                                        module=module)

    instances = retrieve_group_instances(client=client,
                                         module=module,
                                         group_id=group_id)

    module.exit_json(changed=has_changed,
                     group_id=group_id,
                     message=message,
                     instances=instances)
示例#5
0
def main():
    '''
    Apply functions based on the given arguments.
    '''
    spotinst_parser = argparse.ArgumentParser(
        description='''
        ** Managing Spotinst Elastigroup actions **
        ''',
        epilog='Author: Aris Boutselis  <*****@*****.**>')
    spotinst_parser.add_argument('--type','-t', action='store', dest='type', required=True,
                       help='Type of the Organization, two possible \
                       values are magento, launches. This argument \
                       is required. e.g spotinst -t magento .')
    spotinst_parser.add_argument('--list','-l', action='store', dest='id',
                       help='Show information about a single or all Elastigroups \
                       of the organization e.g spotinst -t magento --list all.')
    spotinst_parser.add_argument('--scaleup', action='store',dest='uparg',nargs=2,       
                       help='Scale up a number of instances for a given Elastigroup. \
                       Note: we heavily use autoscaling groups, scaling is done based on asg policy. \
                       e.g --scaleup <group_id> <number> .')
    spotinst_parser.add_argument('--scaledown', action='store',dest='downarg',nargs=2,
                       help='Scale down a number of instances for a given \
                       Elastigroup. Note: we heavily use autoscaling groups,\
                       scaling is done based on asg policy. e.g --scaledown <group_id> <number> .')
    spotinst_parser.add_argument('--capacity',action='store',dest='caparg',nargs=4,
                       help= 'Update capacity values for a given Elastigroup. \
                       e.g --capacity <group_id> <min> <max> <target> .')
    spotinst_parser.add_argument('--deploy','-d',action='store',dest='deparg',nargs=3,
                       help= 'Roll new instances in a single Elastigroup. \
                       e.g --deploy <group_id> <batch_percentage> <grace_period>.')
    spotinst_parser.add_argument('--pipelines', action='store',dest='bbpipelines',nargs=2,
                       help= 'Used only inside Bitbucket pipelines. This argument bypasses netrc auth mechanism \
                       e.g --pipelines <spotinst_account> <spotinst_account_token>.')
    spotinst_results = spotinst_parser.parse_args()
    # get the type to extract the appropriate account id and token
    type_values = ['magento','launches']
    #Be sure that token type is specified, --type <launches|magento>
    if spotinst_results.type in type_values and len(sys.argv) > 4:
        # if this script is used in Bitbucket pipelines, will try to
        # authenticate via Bitbucket ENV variables for the account and token values 
        if spotinst_results.bbpipelines:
            account = spotinst_results.bbpipelines[0]
            token = spotinst_results.bbpipelines[1]
            spotinst_client = spotinst_sdk.SpotinstClient(auth_token=token, account_id=account)
        else:
            token_type = spotinst_results.type+'-token'
            spotinst_client =  connection(token_type)

        # --scaleup
        if spotinst_results.uparg:
            if "sig-" in spotinst_results.uparg[0] and len(spotinst_results.uparg[1]) <= 2:
                scaleup(spotinst_client,spotinst_results.uparg[0],spotinst_results.uparg[1])
            else:
                print ("\n[ERROR] Wrong arguments for scale up function.Exiting...\n" ,spotinst_parser.print_help())
                sys.exit(1)
        # --scaledown
        if spotinst_results.downarg:
            if "sig-" in spotinst_results.downarg[0] and len(spotinst_results.downarg[1]) <= 2:
                scaledown(spotinst_client,spotinst_results.downarg[0],spotinst_results.downarg[1])
            else:
                 print ("\n[ERROR] Wrong arguments for scale down function.Exiting...\n",spotinst_parser.print_help()) 
                 sys.exit(1)
        # --capacity X X X X
        if spotinst_results.caparg:
            oldtarget = showid(spotinst_results.caparg[0], spotinst_client)[1]
            oldmin = showid(spotinst_results.caparg[0], spotinst_client)[2]
            oldmax = showid(spotinst_results.caparg[0], spotinst_client)[3]
            print ("Existing Capacity is min: %s, max: %s, target: %s \n"%(oldmin,oldmax,oldtarget))
            cmin = spotinst_results.caparg[1]
            cmax = spotinst_results.caparg[2]
            target = spotinst_results.caparg[3]
            if len(spotinst_results.caparg[1]) <= 2 and \
            len(spotinst_results.caparg[2]) <= 2 and \
            len(spotinst_results.caparg[3]) <= 2:
                print ("\nRequested capacity is min:%s, max:%s, target:%s \n" %(cmin,cmax,target))
                answer = yes_no('Execute the request?\n')
                if answer:
                    update_capac(spotinst_results.caparg[0], cmin, cmax, target, spotinst_client)
                else:
                    print ("\nAborting..")
                    sys.exit(1)
            else:
                print ("\n[ERROR]: Accepted values should be maximum 2 digit length.\n")
 
        # --list all|<group_id>         
        if spotinst_results.id:
            if spotinst_results.id == 'all':
                showid(spotinst_results.id, spotinst_client)
            elif "sig-" in spotinst_results.id :
                capacity,cap_target,cap_min,cap_max,group_name,env,ami = showid(spotinst_results.id, spotinst_client)
                print ("Group name:%s \nEnvironment:%s \nAmi:%s \nCapacity is min:%s, max:%s and target:%s" %(group_name,env,ami,cap_min,cap_max,cap_target))
            else:
                print ("\n[ERROR]: Accepted values should start with sig-xxxxxxxx \n",spotinst_parser.print_help())
                sys.exit(1)

        # --deploy <group_id> <batch_perc> <grace_period>
        if spotinst_results.deparg:
            if "sig-" in spotinst_results.deparg[0] and \
            len(spotinst_results.deparg[1]) <= 3 and \
            len(spotinst_results.deparg[2])  <= 3:
                    print ("\nRequested batch percentage is %s and grace period is %s \n" %(spotinst_results.deparg[1],spotinst_results.deparg[2]))
                    if spotinst_results.bbpipelines:
                        deploy(spotinst_results.deparg[0],spotinst_results.deparg[1],spotinst_results.deparg[2],spotinst_client)
                    else:
                        answer = yes_no('Execute the request?\n')
                        if answer:
                            deploy(spotinst_results.deparg[0],spotinst_results.deparg[1],spotinst_results.deparg[2],spotinst_client)
                        else:
                            print ("\n[ERROR]: Accepted values should start with sig-xxxxxxxx \n" ,spotinst_parser.print_help())
                            sys.exit(1)

    else:
        print ("\n[Error]: Nothing to do. Exiting..\n")
        sys.exit(1)
示例#6
0
                    help='Name of the deployment to grab suggestions for.')
parser.add_argument(
    '-r',
    '--ratio',
    default=2,
    help='The number between resource requests divided by the suggestions.')
parser.add_argument('-t', '--auth_token', help='Spotinst API Token.')
parser.add_argument('-a', '--account_id', help='ID of the Spotinst account.')
parser.add_argument('-o', '--ocean_id', help='ID of the Ocean cluster.')
parser.add_argument('-n',
                    '--namespace',
                    help='Namespace of the deployment in the cluster.')
args = parser.parse_args()

try:
    client = spotinst_sdk.SpotinstClient(auth_token=args.auth_token,
                                         account_id=args.account_id)
except Exception as e:
    print('Failed client init.\n{}'.format(e))
    sys.exit(1)
try:
    sizing_suggestions = client.get_all_ocean_sizing(args.ocean_id,
                                                     args.namespace)
except Exception as e:
    print('Failed getting suggestions.\n{}'.format(e))
    sys.exit(1)


# credit: https://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
def sizeof_fmt(num, suffix='B'):
    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
        if abs(num) < 1024.0: