def create(nova_client, **kwargs): security_group = build_sg_data() security_group['description'] = ctx.node.properties['description'] sgr_default_values = { 'ip_protocol': 'tcp', 'from_port': 1, 'to_port': 65535, 'cidr': '0.0.0.0/0', # 'group_id': None, # 'parent_group_id': None, } sg_rules = process_rules(nova_client, sgr_default_values, 'cidr', 'group_id', 'from_port', 'to_port') if use_external_sg(nova_client): return transform_resource_name(ctx, security_group) sg = nova_client.security_groups.create(security_group['name'], security_group['description']) set_sg_runtime_properties(sg, nova_client) try: for sgr in sg_rules: sgr['parent_group_id'] = sg.id nova_client.security_group_rules.create(**sgr) except Exception: delete_resource_and_runtime_properties(ctx, nova_client, RUNTIME_PROPERTIES_KEYS) raise
def create(neutron_client, args, **kwargs): security_group = build_sg_data(args) sg_rules = process_rules(neutron_client, DEFAULT_RULE_VALUES, 'remote_ip_prefix', 'remote_group_id', 'port_range_min', 'port_range_max') disable_default_egress_rules = ctx.node.properties.get( 'disable_default_egress_rules') if use_external_sg(neutron_client): return transform_resource_name(ctx, security_group) sg = neutron_client.create_security_group( {'security_group': security_group})['security_group'] set_sg_runtime_properties(sg, neutron_client) 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 sg_rules: sgr['security_group_id'] = sg['id'] neutron_client.create_security_group_rule( {'security_group_rule': sgr}) except Exception: delete_resource_and_runtime_properties(ctx, neutron_client, RUNTIME_PROPERTIES_KEYS) raise
def create(nova_client, **kwargs): security_group = build_sg_data() security_group['description'] = ctx.node.properties['description'] sgr_default_values = { 'ip_protocol': 'tcp', 'from_port': 1, 'to_port': 65535, 'cidr': '0.0.0.0/0', # 'group_id': None, # 'parent_group_id': None, } sg_rules = process_rules(nova_client, sgr_default_values, 'cidr', 'group_id', 'from_port', 'to_port') if use_external_sg(nova_client): return transform_resource_name(ctx, security_group) sg = nova_client.security_groups.create( security_group['name'], security_group['description']) set_sg_runtime_properties(sg, nova_client) try: for sgr in sg_rules: sgr['parent_group_id'] = sg.id nova_client.security_group_rules.create(**sgr) except Exception: delete_resource_and_runtime_properties(ctx, nova_client, RUNTIME_PROPERTIES_KEYS) raise
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( neutron_client, args, status_attempts=10, status_timeout=2, **kwargs ): security_group = build_sg_data(args) if not security_group['description']: security_group['description'] = ctx.node.properties['description'] sg_rules = process_rules(neutron_client, DEFAULT_RULE_VALUES, 'remote_ip_prefix', 'remote_group_id', 'port_range_min', 'port_range_max') disable_default_egress_rules = ctx.node.properties.get( 'disable_default_egress_rules') if use_external_sg(neutron_client): return transform_resource_name(ctx, security_group) sg = neutron_client.create_security_group( {'security_group': security_group})['security_group'] for attempt in range(max(status_attempts, 1)): sleep(status_timeout) try: neutron_client.show_security_group(sg['id']) except RequestException as e: ctx.logger.debug("Waiting for SG to be visible. Attempt {}".format( attempt)) else: break else: raise NonRecoverableError( "Timed out waiting for security_group to exist", e) set_sg_runtime_properties(sg, neutron_client) 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 sg_rules: sgr['security_group_id'] = sg['id'] neutron_client.create_security_group_rule( {'security_group_rule': sgr}) except Exception: try: delete_resource_and_runtime_properties( ctx, neutron_client, RUNTIME_PROPERTIES_KEYS) except Exception as e: raise NonRecoverableError( 'Exception while tearing down for retry', e) raise
def create(neutron_client, args, status_attempts=10, status_timeout=2, **kwargs): security_group = build_sg_data(args) if not security_group['description']: security_group['description'] = ctx.node.properties['description'] sg_rules = process_rules(neutron_client, DEFAULT_RULE_VALUES, 'remote_ip_prefix', 'remote_group_id', 'port_range_min', 'port_range_max') disable_default_egress_rules = ctx.node.properties.get( 'disable_default_egress_rules') if use_external_sg(neutron_client): return transform_resource_name(ctx, security_group) sg = neutron_client.create_security_group( {'security_group': security_group})['security_group'] for attempt in range(max(status_attempts, 1)): sleep(status_timeout) try: neutron_client.show_security_group(sg['id']) except RequestException as e: ctx.logger.debug( "Waiting for SG to be visible. Attempt {}".format(attempt)) else: break else: raise NonRecoverableError( "Timed out waiting for security_group to exist", e) set_sg_runtime_properties(sg, neutron_client) 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 sg_rules: sgr['security_group_id'] = sg['id'] neutron_client.create_security_group_rule( {'security_group_rule': sgr}) except Exception: try: delete_resource_and_runtime_properties(ctx, neutron_client, RUNTIME_PROPERTIES_KEYS) except Exception as e: raise NonRecoverableError('Exception while tearing down for retry', e) raise
def create(ctx, neutron_client, **kwargs): port = { 'name': ctx.node_id, 'network_id': _find_network_in_related_nodes(ctx, neutron_client), 'security_groups': [], } port.update(ctx.properties['port']) transform_resource_name(port, ctx) p = neutron_client.create_port({'port': port})['port'] ctx.runtime_properties['external_id'] = p['id']
def create(neutron_client, **kwargs): network = { 'admin_state_up': True, 'name': ctx.node_id, } network.update(ctx.properties['network']) transform_resource_name(ctx, network) net = neutron_client.create_network({'network': network})['network'] ctx.runtime_properties[OPENSTACK_ID_PROPERTY] = net['id'] ctx.runtime_properties[OPENSTACK_TYPE_PROPERTY] = NETWORK_OPENSTACK_TYPE
def create(ctx, 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`. """ network_id_set = False provider_context = provider(ctx) ctx.logger.debug('router.create(): kwargs={0}'.format(kwargs)) router = { 'name': ctx.node_id, } router.update(ctx.properties['router']) transform_resource_name(router, ctx) # Probably will not be used. External network # is usually provisioned externally. if 'external_id' 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['external_id'] 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.runtime_properties['external_id'] = r['id']
def create(ctx, neutron_client, **kwargs): network = { 'admin_state_up': True, 'name': ctx.node_id, } network.update(ctx.properties['network']) transform_resource_name(network, ctx) net = neutron_client.create_network({'network': network})['network'] ctx.runtime_properties['external_id'] = net['id'] ctx.runtime_properties['external_type'] = 'network'
def create(neutron_client, **kwargs): net_id = get_openstack_id_of_single_connected_node_by_openstack_type( ctx, NETWORK_OPENSTACK_TYPE) port = { 'name': ctx.node_id, 'network_id': net_id, 'security_groups': [], } port.update(ctx.properties['port']) transform_resource_name(ctx, port) p = neutron_client.create_port({'port': port})['port'] ctx.runtime_properties[OPENSTACK_ID_PROPERTY] = p['id']
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': ctx.node_id, } security_group.update(ctx.properties['security_group']) transform_resource_name(ctx, security_group) rules_to_apply = ctx.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.properties.get( 'disable_default_egress_rules') existing_sg = _find_existing_sg(neutron_client, security_group) if existing_sg: _ensure_existing_sg_is_identical( existing_sg, security_group, security_group_rules, not disable_default_egress_rules) return sg = neutron_client.create_security_group( {'security_group': security_group})['security_group'] _set_security_group_runtime_properties(sg['id']) 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_security_group_and_properties(neutron_client, sg['id']) raise
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(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, 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(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(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): 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 _get_management_network_id_and_name(neutron_client, ctx): """Examine the context to find the management network id and name.""" management_network_id = None management_network_name = \ ctx.node.properties.get('management_network_name') provider_context = provider(ctx) if management_network_name: management_network_name = transform_resource_name( ctx, management_network_name) management_network_id = neutron_client.cosmo_get_named( 'network', management_network_name) management_network_id = management_network_id['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. return management_network_id, management_network_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 start_new_server(ctx, nova_client): """ 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: ...' """ provider_context = provider(ctx) def rename(name): return transform_resource_name(name, ctx) # For possible changes by _maybe_transform_userdata() server = { 'name': ctx.node_id } server.update(copy.deepcopy(ctx.properties['server'])) transform_resource_name(server, ctx) ctx.logger.debug( "server.create() server before transformations: {0}".format(server)) if 'nics' in server: raise NonRecoverableError( "Parameter with name 'nics' must not be passed to" " openstack provisioner (under host's " "properties.nova.instance)") _maybe_transform_userdata(server) management_network_id = None management_network_name = None nc = None if ('management_network_name' in ctx.properties) and \ ctx.properties['management_network_name']: management_network_name = ctx.properties['management_network_name'] management_network_name = rename(management_network_name) nc = _neutron_client(ctx) 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: nc = _neutron_client(ctx) server['nics'] = [{'net-id': management_network_id}] # Sugar if 'image_name' in server: server['image'] = nova_client.images.find( name=server['image_name']).id del server['image_name'] if 'flavor_name' in server: server['flavor'] = nova_client.flavors.find( name=server['flavor_name']).id del server['flavor_name'] security_groups = map(rename, server.get('security_groups', [])) if provider_context.agents_security_group: asg = provider_context.agents_security_group['name'] if asg not in security_groups: security_groups.append(asg) server['security_groups'] = security_groups if 'key_name' in server: server['key_name'] = rename(server['key_name']) else: # 'key_name' not in server if provider_context.agents_keypair: server['key_name'] = provider_context.agents_keypair['name'] _fail_on_missing_required_parameters( server, ('name', 'flavor', 'image', 'key_name'), 'server') # Multi-NIC by networks - start network_nodes_runtime_properties = ctx.capabilities.get_all().values() if network_nodes_runtime_properties and \ management_network_id is None: # Known limitation raise NonRecoverableError( "Nova server with multi-NIC requires " "'management_network_name' in properties or id " "from provider context, which was not supplied") nics = [ {'net-id': n['external_id']} for n in network_nodes_runtime_properties if nc.cosmo_is_network(n['external_id']) ] if nics: server['nics'] = server.get('nics', []) + nics # Multi-NIC by networks - end # Multi-NIC by ports - start port_nodes_runtime_properties = ctx.capabilities.get_all().values() if port_nodes_runtime_properties and \ management_network_id is None: # Known limitation raise NonRecoverableError( "Nova server with multi-NIC requires " "'management_network_name' in properties or id " "from provider context, which was not supplied") nics = [ {'port-id': n['external_id']} for n in port_nodes_runtime_properties if nc.cosmo_is_port(n['external_id']) ] if nics: 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({}) params['meta'][NODE_ID_PROPERTY] = ctx.node_id 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 NonRecoverableError("Nova bad request error: " + str(e)) except nova_exceptions.ClientException as e: raise NonRecoverableError("Nova client error: " + str(e)) ctx.runtime_properties[OPENSTACK_SERVER_ID_PROPERTY] = s.id
def rename(name): return transform_resource_name(ctx, 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']
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(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(ctx, 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': ctx.node_id, } security_group.update(ctx.properties['security_group']) transform_resource_name(security_group, ctx) existing_sg = _find_existing_sg(ctx, neutron_client, security_group) if existing_sg: if existing_sg['description'] != security_group['description']: raise NonRecoverableError("Descriptions of existing security group" " and the security group to be created " "do not match while the names do match." " Security group name: {0}".format( security_group['name'])) rules_to_apply = ctx.properties['rules'] egress_rules_to_apply = _egress_rules(rules_to_apply) do_disable_egress = ctx.properties.get('disable_egress') if do_disable_egress: if egress_rules_to_apply and ctx.properties['disable_egress']: raise NonRecoverableError( "Security group {0} can not have both " "disable_egress and an egress rule".format( security_group['name'])) security_group_rules = [] for rule in rules_to_apply: ctx.logger.debug( "security_group.create() rule before transformations: {0}".format( rule)) sgr = { 'direction': 'ingress', 'ethertype': 'IPv4', 'port_range_max': rule.get('port', 65535), 'port_range_min': rule.get('port', 1), 'protocol': 'tcp', 'remote_group_id': None, 'remote_ip_prefix': '0.0.0.0/0', } sgr.update(rule) # Remove the sugaring "port" parameter if 'port' in sgr: del sgr['port'] if ('remote_group_node' in sgr) and sgr['remote_group_node']: _, remote_group_node = _capabilities_of_node_named( sgr['remote_group_node'], ctx) sgr['remote_group_id'] = remote_group_node['external_id'] del sgr['remote_group_node'] del sgr['remote_ip_prefix'] if ('remote_group_name' in sgr) and sgr['remote_group_name']: sgr['remote_group_id'] = neutron_client.cosmo_get_named( 'security_group', sgr['remote_group_name'])['id'] del sgr['remote_group_name'] del sgr['remote_ip_prefix'] ctx.logger.debug( "security_group.create() rule after transformations: {0}".format( sgr)) security_group_rules.append(sgr) if existing_sg: r1 = existing_sg['security_group_rules'] r2 = security_group_rules if not (egress_rules_to_apply or do_disable_egress): # We do expect to see the default egress rules # if we don't have our own and we do not disable # the default egress rules. r2 = r2 + DEFAULT_EGRESS_RULES if _sg_rules_are_equal(r1, r2): ctx.logger.info("Using existing security group named '{0}' with " "id {1}".format( security_group['name'], existing_sg['id'])) ctx.runtime_properties['external_id'] = existing_sg['id'] return else: raise RulesMismatchError("Rules of existing security group" " and the security group to be created " "or used do not match while the names " "do match. Security group name: '{0}'. " "Existing rules: {1}. " "Requested/expected rules: {2} " "".format( security_group['name'], r1, r2)) sg = neutron_client.create_security_group( {'security_group': security_group})['security_group'] if egress_rules_to_apply or do_disable_egress: 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}) ctx.runtime_properties['external_id'] = sg['id']