Example #1
0
    def _validate_required_options(self, tenant_name, tenant_id,
                                   project_name, project_id,
                                   token, service_catalog_url, auth_url):
        if token and not service_catalog_url:
            raise exc.CommandError(
                "bypass_url missing: When specifying a token the bypass_url "
                "must be set via --bypass-url or env[OS_MANILA_BYPASS_URL]")
        if service_catalog_url and not token:
            raise exc.CommandError(
                "Token missing: When specifying a bypass_url a token must be "
                "set via --os-token or env[OS_TOKEN]")
        if token and service_catalog_url:
            return

        if not (tenant_name or tenant_id or project_name or project_id):
            raise exc.CommandError(
                "You must provide a tenant_name, tenant_id, "
                "project_id or project_name (with "
                "project_domain_name or project_domain_id) via "
                "--os-tenant-name or env[OS_TENANT_NAME], "
                "--os-tenant-id or env[OS_TENANT_ID], "
                "--os-project-id or env[OS_PROJECT_ID], "
                "--os-project-name or env[OS_PROJECT_NAME], "
                "--os-project-domain-id or env[OS_PROJECT_DOMAIN_ID] and "
                "--os-project-domain-name or env[OS_PROJECT_DOMAIN_NAME]."
            )

        if not auth_url:
            raise exc.CommandError(
                "You must provide an auth url "
                "via either --os-auth-url or env[OS_AUTH_URL]")
Example #2
0
    def _validate_access(self,
                         access_type,
                         access,
                         valid_access_types=None,
                         enable_ipv6=False):
        if not valid_access_types:
            valid_access_types = ('ip', 'user', 'cert')

        if access_type in valid_access_types:
            if access_type == 'ip':
                try:
                    if enable_ipv6:
                        ipaddress.ip_network(str(access))
                    else:
                        ipaddress.IPv4Network(str(access))
                except ValueError as error:
                    raise exceptions.CommandError(str(error))
            elif access_type == 'user':
                self._validate_username(access)
            elif access_type == 'cert':
                # 'access' is used as the certificate's CN (common name)
                # to which access is allowed or denied by the backend.
                # The standard allows for just about any string in the
                # common name. The meaning of a string depends on its
                # interpretation and is limited to 64 characters.
                self._validate_common_name(access.strip())
            elif access_type == 'cephx':
                self._validate_cephx_id(access.strip())
        else:
            msg = ('Only following access types are supported: %s' %
                   ', '.join(valid_access_types))
            raise exceptions.CommandError(msg)
    def _validate_required_options(self,
                                   os_tenant_name,
                                   os_tenant_id,
                                   os_project_name,
                                   os_project_id,
                                   os_auth_url):

        if not (os_tenant_name or os_tenant_id or os_project_name or
                os_project_id):
            raise exc.CommandError(
                "You must provide a tenant_name, tenant_id, "
                "project_id or project_name (with "
                "project_domain_name or project_domain_id) via "
                "--os-tenant-name (env[OS_TENANT_NAME]), "
                "--os-tenant-id (env[OS_TENANT_ID]), "
                "--os-project-id (env[OS_PROJECT_ID]), "
                "--os-project-name (env[OS_PROJECT_NAME]), "
                "--os-project-domain-id (env[OS_PROJECT_DOMAIN_ID]) and "
                "--os-project-domain-name (env[OS_PROJECT_DOMAIN_NAME])."
            )

        if not os_auth_url:
            raise exc.CommandError(
                "You must provide an auth url "
                "via either --os-auth-url or env[OS_AUTH_URL]")
Example #4
0
def extract_properties(properties):
    result_dict = {}
    for item in properties:
        try:
            (key, value) = item.split('=', 1)
            if key in result_dict:
                raise exceptions.CommandError(
                    "Argument '%s' is specified twice." % key)
            else:
                result_dict[key] = value
        except ValueError:
            raise exceptions.CommandError(
                "Parsing error, expected format 'key=value' for " + item)
    return result_dict
