def create(glance_client, **kwargs): if use_external_resource(ctx, glance_client, IMAGE_OPENSTACK_TYPE): return img_dict = {'name': get_resource_id(ctx, IMAGE_OPENSTACK_TYPE)} _validate_image_dictionary() img_properties = ctx.node.properties['image'] img_dict.update({ key: value for key, value in img_properties.iteritems() if key != 'data' }) img = glance_client.images.create(**img_dict) img_path = img_properties.get('data', '') img_url = ctx.node.properties.get('image_url') try: _validate_image() if img_path: with open(img_path, 'rb') as image_file: glance_client.images.upload(image_id=img.id, image_data=image_file) elif img_url: img = glance_client.images.add_location(img.id, img_url, {}) except: _remove_protected(glance_client) glance_client.images.delete(image_id=img.id) raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = img.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ IMAGE_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = img.name
def create(cinder_client, status_attempts, status_timeout, args, **kwargs): if use_external_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, 'name'): return name = get_resource_id(ctx, VOLUME_OPENSTACK_TYPE) volume_dict = {'name': name} volume_dict.update(ctx.node.properties['volume'], **args) handle_image_from_relationship(volume_dict, 'imageRef', ctx) volume_dict['name'] = transform_resource_name( ctx, volume_dict['name']) v = cinder_client.volumes.create(**volume_dict) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ VOLUME_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \ volume_dict['name'] wait_until_status(cinder_client=cinder_client, volume_id=v.id, status=VOLUME_STATUS_AVAILABLE, num_tries=status_attempts, timeout=status_timeout, ) ctx.instance.runtime_properties[OPENSTACK_AZ_PROPERTY] = \ v.availability_zone
def create(cinder_client, status_attempts, status_timeout, args, **kwargs): if use_external_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, 'name'): return name = get_resource_id(ctx, VOLUME_OPENSTACK_TYPE) volume_dict = {'name': name} volume_dict.update(ctx.node.properties['volume'], **args) handle_image_from_relationship(volume_dict, 'imageRef', ctx) volume_dict['name'] = transform_resource_name(ctx, volume_dict['name']) v = cinder_client.volumes.create(**volume_dict) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ VOLUME_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \ volume_dict['name'] wait_until_status( cinder_client=cinder_client, volume_id=v.id, status=VOLUME_STATUS_AVAILABLE, num_tries=status_attempts, timeout=status_timeout, ) ctx.instance.runtime_properties[OPENSTACK_AZ_PROPERTY] = \ v.availability_zone
def create(neutron_client, **kwargs): """ Create security group with rules. Parameters transformations: rules.N.remote_group_name -> rules.N.remote_group_id rules.N.remote_group_node -> rules.N.remote_group_id (Node name in YAML) """ security_group = { 'description': None, 'name': get_resource_id(ctx, SECURITY_GROUP_OPENSTACK_TYPE), } security_group.update(ctx.node.properties['security_group']) rules_to_apply = ctx.node.properties['rules'] from neutron_plugin.security_group_rule import _process_rule security_group_rules = [] for rule in rules_to_apply: security_group_rules.append(_process_rule(rule, neutron_client)) disable_default_egress_rules = ctx.node.properties.get( 'disable_default_egress_rules') external_sg = use_external_resource(ctx, neutron_client, SECURITY_GROUP_OPENSTACK_TYPE) if external_sg: try: _ensure_existing_sg_is_identical( external_sg, security_group, security_group_rules, not disable_default_egress_rules) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise transform_resource_name(ctx, security_group) sg = neutron_client.create_security_group( {'security_group': security_group})['security_group'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = sg['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SECURITY_GROUP_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = sg['name'] try: if disable_default_egress_rules: for er in _egress_rules(_rules_for_sg_id(neutron_client, sg['id'])): neutron_client.delete_security_group_rule(er['id']) for sgr in security_group_rules: sgr['security_group_id'] = sg['id'] neutron_client.create_security_group_rule( {'security_group_rule': sgr}) except neutron_exceptions.NeutronClientException: delete_resource_and_runtime_properties(ctx, neutron_client, RUNTIME_PROPERTIES_KEYS) raise
def create(glance_client, **kwargs): if use_external_resource(ctx, glance_client, IMAGE_OPENSTACK_TYPE): return img_dict = { 'name': get_resource_id(ctx, IMAGE_OPENSTACK_TYPE) } _validate_image_dictionary() img_properties = ctx.node.properties['image'] img_dict.update({key: value for key, value in img_properties.iteritems() if key != 'data'}) img = glance_client.images.create(**img_dict) img_path = img_properties.get('data', '') img_url = ctx.node.properties.get('image_url') try: _validate_image() if img_path: with open(img_path, 'rb') as image_file: glance_client.images.upload( image_id=img.id, image_data=image_file) elif img_url: img = glance_client.images.add_location(img.id, img_url, {}) except Exception: _remove_protected(glance_client) glance_client.images.delete(image_id=img.id) raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = img.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ IMAGE_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = img.name
def build_sg_data(): security_group = { 'description': None, 'name': get_resource_id(ctx, SECURITY_GROUP_OPENSTACK_TYPE), } security_group.update(ctx.node.properties['security_group']) return security_group
def create(neutron_client, args, **kwargs): ext_port = use_external_resource(ctx, neutron_client, PORT_OPENSTACK_TYPE) if ext_port: try: net_id = \ get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE, True) if net_id: port_id = ctx.instance.runtime_properties[ OPENSTACK_ID_PROPERTY] if neutron_client.show_port( port_id)['port']['network_id'] != net_id: raise NonRecoverableError( 'Expected external resources port {0} and network {1} ' 'to be connected'.format(port_id, net_id)) ctx.instance.runtime_properties[FIXED_IP_ADDRESS_PROPERTY] = \ _get_fixed_ip(ext_port) ctx.instance.runtime_properties[MAC_ADDRESS_PROPERTY] = \ ext_port['mac_address'] return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise net_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port = { 'name': get_resource_id(ctx, PORT_OPENSTACK_TYPE), 'network_id': net_id, 'security_groups': [], } _handle_fixed_ips(port) port.update(ctx.node.properties['port'], **args) transform_resource_name(ctx, port) p = neutron_client.create_port({'port': port})['port'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = p['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] =\ PORT_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = p['name'] ctx.instance.runtime_properties[FIXED_IP_ADDRESS_PROPERTY] = \ _get_fixed_ip(p) ctx.instance.runtime_properties[MAC_ADDRESS_PROPERTY] = p['mac_address']
def create(keystone_client, **kwargs): if use_external_resource(ctx, keystone_client, PROJECT_OPENSTACK_TYPE): return project_dict = { 'name': get_resource_id(ctx, PROJECT_OPENSTACK_TYPE), 'domain': 'default' } project_dict.update(ctx.node.properties['project']) project = keystone_client.projects.create(**project_dict) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = project.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ PROJECT_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = project.name
def create(neutron_client, args, **kwargs): if use_external_resource(ctx, neutron_client, NETWORK_OPENSTACK_TYPE): return network = { 'admin_state_up': True, 'name': get_resource_id(ctx, NETWORK_OPENSTACK_TYPE), } network.update(ctx.node.properties['network'], **args) transform_resource_name(ctx, network) net = neutron_client.create_network({'network': network})['network'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = net['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] =\ NETWORK_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = net['name']
def create(neutron_client, args, **kwargs): if use_external_resource(ctx, neutron_client, SUBNET_OPENSTACK_TYPE): try: net_id = \ get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE, True) if net_id: subnet_id = \ ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] if neutron_client.show_subnet( subnet_id)['subnet']['network_id'] != net_id: raise NonRecoverableError( 'Expected external resources subnet {0} and network' ' {1} to be connected'.format(subnet_id, net_id)) subnet_id = \ ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] subnet = {} subnet.update(ctx.node.properties['subnet'], **args) for host_route in subnet['host_routes']: if not 'nexthop' in host_route.keys(): host_route['nexthop'] = get_relationships_host_ip() neutron_client.update_subnet( subnet_id, {'subnet': subnet}) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise net_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) subnet = { 'name': get_resource_id(ctx, SUBNET_OPENSTACK_TYPE), 'network_id': net_id, } subnet.update(ctx.node.properties['subnet'], **args) transform_resource_name(ctx, subnet) s = neutron_client.create_subnet({'subnet': subnet})['subnet'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SUBNET_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = subnet['name']
def create(nova_client, args, **kwargs): private_key_path = _get_private_key_path() pk_exists = _check_private_key_exists(private_key_path) if use_external_resource(ctx, nova_client, KEYPAIR_OPENSTACK_TYPE): if not pk_exists: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise NonRecoverableError( 'Failed to use external keypair (node {0}): the public key {1}' ' is available on Openstack, but the private key could not be ' 'found at {2}'.format(ctx.node.id, ctx.node.properties['resource_id'], private_key_path)) return if pk_exists: raise NonRecoverableError( "Can't create keypair - private key path already exists: {0}" .format(private_key_path)) keypair = { 'name': get_resource_id(ctx, KEYPAIR_OPENSTACK_TYPE), } keypair.update(ctx.node.properties['keypair'], **args) transform_resource_name(ctx, keypair) keypair = nova_client.keypairs.create(keypair['name'], keypair.get('public_key')) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = keypair.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ KEYPAIR_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = keypair.name try: # write private key file _mkdir_p(os.path.dirname(private_key_path)) with open(private_key_path, 'w') as f: f.write(keypair.private_key) os.chmod(private_key_path, 0600) except Exception: _delete_private_key_file() delete_resource_and_runtime_properties(ctx, nova_client, RUNTIME_PROPERTIES_KEYS) raise
def create(nova_client, args, **kwargs): private_key_path = _get_private_key_path() pk_exists = _check_private_key_exists(private_key_path) if use_external_resource(ctx, nova_client, KEYPAIR_OPENSTACK_TYPE): if not pk_exists: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise NonRecoverableError( 'Failed to use external keypair (node {0}): the public key {1}' ' is available on Openstack, but the private key could not be ' 'found at {2}'.format(ctx.node.id, ctx.node.properties['resource_id'], private_key_path)) return if pk_exists: raise NonRecoverableError( "Can't create keypair - private key path already exists: {0}". format(private_key_path)) keypair = { 'name': get_resource_id(ctx, KEYPAIR_OPENSTACK_TYPE), } keypair.update(ctx.node.properties['keypair'], **args) transform_resource_name(ctx, keypair) keypair = nova_client.keypairs.create(keypair['name'], keypair.get('public_key')) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = keypair.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ KEYPAIR_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = keypair.name try: # write private key file _mkdir_p(os.path.dirname(private_key_path)) with open(private_key_path, 'w') as f: f.write(keypair.private_key) os.chmod(private_key_path, 0600) except Exception: _delete_private_key_file() delete_resource_and_runtime_properties(ctx, nova_client, RUNTIME_PROPERTIES_KEYS) raise
def create(nova_client, args, **kwargs): if use_external_resource(ctx, nova_client, SERVER_GROUP_OPENSTACK_TYPE): return server_grp = { 'name': get_resource_id(ctx, SERVER_GROUP_OPENSTACK_TYPE), 'policies': [ctx.node.properties['policy']] } server_grp.update(copy.deepcopy(ctx.node.properties['server_group'])) server_grp.update(copy.deepcopy(args)) transform_resource_name(ctx, server_grp) server_grp = nova_client.server_groups.create(**server_grp) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = server_grp.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SERVER_GROUP_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server_grp.name
def create(neutron_client, args, **kwargs): if use_external_resource(ctx, neutron_client, SUBNET_OPENSTACK_TYPE): try: net_id = \ get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE, True) if net_id: subnet_id = \ ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] if neutron_client.show_subnet( subnet_id)['subnet']['network_id'] != net_id: raise NonRecoverableError( 'Expected external resources subnet {0} and network' ' {1} to be connected'.format(subnet_id, net_id)) subnet_id = \ ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] subnet = {} subnet.update(ctx.node.properties['subnet'], **args) for host_route in subnet['host_routes']: if not 'nexthop' in host_route.keys(): host_route['nexthop'] = get_relationships_host_ip() neutron_client.update_subnet(subnet_id, {'subnet': subnet}) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise net_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) subnet = { 'name': get_resource_id(ctx, SUBNET_OPENSTACK_TYPE), 'network_id': net_id, } subnet.update(ctx.node.properties['subnet'], **args) transform_resource_name(ctx, subnet) s = neutron_client.create_subnet({'subnet': subnet})['subnet'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SUBNET_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = subnet['name']
def create(neutron_client, args, **kwargs): if use_external_resource(ctx, neutron_client, ROUTER_OPENSTACK_TYPE): try: ext_net_id_by_rel = _get_connected_ext_net_id(neutron_client) if ext_net_id_by_rel: router_id = \ ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] router = neutron_client.show_router(router_id)['router'] if not (router['external_gateway_info'] and 'network_id' in router['external_gateway_info'] and router['external_gateway_info']['network_id'] == ext_net_id_by_rel): raise NonRecoverableError( 'Expected external resources router {0} and ' 'external network {1} to be connected'.format( router_id, ext_net_id_by_rel)) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise router = { 'name': get_resource_id(ctx, ROUTER_OPENSTACK_TYPE), } router.update(ctx.node.properties['router'], **args) ctx.logger.info('router: {0}'.format(router)) transform_resource_name(ctx, router) _handle_external_network_config(router, neutron_client) r = neutron_client.create_router({'router': router})['router'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = r['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] =\ ROUTER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = r['name']
def create(cinder_client, args, **kwargs): if use_external_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, 'display_name'): return name = get_resource_id(ctx, VOLUME_OPENSTACK_TYPE) volume_dict = {'display_name': name} volume_dict.update(ctx.node.properties['volume'], **args) volume_dict['display_name'] = transform_resource_name( ctx, volume_dict['display_name']) v = cinder_client.volumes.create(**volume_dict) ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ VOLUME_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \ volume_dict['display_name'] wait_until_status(cinder_client=cinder_client, volume_id=v.id, status=VOLUME_STATUS_AVAILABLE)
def create(nova_client, neutron_client, args, **kwargs): """ Creates a server. Exposes the parameters mentioned in http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1 .servers.html#novaclient.v1_1.servers.ServerManager.create """ external_server = use_external_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) if external_server: _set_network_and_ip_runtime_properties(external_server) if ctx._local: return else: network_ids = \ get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, PORT_OPENSTACK_TYPE) try: _validate_external_server_nics( neutron_client, network_ids, port_ids ) _validate_external_server_keypair(nova_client) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise provider_context = provider(ctx) def rename(name): return transform_resource_name(ctx, name) server = { 'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE), } server.update(copy.deepcopy(ctx.node.properties['server'])) server.update(copy.deepcopy(args)) _handle_boot_volume(server, ctx) handle_image_from_relationship(server, 'image', ctx) if 'meta' not in server: server['meta'] = dict() transform_resource_name(ctx, server) ctx.logger.debug( "server.create() server before transformations: {0}".format(server)) if ('block_device_mapping' in server or 'block_device_mapping_v2' in server) \ and 'image' not in server: # python-novaclient requires an image field even if BDM is used. server['image'] = ctx.node.properties.get('image') else: _handle_image_or_flavor(server, nova_client, 'image') _handle_image_or_flavor(server, nova_client, 'flavor') if provider_context.agents_security_group: security_groups = server.get('security_groups', []) asg = provider_context.agents_security_group['name'] if asg not in security_groups: security_groups.append(asg) server['security_groups'] = security_groups elif not server.get('security_groups', []): # Make sure that if the server is connected to a security group # from CREATE time so that there the user can control # that there is never a time that a running server is not protected. security_group_names = \ get_openstack_names_of_connected_nodes_by_openstack_type( ctx, SECURITY_GROUP_OPENSTACK_TYPE) server['security_groups'] = security_group_names # server keypair handling keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, KEYPAIR_OPENSTACK_TYPE, True) if 'key_name' in server: if keypair_id: raise NonRecoverableError("server can't both have the " '"key_name" nested property and be ' 'connected to a keypair via a ' 'relationship at the same time') server['key_name'] = rename(server['key_name']) elif keypair_id: server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id) elif provider_context.agents_keypair: server['key_name'] = provider_context.agents_keypair['name'] else: server['key_name'] = None ctx.logger.info( 'server must have a keypair, yet no keypair was connected to the ' 'server node, the "key_name" nested property ' "wasn't used, and there is no agent keypair in the provider " "context. Agent installation can have issues.") _fail_on_missing_required_parameters( server, ('name', 'flavor'), 'server') _prepare_server_nics(neutron_client, ctx, server) # server group handling server_group_id = \ get_openstack_id_of_single_connected_node_by_openstack_type( ctx, SERVER_GROUP_OPENSTACK_TYPE, True) if server_group_id: scheduler_hints = server.get('scheduler_hints', {}) scheduler_hints['group'] = server_group_id server['scheduler_hints'] = scheduler_hints ctx.logger.debug( "server.create() server after transformations: {0}".format(server)) userdata.handle_userdata(server) ctx.logger.info("Creating VM with parameters: {0}".format(str(server))) # Store the server dictionary contents in runtime properties assign_payload_as_runtime_properties(ctx, SERVER_OPENSTACK_TYPE, server) ctx.logger.debug( "Asking Nova to create server. All possible parameters are: {0})" .format(','.join(server.keys()))) try: s = nova_client.servers.create(**server) except nova_exceptions.BadRequest as e: if 'Block Device Mapping is Invalid' in str(e): return ctx.operation.retry( message='Block Device Mapping is not created yet', retry_after=30) raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SERVER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
def create(nova_client, neutron_client, args, **kwargs): """ Creates a server. Exposes the parameters mentioned in http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1 .servers.html#novaclient.v1_1.servers.ServerManager.create """ external_server = use_external_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) if external_server: network_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, PORT_OPENSTACK_TYPE) try: _validate_external_server_nics( neutron_client, network_ids, port_ids ) _validate_external_server_keypair(nova_client) _set_network_and_ip_runtime_properties(external_server) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise provider_context = provider(ctx) def rename(name): return transform_resource_name(ctx, name) server = { 'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE), } server.update(copy.deepcopy(ctx.node.properties['server'])) server.update(copy.deepcopy(args)) if 'meta' not in server: server['meta'] = dict() transform_resource_name(ctx, server) ctx.logger.debug( "server.create() server before transformations: {0}".format(server)) _handle_image_or_flavor(server, nova_client, 'image') _handle_image_or_flavor(server, nova_client, 'flavor') if provider_context.agents_security_group: security_groups = server.get('security_groups', []) asg = provider_context.agents_security_group['name'] if asg not in security_groups: security_groups.append(asg) server['security_groups'] = security_groups # server keypair handling keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, KEYPAIR_OPENSTACK_TYPE, True) if 'key_name' in server: if keypair_id: raise NonRecoverableError("server can't both have the " '"key_name" nested property and be ' 'connected to a keypair via a ' 'relationship at the same time') server['key_name'] = rename(server['key_name']) elif keypair_id: server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id) elif provider_context.agents_keypair: server['key_name'] = provider_context.agents_keypair['name'] else: raise NonRecoverableError( 'server must have a keypair, yet no keypair was connected to the ' 'server node, the "key_name" nested property ' "wasn't used, and there is no agent keypair in the provider " "context") _fail_on_missing_required_parameters( server, ('name', 'flavor', 'image', 'key_name'), 'server') _prepare_server_nics(neutron_client, ctx, server) ctx.logger.debug( "server.create() server after transformations: {0}".format(server)) userdata.handle_userdata(server) ctx.logger.info("Creating VM with parameters: {0}".format(str(server))) ctx.logger.debug( "Asking Nova to create server. All possible parameters are: {0})" .format(','.join(server.keys()))) try: s = nova_client.servers.create(**server) except nova_exceptions.BadRequest as e: if str(e).startswith(MUST_SPECIFY_NETWORK_EXCEPTION_TEXT): raise NonRecoverableError( "Can not provision server: management_network_name or id" " is not specified but there are several networks that the " "server can be connected to.") raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SERVER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
def create(nova_client, neutron_client, args, **kwargs): """ Creates a server. Exposes the parameters mentioned in http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1 .servers.html#novaclient.v1_1.servers.ServerManager.create """ network_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, PORT_OPENSTACK_TYPE) external_server = use_external_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) if external_server: try: _validate_external_server_nics( neutron_client, network_ids, port_ids ) _validate_external_server_keypair(nova_client) _set_network_and_ip_runtime_properties(external_server) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise provider_context = provider(ctx) def rename(name): return transform_resource_name(ctx, name) server = { 'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE), } server.update(copy.deepcopy(ctx.node.properties['server'])) server.update(copy.deepcopy(args)) transform_resource_name(ctx, server) ctx.logger.debug( "server.create() server before transformations: {0}".format(server)) management_network_id = None management_network_name = None if ('management_network_name' in ctx.node.properties) and \ ctx.node.properties['management_network_name']: management_network_name = \ ctx.node.properties['management_network_name'] management_network_name = rename(management_network_name) management_network_id = neutron_client.cosmo_get_named( 'network', management_network_name)['id'] else: int_network = provider_context.int_network if int_network: management_network_id = int_network['id'] management_network_name = int_network['name'] # Already transform. if management_network_id is not None: server['nics'] = \ server.get('nics', []) + [{'net-id': management_network_id}] _handle_image_or_flavor(server, nova_client, 'image') _handle_image_or_flavor(server, nova_client, 'flavor') if provider_context.agents_security_group: security_groups = server.get('security_groups', []) asg = provider_context.agents_security_group['name'] if asg not in security_groups: security_groups.append(asg) server['security_groups'] = security_groups # server keypair handling keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, KEYPAIR_OPENSTACK_TYPE, True) if 'key_name' in server: if keypair_id: raise NonRecoverableError("server can't both have the " '"key_name" nested property and be ' 'connected to a keypair via a ' 'relationship at the same time') server['key_name'] = rename(server['key_name']) elif keypair_id: server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id) elif provider_context.agents_keypair: server['key_name'] = provider_context.agents_keypair['name'] else: raise NonRecoverableError( 'server must have a keypair, yet no keypair was connected to the ' 'server node, the "key_name" nested property ' "wasn't used, and there is no agent keypair in the provider " "context") _fail_on_missing_required_parameters( server, ('name', 'flavor', 'image', 'key_name'), 'server') if management_network_id is None and (network_ids or port_ids): # Known limitation raise NonRecoverableError( "Nova server with NICs requires " "'management_network_name' in properties or id " "from provider context, which was not supplied") # Multi-NIC by networks - start nics = [{'net-id': net_id} for net_id in network_ids] if nics: if management_network_id in network_ids: # de-duplicating the management network id in case it appears in # network_ids. There has to be a management network if a # network is connected to the server. # note: if the management network appears more than once in # network_ids it won't get de-duplicated and the server creation # will fail. nics.remove({'net-id': management_network_id}) server['nics'] = server.get('nics', []) + nics # Multi-NIC by networks - end # Multi-NIC by ports - start nics = [{'port-id': port_id} for port_id in port_ids] if nics: port_network_ids = get_port_network_ids_(neutron_client, port_ids) if management_network_id in port_network_ids: # de-duplicating the management network id in case it appears in # port_ids. There has to be a management network if a # network is connected to the server. # note: if the management network appears more than once in # network_ids it won't get de-duplicated and the server creation # will fail. server['nics'].remove({'net-id': management_network_id}) server['nics'] = server.get('nics', []) + nics # Multi-NIC by ports - end ctx.logger.debug( "server.create() server after transformations: {0}".format(server)) if 'meta' not in server: server['meta'] = dict() if management_network_id is not None: server['meta']['cloudify_management_network_id'] = \ management_network_id if management_network_name is not None: server['meta']['cloudify_management_network_name'] = \ management_network_name userdata.handle_userdata(server) ctx.logger.info("Creating VM with parameters: {0}".format(str(server))) ctx.logger.debug( "Asking Nova to create server. All possible parameters are: {0})" .format(','.join(server.keys()))) try: s = nova_client.servers.create(**server) except nova_exceptions.BadRequest as e: if str(e).startswith(MUST_SPECIFY_NETWORK_EXCEPTION_TEXT): raise NonRecoverableError( "Can not provision server: management_network_name or id" " is not specified but there are several networks that the " "server can be connected to.") raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SERVER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
def create(neutron_client, **kwargs): """Create a router. Optional relationship is to gateway network. Also supports `router.external_gateway_info.network_name`, which is translated to `router.external_gateway_info.network_id`. """ if use_external_resource(ctx, neutron_client, ROUTER_OPENSTACK_TYPE): return network_id_set = False provider_context = provider(ctx) ctx.logger.debug('router.create(): kwargs={0}'.format(kwargs)) router = { 'name': get_resource_id(ctx, ROUTER_OPENSTACK_TYPE), } router.update(ctx.node.properties['router']) transform_resource_name(ctx, router) # Probably will not be used. External network # is usually provisioned externally. # TODO: remove this or modify - it's unreasonable to look for # OPENSTACK_ID_PROPERTY in capabilities as it can be of any connected # node. If the usage of capabilities here remains, need to add # validation in the 'use_external_resource' (before returning) that the # network used is the one connected to the router. if OPENSTACK_ID_PROPERTY in ctx.capabilities: if 'external_gateway_info' not in router: router['external_gateway_info'] = { 'enable_snat': True } router['external_gateway_info'][ 'network_id'] = ctx.capabilities[OPENSTACK_ID_PROPERTY] network_id_set = True # Sugar: external_gateway_info.network_name -> # external_gateway_info.network_id if 'external_gateway_info' in router: egi = router['external_gateway_info'] if 'network_name' in egi: egi['network_id'] = neutron_client.cosmo_get_named( 'network', egi['network_name'])['id'] del egi['network_name'] network_id_set = True if not network_id_set: router['external_gateway_info'] = router.get('external_gateway_info', {}) ext_network = provider_context.ext_network if ext_network: router['external_gateway_info']['network_id'] = ext_network['id'] network_id_set = True if not network_id_set: raise NonRecoverableError('Missing network name or network') r = neutron_client.create_router({'router': router})['router'] ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = r['id'] ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] =\ ROUTER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = r['name']
def create(nova_client, neutron_client, **kwargs): """ Creates a server. Exposes the parameters mentioned in http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1 .servers.html#novaclient.v1_1.servers.ServerManager.create Userdata: In all cases, note that userdata should not be base64 encoded, novaclient expects it raw. The 'userdata' argument under nova.instance can be one of the following: - A string - A hash with 'type: http' and 'url: ...' """ network_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, PORT_OPENSTACK_TYPE) external_server = use_external_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) if external_server: try: _validate_external_server_nics(network_ids, port_ids) _validate_external_server_keypair(nova_client) _set_network_and_ip_runtime_properties(external_server) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise provider_context = provider(ctx) def rename(name): return transform_resource_name(ctx, name) # For possible changes by _maybe_transform_userdata() server = { 'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE), } server.update(copy.deepcopy(ctx.node.properties['server'])) transform_resource_name(ctx, server) ctx.logger.debug( "server.create() server before transformations: {0}".format(server)) _maybe_transform_userdata(server) management_network_id = None management_network_name = None if ('management_network_name' in ctx.node.properties) and \ ctx.node.properties['management_network_name']: management_network_name = \ ctx.node.properties['management_network_name'] management_network_name = rename(management_network_name) nc = _neutron_client() management_network_id = nc.cosmo_get_named( 'network', management_network_name)['id'] else: int_network = provider_context.int_network if int_network: management_network_id = int_network['id'] management_network_name = int_network['name'] # Already transform. if management_network_id is not None: server['nics'] = \ server.get('nics', []) + [{'net-id': management_network_id}] _handle_image_or_flavor(server, nova_client, 'image') _handle_image_or_flavor(server, nova_client, 'flavor') if provider_context.agents_security_group: security_groups = server.get('security_groups', []) asg = provider_context.agents_security_group['name'] if asg not in security_groups: security_groups.append(asg) server['security_groups'] = security_groups # server keypair handling keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, KEYPAIR_OPENSTACK_TYPE, True) if 'key_name' in server: if keypair_id: raise NonRecoverableError("server can't both have the " '"key_name" nested property and be ' 'connected to a keypair via a ' 'relationship at the same time') server['key_name'] = rename(server['key_name']) elif keypair_id: server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id) elif provider_context.agents_keypair: server['key_name'] = provider_context.agents_keypair['name'] else: raise NonRecoverableError( 'server must have a keypair, yet no keypair was connected to the ' 'server node, the "key_name" nested property' "wasn't used, and there is no agent keypair in the provider " "context") _fail_on_missing_required_parameters( server, ('name', 'flavor', 'image', 'key_name'), 'server') if management_network_id is None and (network_ids or port_ids): # Known limitation raise NonRecoverableError( "Nova server with NICs requires " "'management_network_name' in properties or id " "from provider context, which was not supplied") # Multi-NIC by networks - start nics = [{'net-id': net_id} for net_id in network_ids] if nics: if management_network_id in network_ids: # de-duplicating the management network id in case it appears in # network_ids. There has to be a management network if a # network is connected to the server. # note: if the management network appears more than once in # network_ids it won't get de-duplicated and the server creation # will fail. nics.remove({'net-id': management_network_id}) server['nics'] = server.get('nics', []) + nics # Multi-NIC by networks - end # Multi-NIC by ports - start nics = [{'port-id': port_id} for port_id in port_ids] if nics: port_network_ids = get_port_network_ids_(neutron_client, port_ids) if management_network_id in port_network_ids: # de-duplicating the management network id in case it appears in # port_ids. There has to be a management network if a # network is connected to the server. # note: if the management network appears more than once in # network_ids it won't get de-duplicated and the server creation # will fail. server['nics'].remove({'net-id': management_network_id}) server['nics'] = server.get('nics', []) + nics # Multi-NIC by ports - end ctx.logger.debug( "server.create() server after transformations: {0}".format(server)) # First parameter is 'self', skipping params_names = inspect.getargspec(nova_client.servers.create).args[1:] params_default_values = inspect.getargspec( nova_client.servers.create).defaults params = dict(itertools.izip(params_names, params_default_values)) # Fail on unsupported parameters for k in server: if k not in params: raise NonRecoverableError( "Parameter with name '{0}' must not be passed to" " openstack provisioner (under host's " "properties.nova.instance)".format(k)) for k in params: if k in server: params[k] = server[k] if not params['meta']: params['meta'] = dict({}) if management_network_id is not None: params['meta']['cloudify_management_network_id'] = \ management_network_id if management_network_name is not None: params['meta']['cloudify_management_network_name'] = \ management_network_name ctx.logger.info("Creating VM with parameters: {0}".format(str(params))) ctx.logger.debug( "Asking Nova to create server. All possible parameters are: {0})" .format(','.join(params.keys()))) try: s = nova_client.servers.create(**params) except nova_exceptions.BadRequest as e: if str(e).startswith(MUST_SPECIFY_NETWORK_EXCEPTION_TEXT): raise NonRecoverableError( "Can not provision server: management_network_name or id" " is not specified but there are several networks that the " "server can be connected to.") raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SERVER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
def create(nova_client, neutron_client, args, **kwargs): """ Creates a server. Exposes the parameters mentioned in http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1 .servers.html#novaclient.v1_1.servers.ServerManager.create """ external_server = use_external_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) if external_server: _set_network_and_ip_runtime_properties(external_server) if ctx._local: return else: network_ids = \ get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type( ctx, PORT_OPENSTACK_TYPE) try: _validate_external_server_nics( neutron_client, network_ids, port_ids ) _validate_external_server_keypair(nova_client) return except Exception: delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS) raise provider_context = provider(ctx) def rename(name): return transform_resource_name(ctx, name) server = { 'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE), } server.update(copy.deepcopy(ctx.node.properties['server'])) server.update(copy.deepcopy(args)) _handle_boot_volume(server, ctx) handle_image_from_relationship(server, 'image', ctx) if 'meta' not in server: server['meta'] = dict() transform_resource_name(ctx, server) ctx.logger.debug( "server.create() server before transformations: {0}".format(server)) if ('block_device_mapping' in server or 'block_device_mapping_v2' in server) \ and 'image' not in server: # python-novaclient requires an image field even if BDM is used. server['image'] = ctx.node.properties.get('image') else: _handle_image_or_flavor(server, nova_client, 'image') _handle_image_or_flavor(server, nova_client, 'flavor') if provider_context.agents_security_group: security_groups = server.get('security_groups', []) asg = provider_context.agents_security_group['name'] if asg not in security_groups: security_groups.append(asg) server['security_groups'] = security_groups elif not server.get('security_groups', []): # Make sure that if the server is connected to a security group # from CREATE time so that there the user can control # that there is never a time that a running server is not protected. security_group_names = \ get_openstack_names_of_connected_nodes_by_openstack_type( ctx, SECURITY_GROUP_OPENSTACK_TYPE) server['security_groups'] = security_group_names # server keypair handling keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, KEYPAIR_OPENSTACK_TYPE, True) if 'key_name' in server: if keypair_id: raise NonRecoverableError("server can't both have the " '"key_name" nested property and be ' 'connected to a keypair via a ' 'relationship at the same time') server['key_name'] = rename(server['key_name']) elif keypair_id: server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id) elif provider_context.agents_keypair: server['key_name'] = provider_context.agents_keypair['name'] else: server['key_name'] = None ctx.logger.info( 'server must have a keypair, yet no keypair was connected to the ' 'server node, the "key_name" nested property ' "wasn't used, and there is no agent keypair in the provider " "context. Agent installation can have issues.") _fail_on_missing_required_parameters( server, ('name', 'flavor'), 'server') _prepare_server_nics(neutron_client, ctx, server) # server group handling server_group_id = \ get_openstack_id_of_single_connected_node_by_openstack_type( ctx, SERVER_GROUP_OPENSTACK_TYPE, True) if server_group_id: scheduler_hints = server.get('scheduler_hints', {}) scheduler_hints['group'] = server_group_id server['scheduler_hints'] = scheduler_hints ctx.logger.debug( "server.create() server after transformations: {0}".format(server)) userdata.handle_userdata(server) ctx.logger.info("Creating VM with parameters: {0}".format(str(server))) # Store the server dictionary contents in runtime properties assign_payload_as_runtime_properties(ctx, SERVER_OPENSTACK_TYPE, server) ctx.logger.debug( "Asking Nova to create server. All possible parameters are: [{0}]" .format(','.join(server.keys()))) try: s = nova_client.servers.create(**server) except nova_exceptions.BadRequest as e: if 'Block Device Mapping is Invalid' in str(e): return ctx.operation.retry( message='Block Device Mapping is not created yet', retry_after=30) raise ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ SERVER_OPENSTACK_TYPE ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']