def on_post(self, req, resp, tenant_id): body = json.loads(req.stream.read().decode()) try: name = body['keypair']['name'] key = body['keypair'].get('public_key', generate_random_key()) except (KeyError, TypeError): return bad_request(resp, 'Not all fields exist to create keypair.') validate_result = validate_keypair_name(resp, name) if not validate_result: return client = req.env['sl_client'] mgr = SshKeyManager(client) # Make sure the key with that label doesn't already exist existing_keys = mgr.list_keys(label=name) if existing_keys: return duplicate(resp, 'Duplicate key by that name') try: keypair = mgr.add_key(key, name) resp.body = {'keypair': format_keypair(keypair)} except SoftLayerAPIError as e: if 'Unable to generate a fingerprint' in e.faultString: return bad_request(resp, e.faultString) if 'SSH key already exists' in e.faultString: return duplicate(resp, e.faultString) raise
def on_get(self, req, resp, tenant_id): client = req.env['sl_client'] mgr = SshKeyManager(client) keypairs = mgr.list_keys() resp.body = { 'keypairs': [{ 'keypair': format_keypair(keypair)} for keypair in keypairs]}
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get("<identifier>"), "SshKey") if args["--really"] or no_going_back(key_id): mgr.delete_key(key_id) else: CLIAbort("Aborted")
def __init__(self, config, client=None): self.config = config if client is None: client = Client(auth=self.config['auth'], endpoint_url=self.config['endpoint_url']) self.client = client self.ssh = SshKeyManager(client) self.instances = CCIManager(client)
def global_search(search): client = get_client() match_string = '<span class="text-primary">%s</span>' % search term = re.compile(search, re.IGNORECASE) results = [] if 'vm' in app.config['installed_blueprints']: cci = CCIManager(client) # if hostname_regex.match(term): for vm in cci.list_instances(): if term.match(vm['hostname']) or \ term.match(vm.get('primaryIpAddress', '')): text = '%s (%s)' % (vm['fullyQualifiedDomainName'], vm.get('primaryIpAddress', 'No Public IP')) text = term.sub(match_string, text) results.append({ 'label': '<strong>VM:</strong> ' + text, 'value': url_for('vm_module.view', vm_id=vm['id']) }) if 'servers' in app.config['installed_blueprints']: hw = HardwareManager(client) for svr in hw.list_hardware(): if term.match(svr['hostname']) or \ term.match(svr.get('primaryIpAddress', '')): text = '%s (%s)' % (svr['fullyQualifiedDomainName'], svr.get('primaryIpAddress', 'No Public IP')) text = term.sub(match_string, text) results.append({ 'label': '<strong>Server:</strong> ' + text, 'value': url_for('server_module.view', server_id=svr['id']) }) if 'sshkeys' in app.config['installed_blueprints']: ssh = SshKeyManager(client) for key in ssh.list_keys(): if term.match(key['label']) or term.match(key['fingerprint']): text = '%s (%s)' % (key['label'], key['fingerprint']) text = term.sub(match_string, text) results.append({ 'label': '<strong>SSH Key:</strong> ' + text, 'value': url_for('ssh_module.view', key_id=key['id']) }) return results
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get('<identifier>'), 'SshKey') if args['--really'] or no_going_back(key_id): mgr.delete_key(key_id) else: CLIAbort('Aborted')
def execute(self, args): mgr = SshKeyManager(self.client) keys = mgr.list_keys() t = Table(["id", "label", "fingerprint", "notes"]) for key in keys: t.add_row([key["id"], key["label"], key["fingerprint"], key.get("notes", "-")]) return t
def on_delete(self, req, resp, tenant_id, keypair_name): # keypair_name client = req.env['sl_client'] mgr = SshKeyManager(client) keys = mgr.list_keys(label=keypair_name) if len(keys) == 0: return not_found(resp, 'KeyPair not Found') mgr.delete_key(keys[0]['id']) resp.status = 202
def on_get(self, req, resp, tenant_id, keypair_name): client = req.env['sl_client'] mgr = SshKeyManager(client) keys = mgr.list_keys(label=keypair_name) if len(keys) == 0: return not_found(resp, 'KeyPair not found') keypair = mgr.get_key(keys[0]['id']) resp.body = {'keypair': format_keypair(keypair)}
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get('<identifier>'), 'SshKey') if not mgr.edit_key(key_id, label=args['--label'], notes=args['--notes']): raise CLIAbort('Failed to edit SSH key')
def execute(self, args): mgr = SshKeyManager(self.client) keys = mgr.list_keys() t = Table(['id', 'label', 'fingerprint', 'notes']) for key in keys: t.add_row([key['id'], key['label'], key['fingerprint'], key.get('notes', '-')]) return t
def execute(self, args): if args.get('--key'): key = args['--key'] else: key_file = open(expanduser(args['--file']), 'rU') key = key_file.read().strip() key_file.close() mgr = SshKeyManager(self.client) result = mgr.add_key(key, args['<label>'], args.get('--notes')) return "SSH key added: %s" % result.get('fingerprint')
def execute(self, args): if args.get('--key'): key = args['--key'] else: f = open(expanduser(args['--file']), 'rU') key = f.read().strip() f.close() mgr = SshKeyManager(self.client) result = mgr.add_key(key, args['<label>'], args.get('--notes')) if type(result) is dict and result.get('fingerprint'): return "SSH key added."
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get("<identifier>"), "SshKey") data = {} if args.get("--label"): data["label"] = args["--label"] if args.get("--notes"): data["notes"] = args["--notes"] if not mgr.edit_key(key_id, **data): raise CLIAbort("Failed to edit SSH key")
def execute(self, args): if args.get("--key"): key = args["--key"] else: f = open(expanduser(args["--file"]), "rU") key = f.read().strip() f.close() mgr = SshKeyManager(self.client) result = mgr.add_key(key, args["<label>"], args.get("--notes")) if type(result) is dict and result.get("fingerprint"): return "SSH key added."
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get('<identifier>'), 'SshKey') data = {} if args.get('--label'): data['label'] = args['--label'] if args.get('--notes'): data['notes'] = args['--notes'] if not mgr.edit_key(key_id, **data): raise CLIAbort('Failed to edit SSH key')
def global_search(search): client = get_client() match_string = '<span class="text-primary">%s</span>' % search term = re.compile(search, re.IGNORECASE) results = [] if 'vm' in app.config['installed_blueprints']: cci = CCIManager(client) # if hostname_regex.match(term): for vm in cci.list_instances(): if term.match(vm['hostname']) or \ term.match(vm.get('primaryIpAddress', '')): text = '%s (%s)' % (vm['fullyQualifiedDomainName'], vm.get('primaryIpAddress', 'No Public IP')) text = term.sub(match_string, text) results.append({'label': '<strong>VM:</strong> ' + text, 'value': url_for('vm_module.view', vm_id=vm['id'])}) if 'servers' in app.config['installed_blueprints']: hw = HardwareManager(client) for svr in hw.list_hardware(): if term.match(svr['hostname']) or \ term.match(svr.get('primaryIpAddress', '')): text = '%s (%s)' % (svr['fullyQualifiedDomainName'], svr.get('primaryIpAddress', 'No Public IP')) text = term.sub(match_string, text) results.append({'label': '<strong>Server:</strong> ' + text, 'value': url_for('server_module.view', server_id=svr['id'])}) if 'sshkeys' in app.config['installed_blueprints']: ssh = SshKeyManager(client) for key in ssh.list_keys(): if term.match(key['label']) or term.match(key['fingerprint']): text = '%s (%s)' % (key['label'], key['fingerprint']) text = term.sub(match_string, text) results.append({'label': '<strong>SSH Key:</strong> ' + text, 'value': url_for('ssh_module.view', key_id=key['id'])}) return results
class SoftLayer(object): def __init__(self, config, client=None): self.config = config if client is None: client = Client(auth=self.config['auth'], endpoint_url=self.config['endpoint_url']) self.client = client self.ssh = SshKeyManager(client) self.instances = CCIManager(client) @classmethod def get_config(cls): provider_conf = client_conf.get_client_settings() if 'SL_SSH_KEY' in os.environ: provider_conf['ssh_key'] = os.environ['SL_SSH_KEY'] if not ('auth' in provider_conf and 'endpoint_url' in provider_conf): raise ConfigError("Missing digital ocean api credentials") return provider_conf def get_ssh_keys(self): keys = map(SSHKey, self.ssh.list_keys()) if 'ssh_key' in self.config: keys = [k for k in keys if k.name == self.config['ssh_key']] log.debug("Using SoftLayer ssh keys: %s" % ", ".join(k.name for k in keys)) return keys def get_instances(self): return map(Instance, self.instances.list_instances()) def get_instance(self, instance_id): return Instance(self.instances.get_instance(instance_id)) def launch_instance(self, params): return Instance(self.instances.create_instance(**params)) def terminate_instance(self, instance_id): self.instances.cancel_instance(instance_id) def wait_on(self, instance): # Wait up to 5 minutes, in 30 sec increments result = self._wait_on_instance(instance, 30, 10) if not result: raise ProviderError("Could not provision instance before timeout") return result def _wait_on_instance(self, instance, limit, delay=10): # Redo cci.wait to give user feedback in verbose mode. for count, new_instance in enumerate(itertools.repeat(instance.id)): instance = self.get_instance(new_instance) if not instance.get('activeTransaction', {}).get('id') and \ instance.get('provisionDate'): return True if count >= limit: return False if count and count % 3 == 0: log.debug("Waiting for instance:%s ip:%s waited:%ds" % (instance.name, instance.ip_address, count * delay)) time.sleep(delay)
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get("<identifier>"), "SshKey") key = mgr.get_key(key_id) if args.get("--file"): f = open(expanduser(args["--file"]), "w") f.write(key["key"]) f.close() t = KeyValueTable(["Name", "Value"]) t.add_row(["id", key["id"]]) t.add_row(["label", key["label"]]) t.add_row(["notes", key.get("notes", "-")]) return t
def execute(self, args): mgr = SshKeyManager(self.client) key_id = resolve_id(mgr.resolve_ids, args.get('<identifier>'), 'SshKey') key = mgr.get_key(key_id) if args.get('--file'): with open(expanduser(args['--file']), 'w') as pub_file: pub_file.write(key['key']) table = KeyValueTable(['Name', 'Value']) table.add_row(['id', key['id']]) table.add_row(['label', key['label']]) table.add_row(['notes', key.get('notes', '-')]) return table
def __init__(self, config, client=None): self.config = config if client is None: client = Client( auth=self.config['auth'], endpoint_url=self.config['endpoint_url']) self.client = client self.ssh = SshKeyManager(client) self.instances = CCIManager(client)
def execute(client, args): mgr = SshKeyManager(client) key_id = resolve_id(mgr.resolve_ids, args.get('<identifier>'), 'SshKey') key = mgr.get_key(key_id) if args.get('--file'): f = open(expanduser(args['--file']), 'w') f.write(key['key']) f.close() t = KeyValueTable(['Name', 'Value']) t.add_row(['id', key['id']]) t.add_row(['label', key['label']]) t.add_row(['notes', key.get('notes', '-')]) return t
def listSSHKeys(label=None): sshManager = SshKeyManager(client) sshKeys = sshManager.list_keys(label=label) return sshKeys
def get_sshkey_manager(): return SshKeyManager(get_client())
def on_post(self, req, resp, tenant_id): client = req.env['sl_client'] body = json.loads(req.stream.read().decode()) flavor_id = int(body['server'].get('flavorRef')) if flavor_id not in FLAVORS: return bad_request(resp, 'Flavor could not be found') flavor = FLAVORS[flavor_id] ssh_keys = [] key_name = body['server'].get('key_name') if key_name: sshkey_mgr = SshKeyManager(client) keys = sshkey_mgr.list_keys(label=key_name) if len(keys) == 0: return bad_request(resp, 'KeyPair could not be found') ssh_keys.append(keys[0]['id']) private_network_only = False networks = lookup(body, 'server', 'networks') if networks: # Make sure they're valid networks if not all([network['uuid'] in ['public', 'private'] in network for network in networks]): return bad_request(resp, message='Invalid network') # Find out if it's private only if not any([network['uuid'] == 'public' in network for network in networks]): private_network_only = True user_data = {} if lookup(body, 'server', 'metadata'): user_data['metadata'] = lookup(body, 'server', 'metadata') if lookup(body, 'server', 'user_data'): user_data['user_data'] = lookup(body, 'server', 'user_data') if lookup(body, 'server', 'personality'): user_data['personality'] = lookup(body, 'server', 'personality') datacenter = None if lookup(body, 'server', 'availability_zone'): datacenter = lookup(body, 'server', 'availability_zone') cci = CCIManager(client) payload = { 'hostname': body['server']['name'], 'domain': CONF['default_domain'] or 'jumpgate.com', 'cpus': flavor['cpus'], 'memory': flavor['ram'], 'local_disk': False if flavor['disk-type'] == 'SAN' else True, 'hourly': True, # TODO - How do we set this accurately? 'datacenter': datacenter, 'image_id': body['server']['imageRef'], 'ssh_keys': ssh_keys, 'private': private_network_only, 'userdata': json.dumps(user_data), } try: new_instance = cci.create_instance(**payload) except ValueError as e: return bad_request(resp, message=str(e)) resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = {'server': { 'id': new_instance['id'], 'links': [{ 'href': self.app.get_endpoint_url( 'compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self'}], 'adminPass': '', }}
def on_post(self, req, resp, tenant_id): client = req.env['sl_client'] body = json.loads(req.stream.read().decode()) flavor_id = int(body['server'].get('flavorRef')) if flavor_id not in FLAVORS: return bad_request(resp, 'Flavor could not be found') flavor = FLAVORS[flavor_id] ssh_keys = [] key_name = body['server'].get('key_name') if key_name: sshkey_mgr = SshKeyManager(client) keys = sshkey_mgr.list_keys(label=key_name) if len(keys) == 0: return bad_request(resp, 'KeyPair could not be found') ssh_keys.append(keys[0]['id']) private_network_only = False networks = lookup(body, 'server', 'networks') if networks: # Make sure they're valid networks if not all([ network['uuid'] in ['public', 'private'] in network for network in networks ]): return bad_request(resp, message='Invalid network') # Find out if it's private only if not any([ network['uuid'] == 'public' in network for network in networks ]): private_network_only = True user_data = {} if lookup(body, 'server', 'metadata'): user_data['metadata'] = lookup(body, 'server', 'metadata') if lookup(body, 'server', 'user_data'): user_data['user_data'] = lookup(body, 'server', 'user_data') if lookup(body, 'server', 'personality'): user_data['personality'] = lookup(body, 'server', 'personality') datacenter = None if lookup(body, 'server', 'availability_zone'): datacenter = lookup(body, 'server', 'availability_zone') cci = CCIManager(client) payload = { 'hostname': body['server']['name'], 'domain': 'jumpgate.com', # TODO - Don't hardcode this 'cpus': flavor['cpus'], 'memory': flavor['ram'], 'hourly': True, # TODO - How do we set this accurately? 'datacenter': datacenter, 'image_id': body['server']['imageRef'], 'ssh_keys': ssh_keys, 'private': private_network_only, 'userdata': json.dumps(user_data), } try: new_instance = cci.create_instance(**payload) except ValueError as e: return bad_request(resp, message=str(e)) resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = { 'server': { 'id': new_instance['id'], 'links': [{ 'href': self.app.get_endpoint_url('compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self' }], 'adminPass': '', } }
def setUp(self): self.client = FixtureClient() self.sshkey = SshKeyManager(self.client)
class SshKeyTests(unittest.TestCase): def setUp(self): self.client = FixtureClient() self.sshkey = SshKeyManager(self.client) def test_add_key(self): key = 'pretend this is a public SSH key' label = 'Test label' notes = 'My notes' data = { 'key': key, 'label': label, 'notes': notes, } mcall = call(data) service = self.client['Security_Ssh_Key'] self.sshkey.add_key(key=key, label=label, notes=notes) service.createObject.assert_has_calls(mcall) def test_delete_key(self): id = 1234 mcall = call(id=id) service = self.client['Security_Ssh_Key'] self.sshkey.delete_key(id) service.deleteObject.assert_has_calls(mcall) def test_edit_key(self): id = 1234 label = 'Test label' notes = 'My notes' data = { 'label': label, 'notes': notes, } mcall = call(data, id=id) service = self.client['Security_Ssh_Key'] self.sshkey.edit_key(id, label=label, notes=notes) service.editObject.assert_has_calls(mcall) def test_get_key(self): id = 1234 mcall = call(id=id) service = self.client['Security_Ssh_Key'] self.sshkey.get_key(id) service.getObject.assert_has_calls(mcall) def test_list_keys(self): service = self.client['Account'] self.sshkey.list_keys(label='some label') service.getSshKeys.assert_called_with( filter={'sshKeys': {'label': {'operation': '_= some label'}}}) def test_resolve_ids_label(self): _id = self.sshkey._get_ids_from_label('Test 1') self.assertEqual(_id, ['100']) _id = self.sshkey._get_ids_from_label('nope') self.assertEqual(_id, [])
class SoftLayer(object): def __init__(self, config, client=None): self.config = config if client is None: client = Client( auth=self.config['auth'], endpoint_url=self.config['endpoint_url']) self.client = client self.ssh = SshKeyManager(client) self.instances = CCIManager(client) @classmethod def get_config(cls): provider_conf = client_conf.get_client_settings() if 'SL_SSH_KEY' in os.environ: provider_conf['ssh_key'] = os.environ['SL_SSH_KEY'] if not ('auth' in provider_conf and 'endpoint_url' in provider_conf): raise ConfigError("Missing digital ocean api credentials") return provider_conf def get_ssh_keys(self): keys = map(SSHKey, self.ssh.list_keys()) if 'ssh_key' in self.config: keys = [k for k in keys if k.name == self.config['ssh_key']] log.debug( "Using SoftLayer ssh keys: %s" % ", ".join(k.name for k in keys)) return keys def get_instances(self): return map(Instance, self.instances.list_instances()) def get_instance(self, instance_id): return Instance(self.instances.get_instance(instance_id)) def launch_instance(self, params): return Instance(self.instances.create_instance(**params)) def terminate_instance(self, instance_id): self.instances.cancel_instance(instance_id) def wait_on(self, instance): # Wait up to 5 minutes, in 30 sec increments result = self._wait_on_instance(instance, 30, 10) if not result: raise ProviderError("Could not provision instance before timeout") return result def _wait_on_instance(self, instance, limit, delay=10): # Redo cci.wait to give user feedback in verbose mode. for count, new_instance in enumerate(itertools.repeat(instance.id)): instance = self.get_instance(new_instance) if not instance.get('activeTransaction', {}).get('id') and \ instance.get('provisionDate'): return True if count >= limit: return False if count and count % 3 == 0: log.debug("Waiting for instance:%s ip:%s waited:%ds" % ( instance.name, instance.ip_address, count*delay)) time.sleep(delay)
def setUp(self): self.client = MagicMock() self.sshkey = SshKeyManager(self.client)
def on_post(self, req, resp, tenant_id): client = req.env["sl_client"] body = json.loads(req.stream.read().decode()) flavor_id = int(body["server"].get("flavorRef")) if flavor_id not in FLAVORS: return bad_request(resp, "Flavor could not be found") flavor = FLAVORS[flavor_id] ssh_keys = [] key_name = body["server"].get("key_name") if key_name: sshkey_mgr = SshKeyManager(client) keys = sshkey_mgr.list_keys(label=key_name) if len(keys) == 0: return bad_request(resp, "KeyPair could not be found") ssh_keys.append(keys[0]["id"]) private_network_only = False networks = lookup(body, "server", "networks") if networks: # Make sure they're valid networks if not all([network["uuid"] in ["public", "private"] in network for network in networks]): return bad_request(resp, message="Invalid network") # Find out if it's private only if not any([network["uuid"] == "public" in network for network in networks]): private_network_only = True user_data = {} if lookup(body, "server", "metadata"): user_data["metadata"] = lookup(body, "server", "metadata") if lookup(body, "server", "user_data"): user_data["user_data"] = lookup(body, "server", "user_data") if lookup(body, "server", "personality"): user_data["personality"] = lookup(body, "server", "personality") datacenter = None if lookup(body, "server", "availability_zone"): datacenter = lookup(body, "server", "availability_zone") cci = CCIManager(client) payload = { "hostname": body["server"]["name"], "domain": CONF["default_domain"] or "jumpgate.com", "cpus": flavor["cpus"], "memory": flavor["ram"], "local_disk": False if flavor["disk-type"] == "SAN" else True, "hourly": True, # TODO - How do we set this accurately? "datacenter": datacenter, "image_id": body["server"]["imageRef"], "ssh_keys": ssh_keys, "private": private_network_only, "userdata": json.dumps(user_data), } try: new_instance = cci.create_instance(**payload) except ValueError as e: return bad_request(resp, message=str(e)) resp.set_header("x-compute-request-id", "create") resp.status = 202 resp.body = { "server": { "id": new_instance["id"], "links": [ { "href": self.app.get_endpoint_url("compute", req, "v2_server", instance_id=new_instance["id"]), "rel": "self", } ], "adminPass": "", } }