Example #5
0
    def _validate_username(access):
        sole_periods_spaces_re = r'[\s|\.]+$'
        valid_username_re = r'.[^\"\/\\\[\]\:\;\|\=\,\+\*\?\<\>]{3,254}$'
        username = access

        if re.match(sole_periods_spaces_re, username):
            exc_str = ('Invalid user or group name,cannot consist solely '
                       'of periods or spaces.')
            raise exceptions.CommandError(exc_str)

        if not re.match(valid_username_re, username):
            exc_str = ('Invalid user or group name. Must be 4-255 characters '
                       'and consist of alphanumeric characters and '
                       'exclude special characters "/\\[]:;|=,+*?<>')
            raise exceptions.CommandError(exc_str)
Example #6
0
    def _validate_cephx_id(cephx_id):
        if not cephx_id:
            raise exceptions.CommandError('Ceph IDs may not be empty.')

        # This restriction may be lifted in Ceph in the future:
        # http://tracker.ceph.com/issues/14626
        if not set(cephx_id) <= set(string.printable):
            raise exceptions.CommandError(
                'Ceph IDs must consist of ASCII printable characters.')

        # Periods are technically permitted, but we restrict them here
        # to avoid confusion where users are unsure whether they should
        # include the "client." prefix: otherwise they could accidentally
        # create "client.client.foobar".
        if '.' in cephx_id:
            raise exceptions.CommandError('Ceph IDs may not contain periods.')
Example #7
0
    def _handle_spec_driver_handles_share_servers(
            self, extra_specs, spec_driver_handles_share_servers):
        """Validation and default for DHSS extra spec."""

        if spec_driver_handles_share_servers is not None:
            if 'driver_handles_share_servers' in extra_specs:
                msg = ("'driver_handles_share_servers' is already set via "
                       "positional argument.")
                raise exceptions.CommandError(msg)
            else:
                extra_specs['driver_handles_share_servers'] = (
                    spec_driver_handles_share_servers)
        else:
            msg = ("'driver_handles_share_servers' is not set via "
                   "positional argument.")
            raise exceptions.CommandError(msg)
    def update(self, share_network, neutron_net_id=None,
               neutron_subnet_id=None, name=None,
               description=None):
        """Updates a share network.

        :param share_network: share network to update.
        :rtype: :class:`ShareNetwork`
        """
        values = {}
        if neutron_net_id is not None:
            values['neutron_net_id'] = neutron_net_id
        if neutron_subnet_id is not None:
            values['neutron_subnet_id'] = neutron_subnet_id
        if name is not None:
            values['name'] = name
        if description is not None:
            values['description'] = description

        for k, v in values.items():
            if v == '':
                values[k] = None

        if not values:
            msg = "Must specify fields to be updated"
            raise exceptions.CommandError(msg)

        body = {RESOURCE_NAME: values}
        return self._update(RESOURCE_PATH % common_base.getid(share_network),
                            body,
                            RESOURCE_NAME)
Example #9
0
 def _validate_username(access):
     valid_username_re = '[\w\$\.\-_\`;\'\{\}\[\]\\\\]{4,255}$'
     username = access
     if not re.match(valid_username_re, username):
         exc_str = ('Invalid user or group name. Must be 4-255 characters '
                    'and consist of alphanumeric characters and '
                    'special characters $]{.-_\'`;}[\\')
         raise exceptions.CommandError(exc_str)
Example #10
0
def extract_extra_specs(extra_specs, specs_to_add):
    for item in specs_to_add:
        (key, value) = item.split('=', 1)
        if key in extra_specs:
            msg = ("Argument '%s' value specified twice." % key)
            raise exceptions.CommandError(msg)
        elif key in constants.BOOL_SPECS:
            if strutils.is_valid_boolstr(value):
                extra_specs[key] = value.capitalize()
            else:
                msg = ("Argument '%s' is of boolean "
                       "type and has invalid value: %s" %
                       (key, six.text_type(value)))
                raise exceptions.CommandError(msg)
        else:
            extra_specs[key] = value
    return extra_specs
Example #11
0
 def _validate_access(self, access_type, access):
     if access_type == 'ip':
         self._validate_ip_range(access)
     elif access_type == 'passwd':
         self._validate_username(access)
     else:
         raise exceptions.CommandError(
             'Only ip and passwd type are supported')
