def connect(host, users=None): log.debug("Connecting to '{}'".format(host)) if "@" in host: parts = host.split("@") assert len(parts) == 2 host = parts[1] if not users: users = [parts[0]] if not users: users = [ "Administrator", "ubuntu", "ec2-user", "centos", "vagrant", "root" ] # Similar to ssh, try own username first, # some systems will lock us out if we have too many failed attempts. if whoami() not in users: users = [whoami()] + users for user in users: try: log.debug("Attempting ssh: {}@{}".format(user, host)) c = fabric.Connection(host=host, user=user) c.ssh_user = user c.ssh_host = host c.run("whoami", hide=True) return c except AuthenticationException: continue sys.exit("Could not ssh into '{}'".format(host))
def connect(host, users=None): log.debug(f"Connecting to '{host}'") log.debug(f"users= '{users}'") if "@" in host: parts = host.split("@") assert len(parts) == 2 host = parts[1] if not users: users = [parts[0]] if not users: users = [ "Administrator", "admin", "ubuntu", "ec2-user", "centos", "vagrant", "root", ] # Similar to ssh, try own username first, # some systems will lock us out if we have too many failed attempts. if whoami() not in users: users = [whoami()] + users for user in users: try: log.debug(f"Attempting ssh: {user}@{host}") connect_kwargs = {} key = os.getenv("CF_REMOTE_SSH_KEY") if key: connect_kwargs["key_filename"] = os.path.expanduser(key) c = fabric.Connection(host=host, user=user, connect_kwargs=connect_kwargs) c.ssh_user = user c.ssh_host = host c.run("whoami", hide=True) return c except AuthenticationException: continue sys.exit(f"Could not ssh into '{host}'")
def spawn_vm_in_aws(platform, aws_creds, key_pair, security_groups, region, name=None, size=None, role=None): driver = get_cloud_driver(Providers.AWS, aws_creds, region) existing_vms = driver.list_nodes() if name is None: name = _get_unused_name([vm.name for vm in existing_vms], platform, _NAME_RANDOM_PART_LENGTH) else: if any(vm.state in (0, 'running') and vm.name == name for vm in existing_vms): raise ValueError("VM with the name '%s' already exists" % name) aws_platform = aws_platforms[platform] size = size or aws_platform.get("xlsize") or aws_platform["size"] user = aws_platform.get("user") ami = aws_platform["ami"] log.info("Spawning new '%s' VM in AWS (AMI: %s, size=%s)" % (platform, ami, size)) node = driver.create_node( name=name, image=NodeImage(id=ami, name=None, driver=driver), size=NodeSize(id=size, name=None, ram=None, disk=None, bandwidth=None, price=None, driver=driver), ex_keyname=key_pair, ex_security_groups=security_groups, ex_metadata={ "created-by": "cf-remote", "owner": whoami(), }, ) return VM(name, driver, node, role, platform, size, key_pair, security_groups, user, Providers.AWS)
def spawn_vm_in_gcp(platform, gcp_creds, region, name=None, size="n1-standard-1", network=None, public_ip=True, role=None): driver = get_cloud_driver(Providers.GCP, gcp_creds, region) existing_vms = driver.list_nodes() if name is None: name = _get_unused_name([vm.name for vm in existing_vms], platform, _NAME_RANDOM_PART_LENGTH) else: if any(vm.state in (0, 'running') and vm.name == name for vm in existing_vms): raise ValueError("VM with the name '%s' already exists" % name) # TODO: Should we have a list of GCP platforms/images? No weird IDs needed, # they are straightforward like "centos-7" or "debian-9". kwargs = dict() if network is not None: net, subnet = network.split("/") kwargs["ex_network"] = net kwargs["ex_subnetwork"] = subnet if not public_ip: kwargs["external_ip"] = None kwargs["ex_metadata"] = { "created-by": "cf-remote", "owner": whoami(), } if not size: size = "n1-standard-1" node = driver.create_node(name, size, platform, **kwargs) return VM(name, driver, node, role, platform, size, None, None, None, Providers.GCP)
def spawn(platform, count, role, group_name, provider=Providers.AWS, region=None, size=None, network=None, public_ip=True, extend_group=False): if os.path.exists(CLOUD_CONFIG_FPATH): creds_data = read_json(CLOUD_CONFIG_FPATH) else: print("Cloud credentials not found at %s" % CLOUD_CONFIG_FPATH) return 1 if os.path.exists(CLOUD_STATE_FPATH): vms_info = read_json(CLOUD_STATE_FPATH) else: vms_info = dict() group_key = "@%s" % group_name group_exists = group_key in vms_info if not extend_group and group_exists: print("Group '%s' already exists!" % group_key) return 1 creds = None sec_groups = None key_pair = None if provider == Providers.AWS: try: creds = AWSCredentials(creds_data["aws"]["key"], creds_data["aws"]["secret"]) sec_groups = creds_data["aws"]["security_groups"] key_pair = creds_data["aws"]["key_pair"] except KeyError: print( "Incomplete AWS credential info") # TODO: report missing keys return 1 region = region or creds_data["aws"].get("region", "eu-west-1") elif provider == Providers.GCP: try: creds = GCPCredentials(creds_data["gcp"]["project_id"], creds_data["gcp"]["service_account_id"], creds_data["gcp"]["key_path"]) except KeyError: print( "Incomplete GCP credential info") # TODO: report missing keys return 1 region = region or creds_data["gcp"].get("region", "europe-west1-b") # TODO: Do we have to complicate this instead of just assuming existing VMs # were created by this code and thus follow the naming pattern from this # code? if group_exists: range_start = len( [key for key in vms_info[group_key].keys() if key != "meta"]) else: range_start = 0 requests = [] for i in range(range_start, range_start + count): vm_name = whoami()[0:2] + group_name + "-" + platform + role + str(i) requests.append( VMRequest(platform=platform, name=vm_name, size=size, public_ip=public_ip)) print("Spawning VMs...", end="") sys.stdout.flush() vms = spawn_vms(requests, creds, region, key_pair, security_groups=sec_groups, provider=provider, network=network, role=role, spawned_cb=print_progress_dot) print("DONE") if public_ip and (not all(vm.public_ips for vm in vms)): print("Waiting for VMs to get IP addresses...", end="") sys.stdout.flush() # STDOUT is line-buffered while not all(vm.public_ips for vm in vms): time.sleep(1) print_progress_dot() print("DONE") if group_exists: vms_info[group_key].update(dump_vms_info(vms)) else: vms_info[group_key] = dump_vms_info(vms) write_json(CLOUD_STATE_FPATH, vms_info) print("Details about the spawned VMs can be found in %s" % CLOUD_STATE_FPATH) return 0
def spawn(platform, count, role, group_name, provider=Providers.AWS, region=None): if os.path.exists(CLOUD_CONFIG_FPATH): creds_data = read_json(CLOUD_CONFIG_FPATH) else: print("Cloud credentials not found at %s" % CLOUD_CONFIG_FPATH) return 1 if os.path.exists(CLOUD_STATE_FPATH): vms_info = read_json(CLOUD_STATE_FPATH) else: vms_info = dict() group_key = "@%s" % group_name if group_key in vms_info: print("Group '%s' already exists!" % group_key) return 1 try: creds = AWSCredentials(creds_data["aws"]["key"], creds_data["aws"]["secret"]) sec_groups = creds_data["aws"]["security_groups"] key_pair = creds_data["aws"]["key_pair"] except KeyError: print("Incomplete AWS credential info") # TODO: report missing keys return 1 region = region or creds_data["aws"].get("region", "eu-west-1") requests = [] for i in range(count): vm_name = whoami()[0:2] + group_name + "-" + platform + role + str(i) requests.append(VMRequest(platform=platform, name=vm_name, size=None)) print("Spawning VMs...", end="") sys.stdout.flush() vms = spawn_vms(requests, creds, region, key_pair, security_groups=sec_groups, provider=provider, role=role) print("DONE") if not all(vm.public_ips for vm in vms): print("Waiting for VMs to get IP addresses...", end="") sys.stdout.flush() # STDOUT is line-buffered while not all(vm.public_ips for vm in vms): time.sleep(1) print(".", end="") sys.stdout.flush() # STDOUT is line-buffered print("DONE") vms_info[group_key] = dump_vms_info(vms) write_json(CLOUD_STATE_FPATH, vms_info) print("Details about the spawned VMs can be found in %s" % CLOUD_STATE_FPATH) return 0