def _test_quota_validation(self, amount, quota, failure_expected): ctx = MockCloudifyContext(node_id='node_id', properties={}) client = mock.MagicMock() def mock_cosmo_list(_): return [x for x in range(0, amount)] client.cosmo_list = mock_cosmo_list def mock_get_quota(_): return quota client.get_quota = mock_get_quota if failure_expected: self.assertRaisesRegexp( NonRecoverableError, 'cannot be created due to quota limitations', common.validate_resource, ctx=ctx, sugared_client=client, openstack_type='openstack_type') else: common.validate_resource(ctx=ctx, sugared_client=client, openstack_type='openstack_type')
def creation_validation(neutron_client, **kwargs): validate_resource(ctx, neutron_client, SECURITY_GROUP_OPENSTACK_TYPE) ctx.logger.debug('validating CIDR for rules with a remote_ip_prefix field') for rule in ctx.node.properties['rules']: if 'remote_ip_prefix' in rule: validate_ip_or_range_syntax(ctx, rule['remote_ip_prefix'])
def sg_creation_validation(client, cidr_field_name, **kwargs): validate_resource(ctx, client, SECURITY_GROUP_OPENSTACK_TYPE) ctx.logger.debug('validating CIDR for rules with a {0} field'.format( cidr_field_name)) for rule in ctx.node.properties['rules']: if cidr_field_name in rule: validate_ip_or_range_syntax(ctx, rule[cidr_field_name])
def sg_creation_validation(client, cidr_field_name, **kwargs): validate_resource(ctx, client, SECURITY_GROUP_OPENSTACK_TYPE) ctx.logger.debug( 'validating CIDR for rules with a {0} field'.format(cidr_field_name)) for rule in ctx.node.properties['rules']: if cidr_field_name in rule: validate_ip_or_range_syntax(ctx, rule[cidr_field_name])
def creation_validation(neutron_client, **kwargs): validate_resource(ctx, neutron_client, SUBNET_OPENSTACK_TYPE) if 'cidr' not in ctx.node.properties['subnet']: err = '"cidr" property must appear under the "subnet" property of a ' \ 'subnet node' ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) validate_ip_or_range_syntax(ctx, ctx.node.properties['subnet']['cidr'])
def creation_validation(neutron_client, args, **kwargs): validate_resource(ctx, neutron_client, SUBNET_OPENSTACK_TYPE) subnet = dict(ctx.node.properties[SUBNET_OPENSTACK_TYPE], **args) if CIDR not in subnet: err = '"cidr" property must appear under the "subnet" property of a ' \ 'subnet node' ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) validate_ip_or_range_syntax(ctx, subnet[CIDR])
def creation_validation(nova_client, **kwargs): def validate_private_key_permissions(private_key_path): ctx.logger.debug('checking whether private key file {0} has the ' 'correct permissions'.format(private_key_path)) if not os.access(private_key_path, os.R_OK | os.W_OK): err = 'private key file {0} is not readable and/or ' \ 'writeable'.format(private_key_path) ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) ctx.logger.debug('OK: private key file {0} has the correct ' 'permissions'.format(private_key_path)) def validate_path_owner(path): ctx.logger.debug('checking whether directory {0} is owned by the ' 'current user'.format(path)) from pwd import getpwnam, getpwuid user = getuser() owner = getpwuid(os.stat(path).st_uid).pw_name current_user_id = str(getpwnam(user).pw_uid) owner_id = str(os.stat(path).st_uid) if not current_user_id == owner_id: err = '{0} is not owned by the current user (it is owned by {1})'\ .format(path, owner) ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) ctx.logger.debug('OK: {0} is owned by the current user'.format(path)) validate_resource(ctx, nova_client, KEYPAIR_OPENSTACK_TYPE) private_key_path = _get_private_key_path() pk_exists = _check_private_key_exists(private_key_path) if is_external_resource(ctx): if pk_exists: if platform.system() == 'Linux': validate_private_key_permissions(private_key_path) validate_path_owner(private_key_path) else: err = "can't use external keypair: the public key {0} is " \ "available on Openstack, but the private key could not be " \ "found at {1}".format(ctx.node.properties['resource_id'], private_key_path) ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) else: if pk_exists: err = 'private key path already exists: {0}'.format( private_key_path) ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) ctx.logger.debug('OK: keypair configuration is valid')
def _test_validate_resource(self, is_external, create_if_missing, exists, client_mock_provided=None): properties = {'create_if_missing': create_if_missing, 'use_external_resource': is_external, 'resource_id': 'resource_id'} client_mock = client_mock_provided or mock.MagicMock() os_type = 'test' def _raise_error(*_): raise NonRecoverableError('Error') def _return_something(*_): return mock.MagicMock() return_value = _return_something if exists else _raise_error if exists: properties.update({'resource_id': 'rid'}) node_context = MockCloudifyContext(node_id='a20847', properties=properties) with mock.patch( 'openstack_plugin_common._get_resource_by_name_or_id_from_ctx', new=return_value): return common.validate_resource(node_context, client_mock, os_type)
def _test_validate_resource(self, is_external, create_if_missing, exists, client_mock_provided=None): properties = { 'create_if_missing': create_if_missing, 'use_external_resource': is_external, 'resource_id': 'resource_id' } client_mock = client_mock_provided or mock.MagicMock() os_type = 'test' def _raise_error(*_): raise NonRecoverableError('Error') def _return_something(*_): return mock.MagicMock() return_value = _return_something if exists else _raise_error if exists: properties.update({'resource_id': 'rid'}) node_context = MockCloudifyContext(node_id='a20847', properties=properties) with mock.patch( 'openstack_plugin_common._get_resource_by_name_or_id_from_ctx', new=return_value): return common.validate_resource(node_context, client_mock, os_type)
def creation_validation(nova_client, args, **kwargs): def validate_server_property_value_exists(server_props, property_name): ctx.logger.debug( 'checking whether {0} exists...'.format(property_name)) serv_props_copy = server_props.copy() try: handle_image_from_relationship(serv_props_copy, 'image', ctx) _handle_image_or_flavor(serv_props_copy, nova_client, property_name) except (NonRecoverableError, nova_exceptions.NotFound) as e: # temporary error - once image/flavor_name get removed, these # errors won't be relevant anymore err = str(e) ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) prop_value_id = str(serv_props_copy[property_name]) prop_values = list(nova_client.cosmo_list(property_name)) for f in prop_values: if prop_value_id == f.id: ctx.logger.debug('OK: {0} exists'.format(property_name)) return err = '{0} {1} does not exist'.format(property_name, prop_value_id) ctx.logger.error('VALIDATION ERROR: ' + err) if prop_values: ctx.logger.info('list of available {0}s:'.format(property_name)) for f in prop_values: ctx.logger.info(' {0:>10} - {1}'.format(f.id, f.name)) else: ctx.logger.info('there are no available {0}s'.format( property_name)) raise NonRecoverableError(err) validate_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) server_props = dict(ctx.node.properties['server'], **args) validate_server_property_value_exists(server_props, 'image') validate_server_property_value_exists(server_props, 'flavor')
def creation_validation(nova_client, **kwargs): def validate_server_property_value_exists(server_props, property_name): is_property_name = False prop_val = server_props.get(property_name) if not prop_val: prop_val = server_props.get('{0}_name'.format(property_name)) if not prop_val: err = 'must have a "{0}" or "{0}_name" field under ' \ '"server" property'.format(property_name) ctx.logger.error('VALIDATION ERROR: ' + err) is_property_name = True prop_val = str(prop_val) ctx.logger.debug( 'checking whether {0} {1} exists...'.format(property_name, prop_val)) prop_values = list(nova_client.cosmo_list(property_name)) for f in prop_values: if (is_property_name and prop_val == f.name) or \ (not is_property_name and prop_val == f.id): ctx.logger.debug('OK: {0} {1} exists'.format( property_name, prop_val)) return err = '{0} {1} does not exist'.format(property_name, prop_val) ctx.logger.error('VALIDATION ERROR: ' + err) if prop_values: ctx.logger.info('list of available {0}s:'.format(property_name)) for f in prop_values: ctx.logger.info(' {0:>10} - {1}'.format(f.id, f.name)) else: ctx.logger.info('there are no available {0}s'.format( property_name)) raise NonRecoverableError(err) validate_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) server_props = ctx.node.properties['server'] validate_server_property_value_exists(server_props, 'image') validate_server_property_value_exists(server_props, 'flavor')
def creation_validation(nova_client, args, **kwargs): def validate_server_property_value_exists(server_props, property_name): ctx.logger.debug( 'checking whether {0} exists...'.format(property_name)) serv_props_copy = server_props.copy() try: handle_image_from_relationship(serv_props_copy, 'image', ctx) _handle_image_or_flavor(serv_props_copy, nova_client, property_name) except (NonRecoverableError, nova_exceptions.NotFound) as e: # temporary error - once image/flavor_name get removed, these # errors won't be relevant anymore err = str(e) ctx.logger.error('VALIDATION ERROR: ' + err) raise NonRecoverableError(err) prop_value_id = str(serv_props_copy[property_name]) prop_values = list(nova_client.cosmo_list(property_name)) for f in prop_values: if prop_value_id == f.id: ctx.logger.debug('OK: {0} exists'.format(property_name)) return err = '{0} {1} does not exist'.format(property_name, prop_value_id) ctx.logger.error('VALIDATION ERROR: ' + err) if prop_values: ctx.logger.info('list of available {0}s:'.format(property_name)) for f in prop_values: ctx.logger.info(' {0:>10} - {1}'.format(f.id, f.name)) else: ctx.logger.info('there are no available {0}s'.format( property_name)) raise NonRecoverableError(err) validate_resource(ctx, nova_client, SERVER_OPENSTACK_TYPE) server_props = dict(ctx.node.properties['server'], **args) validate_server_property_value_exists(server_props, 'flavor')
def _test_quota_validation(self, amount, quota, failure_expected): ctx = MockCloudifyContext(node_id='node_id', properties={}) client = mock.MagicMock() def mock_cosmo_list(_): return [x for x in range(0, amount)] client.cosmo_list = mock_cosmo_list def mock_get_quota(_): return quota client.get_quota = mock_get_quota if failure_expected: self.assertRaisesRegexp( NonRecoverableError, 'cannot be created due to quota limitations', common.validate_resource, ctx=ctx, sugared_client=client, openstack_type='openstack_type') else: common.validate_resource( ctx=ctx, sugared_client=client, openstack_type='openstack_type')
def creation_validation(cinder_client, **kwargs): validate_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, 'display_name')
def creation_validation(neutron_client, **kwargs): validate_resource(ctx, neutron_client, NETWORK_OPENSTACK_TYPE)
def creation_validation(glance_client, **kwargs): validate_resource(ctx, glance_client, IMAGE_OPENSTACK_TYPE) _validate_image_dictionary() _validate_image()
def floatingip_creation_validation(client, ip_field_name, **kwargs): validate_resource(ctx, client, FLOATINGIP_OPENSTACK_TYPE, ip_field_name)
def creation_validation(nova_client, **kwargs): validate_resource(ctx, nova_client, SERVER_GROUP_OPENSTACK_TYPE) ctx.logger.debug('OK: server group configuration is valid')
def creation_validation(keystone_client, **kwargs): validate_resource(ctx, keystone_client, PROJECT_OPENSTACK_TYPE)
def creation_validation(cinder_client, **kwargs): validate_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, VOLUME_OPENSTACK_ID_KEY)
def creation_validation(neutron_client, **kwargs): validate_resource(ctx, neutron_client, FLOATINGIP_OPENSTACK_TYPE, 'floating_ip_address')