Example #12
0
    def update(self,
               security_service,
               dns_ip=None,
               ou=None,
               server=None,
               domain=None,
               password=None,
               user=None,
               name=None,
               description=None):
        """Updates a security service.

        :param security_service: security service to update.
        :param dns_ip: dns ip address used inside tenant's network
        :param ou: security service organizational unit
        :param server: security service server ip address or hostname
        :param domain: security service domain
        :param user: security identifier used by tenant
        :param password: password used by user
        :param name: security service name
        :param description: security service description
        :rtype: :class:`SecurityService`
        """

        values = {}
        if dns_ip is not None:
            values['dns_ip'] = dns_ip
        if ou is not None:
            values['ou'] = ou
        if server is not None:
            values['server'] = server
        if domain is not None:
            values['domain'] = domain
        if user is not None:
            values['user'] = user
        if password is not None:
            values['password'] = password
        if name is not None:
            values['name'] = name
        if description is not None:
            values['description'] = description

        for k, v in values.items():
            if v == '':
                values[k] = None

        if not values:
            msg = "Must specify fields to be updated"
            raise exceptions.CommandError(msg)

        body = {RESOURCE_NAME: values}

        return self._update(
            RESOURCE_PATH % common_base.getid(security_service),
            body,
            RESOURCE_NAME,
        )
Example #13
0
 def _validate_ip_range(ip_range):
     ip_range = ip_range.split('/')
     exc_str = ('Supported ip format examples:\n'
                '\t10.0.0.2, 10.0.0.*, 10.0.0.0/24')
     if len(ip_range) > 2:
         raise exceptions.CommandError(exc_str)
     allow_asterisk = (len(ip_range) == 1)
     ip_range = ip_range[0].split('.')
     if len(ip_range) != 4:
         raise exceptions.CommandError(exc_str)
     for item in ip_range:
         try:
             if 0 <= int(item) <= 255:
                 continue
             raise ValueError()
         except ValueError:
             if not (allow_asterisk and item == '*'):
                 raise exceptions.CommandError(exc_str)
Example #14
0
 def do_help(self, args):
     """Display help about this program or one of its subcommands."""
     if args.command:
         if args.command in self.subcommands:
             self.subcommands[args.command].print_help()
         else:
             raise exc.CommandError("'%s' is not a valid subcommand" %
                                    args.command)
     else:
         self.parser.print_help()
Example #15
0
def find_resource(manager, name_or_id):
    """Helper for the _find_* methods."""
    # first try to get entity as integer id
    try:
        if isinstance(name_or_id, int) or name_or_id.isdigit():
            return manager.get(int(name_or_id))
    except exceptions.NotFound:
        pass

    # now try to get entity as uuid
    try:
        uuid.UUID(strutils.safe_decode(name_or_id))
        return manager.get(name_or_id)
    except (ValueError, exceptions.NotFound):
        pass

    try:
        try:
            return manager.find(human_id=name_or_id)
        except exceptions.NotFound:
            pass

        # finally try to find entity by name
        try:
            return manager.find(name=name_or_id)
        except exceptions.NotFound:
            try:
                return manager.find(display_name=name_or_id)
            except (UnicodeDecodeError, exceptions.NotFound):
                try:
                    # Volumes does not have name, but display_name
                    return manager.find(display_name=name_or_id)
                except exceptions.NotFound:
                    msg = "No %s with a name or ID of '%s' exists." % \
                        (manager.resource_class.__name__.lower(), name_or_id)
                    raise exceptions.CommandError(msg)
    except exceptions.NoUniqueMatch:
        msg = ("Multiple %s matches found for '%s', use an ID to be more"
               " specific." %
               (manager.resource_class.__name__.lower(), name_or_id))
        raise exceptions.CommandError(msg)
Example #16
0
    def _handle_spec_snapshot_support(self, extra_specs, spec_snapshot_support,
                                      set_default=False):
        """Validation and default for snapshot extra spec."""

        if spec_snapshot_support is not None:
            if 'snapshot_support' in extra_specs:
                msg = "'snapshot_support' extra spec is provided twice."
                raise exceptions.CommandError(msg)
            else:
                extra_specs['snapshot_support'] = spec_snapshot_support
        elif 'snapshot_support' not in extra_specs and set_default:
            extra_specs['snapshot_support'] = True
Example #17
0
    def _get_keystone_client(self):
        # First create a Keystone session
        if self.insecure:
            verify = False
        else:
            verify = self.cacert or True
        ks_session = session.Session(verify=verify, cert=self.cert)

        # Discover the supported keystone versions using the given url
        ks_discover = discover.Discover(session=ks_session,
                                        auth_url=self.auth_url)

        # Inspect the auth_url to see the supported version. If both v3 and v2
        # are supported, then use the highest version if possible.
        v2_auth_url = ks_discover.url_for('v2.0')
        v3_auth_url = ks_discover.url_for('v3.0')

        if v3_auth_url:
            keystone_client = ks_client.Client(
                session=ks_session,
                version=(3, 0),
                auth_url=v3_auth_url,
                username=self.username,
                password=self.password,
                user_id=self.user_id,
                user_domain_name=self.user_domain_name,
                user_domain_id=self.user_domain_id,
                project_id=self.project_id or self.tenant_id,
                project_name=self.project_name,
                project_domain_name=self.project_domain_name,
                project_domain_id=self.project_domain_id,
                region_name=self.region_name)
        elif v2_auth_url:
            keystone_client = ks_client.Client(
                session=ks_session,
                version=(2, 0),
                auth_url=v2_auth_url,
                username=self.username,
                password=self.password,
                tenant_id=self.tenant_id,
                tenant_name=self.tenant_name,
                region_name=self.region_name,
                cert=self.cert,
                use_keyring=self.use_keyring,
                force_new_token=self.force_new_token,
                stale_duration=self.cached_token_lifetime)
        else:
            raise exceptions.CommandError(
                'Unable to determine the Keystone version to authenticate '
                'with using the given auth_url.')
        keystone_client.authenticate()
        return keystone_client
Example #18
0
def extract_extra_specs(extra_specs,
                        specs_to_add,
                        bool_specs=constants.BOOL_SPECS):
    try:
        for item in specs_to_add:
            (key, value) = item.split('=', 1)
            if key in extra_specs:
                msg = ("Argument '%s' value specified twice." % key)
                raise exceptions.CommandError(msg)
            elif key in bool_specs:
                if strutils.is_valid_boolstr(value):
                    extra_specs[key] = value.capitalize()
                else:
                    msg = ("Argument '%s' is of boolean "
                           "type and has invalid value: %s" %
                           (key, str(value)))
                    raise exceptions.CommandError(msg)
            else:
                extra_specs[key] = value
    except ValueError:
        msg = LOG.error(_("Wrong format: specs should be key=value pairs."))
        raise exceptions.CommandError(msg)
    return extra_specs
Example #19
0
 def _validate_ip_range(ip_range):
     ip_range = ip_range.split('/')
     exc_str = ('Supported ip format examples:\n' '\t10.0.0.2, 10.0.0.0/24')
     if len(ip_range) > 2:
         raise exceptions.CommandError(exc_str)
     if len(ip_range) == 2:
         try:
             prefix = int(ip_range[1])
             if prefix < 0 or prefix > 32:
                 raise ValueError()
         except ValueError:
             msg = 'IP prefix should be in range from 0 to 32'
             raise exceptions.CommandError(msg)
     ip_range = ip_range[0].split('.')
     if len(ip_range) != 4:
         raise exceptions.CommandError(exc_str)
     for item in ip_range:
         try:
             if 0 <= int(item) <= 255:
                 continue
             raise ValueError()
         except ValueError:
             raise exceptions.CommandError(exc_str)
Example #20
0
 def _validate_access(self, access_type, access):
     if access_type == 'ip':
         self._validate_ip_range(access)
     elif access_type == 'user':
         self._validate_username(access)
     elif access_type == 'cert':
         # 'access' is used as the certificate's CN (common name)
         # to which access is allowed or denied by the backend.
         # The standard allows for just about any string in the
         # common name. The meaning of a string depends on its
         # interpretation and is limited to 64 characters.
         self._validate_common_name(access.strip())
     else:
         raise exceptions.CommandError(
             'Only ip, user, and cert types are supported')
Example #21
0
def extract_key_value_options(pairs):
    result_dict = {}
    duplicate_options = []
    pairs = pairs or {}

    for attr, value in pairs.items():
        if attr not in result_dict:
            result_dict[attr] = value
        else:
            duplicate_options.append(attr)

    if pairs and len(duplicate_options) > 0:
        duplicate_str = ', '.join(duplicate_options)
        msg = "Following options were duplicated: %s" % duplicate_str
        raise exceptions.CommandError(msg)

    return result_dict
Example #22
0
    def main(self, argv):
        # Parse args once to find version and debug settings
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)
        self.setup_debugging(options.debug)

        # build available subcommands based on version
        self.extensions = self._discover_extensions(
            options.os_share_api_version)
        self._run_extension_hooks('__pre_parse_args__')

        subcommand_parser = self.get_subcommand_parser(
            options.os_share_api_version)
        self.parser = subcommand_parser

        if options.help or not argv:
            subcommand_parser.print_help()
            return 0

        args = subcommand_parser.parse_args(argv)
        self._run_extension_hooks('__post_parse_args__', args)

        # Short-circuit and deal with help right away.
        if args.func == self.do_help:
            self.do_help(args)
            return 0
        elif args.func == self.do_bash_completion:
            self.do_bash_completion(args)
            return 0

        (os_username, os_password, os_tenant_name, os_auth_url, os_region_name,
         os_tenant_id, endpoint_type, insecure, service_type, service_name,
         share_service_name, username, apikey, projectid, url, region_name,
         cacert) = (args.os_username, args.os_password, args.os_tenant_name,
                    args.os_auth_url, args.os_region_name, args.os_tenant_id,
                    args.endpoint_type, args.insecure, args.service_type,
                    args.service_name, args.share_service_name, args.username,
                    args.apikey, args.projectid, args.url, args.region_name,
                    args.os_cacert)

        if not endpoint_type:
            endpoint_type = DEFAULT_MANILA_ENDPOINT_TYPE

        if not service_type:
            service_type = DEFAULT_MANILA_SERVICE_TYPE
            service_type = utils.get_service_type(args.func) or service_type

        #FIXME(usrleon): Here should be restrict for project id same as
        # for os_username or os_password but for compatibility it is not.

        if not utils.isunauthenticated(args.func):
            if not os_username:
                if not username:
                    raise exc.CommandError(
                        "You must provide a username "
                        "via either --os-username or env[OS_USERNAME]")
                else:
                    os_username = username

            if not os_password:
                if not apikey:
                    raise exc.CommandError("You must provide a password "
                                           "via either --os-password or via "
                                           "env[OS_PASSWORD]")
                else:
                    os_password = apikey

            if not (os_tenant_name or os_tenant_id):
                if not projectid:
                    raise exc.CommandError("You must provide a tenant_id "
                                           "via either --os-tenant-id or "
                                           "env[OS_TENANT_ID]")
                else:
                    os_tenant_name = projectid

            if not os_auth_url:
                if not url:
                    raise exc.CommandError(
                        "You must provide an auth url "
                        "via either --os-auth-url or env[OS_AUTH_URL]")
                else:
                    os_auth_url = url

            if not os_region_name and region_name:
                os_region_name = region_name

        if not (os_tenant_name or os_tenant_id):
            raise exc.CommandError(
                "You must provide a tenant_id "
                "via either --os-tenant-id or env[OS_TENANT_ID]")

        if not os_auth_url:
            raise exc.CommandError(
                "You must provide an auth url "
                "via either --os-auth-url or env[OS_AUTH_URL]")

        self.cs = client.Client(options.os_share_api_version,
                                os_username,
                                os_password,
                                os_tenant_name,
                                os_auth_url,
                                insecure,
                                region_name=os_region_name,
                                tenant_id=os_tenant_id,
                                endpoint_type=endpoint_type,
                                extensions=self.extensions,
                                service_type=service_type,
                                service_name=service_name,
                                share_service_name=share_service_name,
                                retries=options.retries,
                                http_log_debug=args.debug,
                                cacert=cacert)

        try:
            if not utils.isunauthenticated(args.func):
                self.cs.authenticate()
        except exc.Unauthorized:
            raise exc.CommandError("Invalid OpenStack Manila credentials.")
        except exc.AuthorizationFailure:
            raise exc.CommandError("Unable to authorize user")

        args.func(self.cs, args)
Example #23
0
 def _validate_username(access):
     valid_useraname_re = '\w{4,32}'
     username = access
     if not re.match(valid_useraname_re, username):
         exc_str = _('Invalid user name. Must be alphanum 4-32 chars long')
         raise exceptions.CommandError(exc_str)
Example #24
0
 def _validate_common_name(access):
     if len(access) == 0 or len(access) > 64:
         exc_str = ('Invalid CN (common name). Must be 1-64 chars long.')
         raise exceptions.CommandError(exc_str)