コード例 #1
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        # FIXME(gyee): there are two scenarios:
        #
        # 1. user update password for himself
        # 2. admin update password on behalf of the user. This is an unlikely
        #    scenario because that will require admin knowing the user's
        #    original password which is forbidden under most security
        #    policies.
        #
        # Of the two scenarios above, user either authenticate using its
        # original password or an authentication token. For scenario #1,
        # if user is authenticating with its original password (i.e. passing
        # --os-password argument), we can just make use of it instead of using
        # --original-password or prompting. For scenario #2, admin will need
        # to specify --original-password option or this won't work because
        # --os-password is the admin's own password. In the future if we stop
        # supporting scenario #2 then we can just do this.
        #
        # current_password = (parsed_args.original_password or
        #                     self.app.cloud.password)
        #
        current_password = parsed_args.original_password
        if current_password is None:
            current_password = utils.get_password(
                self.app.stdin, prompt="Current Password:"******"New Password:")

        identity_client.users.update_password(current_password, password)
コード例 #2
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        # FIXME(gyee): there are two scenarios:
        #
        # 1. user update password for himself
        # 2. admin update password on behalf of the user. This is an unlikely
        #    scenario because that will require admin knowing the user's
        #    original password which is forbidden under most security
        #    policies.
        #
        # Of the two scenarios above, user either authenticate using its
        # original password or an authentication token. For scenario #1,
        # if user is authenticating with its original password (i.e. passing
        # --os-password argument), we can just make use of it instead of using
        # --original-password or prompting. For scenario #2, admin will need
        # to specify --original-password option or this won't work because
        # --os-password is the admin's own password. In the future if we stop
        # supporting scenario #2 then we can just do this.
        #
        # current_password = (parsed_args.original_password or
        #                     self.app.cloud.password)
        #
        current_password = parsed_args.original_password
        if current_password is None:
            current_password = utils.get_password(self.app.stdin,
                                                  prompt="Current Password:"******"New Password:")

        identity_client.users.update_password(current_password, password)
コード例 #3
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        client = self.app.client_manager.data_processing

        jb_id = utils.get_resource_id(
            client.job_binaries, parsed_args.job_binary)

        if parsed_args.json:
            blob = osc_utils.read_blob_file_contents(parsed_args.json)
            try:
                template = jsonutils.loads(blob)
            except ValueError as e:
                raise exceptions.CommandError(
                    'An error occurred when reading '
                    'template from file %s: %s' % (parsed_args.json, e))
            data = client.job_binaries.update(jb_id, template).to_dict()
        else:
            if parsed_args.password_prompt:
                parsed_args.password = osc_utils.get_password(
                    self.app.stdin, confirm=False)
            if parsed_args.secret_key_prompt:
                parsed_args.secret_key = osc_utils.get_password(
                    self.app.stdin, confirm=False)

            extra = {}
            if parsed_args.password:
                extra['password'] = parsed_args.password
            if parsed_args.username:
                extra['user'] = parsed_args.username
            if parsed_args.access_key:
                extra['accesskey'] = parsed_args.access_key
            if parsed_args.secret_key:
                extra['secretkey'] = parsed_args.secret_key
            if parsed_args.s3_endpoint:
                extra['endpoint'] = parsed_args.s3_endpoint
            if not extra:
                extra = None

            update_fields = utils.create_dict_from_kwargs(
                name=parsed_args.name, url=parsed_args.url,
                description=parsed_args.description,
                extra=extra, is_public=parsed_args.is_public,
                is_protected=parsed_args.is_protected
            )

            data = client.job_binaries.update(
                jb_id, update_fields).to_dict()

        data = utils.prepare_data(data, JOB_BINARY_FIELDS)

        return self.dict2columns(data)
コード例 #4
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        client = self.app.client_manager.data_processing

        jb_id = utils.get_resource_id(client.job_binaries,
                                      parsed_args.job_binary)

        if parsed_args.json:
            blob = osc_utils.read_blob_file_contents(parsed_args.json)
            try:
                template = jsonutils.loads(blob)
            except ValueError as e:
                raise exceptions.CommandError('An error occurred when reading '
                                              'template from file %s: %s' %
                                              (parsed_args.json, e))
            data = client.job_binaries.update(jb_id, template).to_dict()
        else:
            if parsed_args.password_prompt:
                parsed_args.password = osc_utils.get_password(self.app.stdin,
                                                              confirm=False)
            if parsed_args.secret_key_prompt:
                parsed_args.secret_key = osc_utils.get_password(self.app.stdin,
                                                                confirm=False)

            extra = {}
            if parsed_args.password:
                extra['password'] = parsed_args.password
            if parsed_args.username:
                extra['user'] = parsed_args.username
            if parsed_args.access_key:
                extra['accesskey'] = parsed_args.access_key
            if parsed_args.secret_key:
                extra['secretkey'] = parsed_args.secret_key
            if parsed_args.s3_endpoint:
                extra['endpoint'] = parsed_args.s3_endpoint
            if not extra:
                extra = None

            update_fields = utils.create_dict_from_kwargs(
                name=parsed_args.name,
                url=parsed_args.url,
                description=parsed_args.description,
                extra=extra,
                is_public=parsed_args.is_public,
                is_protected=parsed_args.is_protected)

            data = client.job_binaries.update(jb_id, update_fields).to_dict()

        data = utils.prepare_data(data, JOB_BINARY_FIELDS)

        return self.dict2columns(data)
コード例 #5
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        # FIXME(gyee): there are two scenarios:
        #
        # 1. user update password for himself
        # 2. admin update password on behalf of the user. This is an unlikely
        #    scenario because that will require admin knowing the user's
        #    original password which is forbidden under most security
        #    policies.
        #
        # Of the two scenarios above, user either authenticate using its
        # original password or an authentication token. For scenario #1,
        # if user is authenticating with its original password (i.e. passing
        # --os-password argument), we can just make use of it instead of using
        # --original-password or prompting. For scenario #2, admin will need
        # to specify --original-password option or this won't work because
        # --os-password is the admin's own password. In the future if we stop
        # supporting scenario #2 then we can just do this.
        #
        # current_password = (parsed_args.original_password or
        #                     self.app.cloud.password)
        #
        current_password = parsed_args.original_password
        if current_password is None:
            current_password = utils.get_password(
                self.app.stdin, prompt="Current Password:"******"New Password:"******"No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        identity_client.users.update_password(current_password, password)

        # retrieve the authentication information from the cached token session
        session_auth = identity_client.session.auth
        username = ""
        if "username" in session_auth.__dict__:
            username = session_auth.username
        elif "_username" in session_auth.__dict__:
            username = session_auth._username
        if username == 'admin' :
            print("Warning: '%s' password changed. Please wait 5 minutes "
                  "before Locking/Unlocking the controllers for the password "
                  "change to come into effect\n" %(username))
コード例 #6
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if '' == parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )
        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        if parsed_args.password:
            kwargs['password'] = parsed_args.password
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id
            kwargs['default_project'] = project_id
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #7
0
ファイル: test_utils.py プロジェクト: dtroyer/osc-lib
 def test_get_password_bad_once(self):
     answers = [PASSWORD, WASSPORD, DROWSSAP, DROWSSAP]
     with mock.patch("getpass.getpass", side_effect=answers):
         mock_stdin = mock.Mock()
         mock_stdin.isatty = mock.Mock()
         mock_stdin.isatty.return_value = True
         self.assertEqual(DROWSSAP, utils.get_password(mock_stdin))
コード例 #8
0
 def test_get_password_bad_once(self):
     answers = [PASSWORD, WASSPORD, DROWSSAP, DROWSSAP]
     with mock.patch("getpass.getpass", side_effect=answers):
         mock_stdin = mock.Mock()
         mock_stdin.isatty = mock.Mock()
         mock_stdin.isatty.return_value = True
         self.assertEqual(DROWSSAP, utils.get_password(mock_stdin))
コード例 #9
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )
        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        if parsed_args.password:
            kwargs['password'] = parsed_args.password
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id
            kwargs['default_project'] = project_id
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #10
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )
        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        if parsed_args.password:
            kwargs['password'] = parsed_args.password
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id
            kwargs['default_project'] = project_id
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #11
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        client = self.app.client_manager.data_processing

        if parsed_args.json:
            blob = osc_utils.read_blob_file_contents(parsed_args.json)
            try:
                template = jsonutils.loads(blob)
            except ValueError as e:
                raise exceptions.CommandError('An error occurred when reading '
                                              'template from file %s: %s' %
                                              (parsed_args.json, e))
            data = client.job_binaries.create(**template).to_dict()
        else:
            if parsed_args.data:
                data = open(parsed_args.data).read()
                jbi_id = client.job_binary_internals.create(
                    parsed_args.name, data).id
                parsed_args.url = 'internal-db://' + jbi_id

            if parsed_args.password_prompt:
                parsed_args.password = osc_utils.get_password(self.app.stdin,
                                                              confirm=False)

            if parsed_args.password and not parsed_args.username:
                raise exceptions.CommandError(
                    'Username via --username should be provided with password')

            if parsed_args.username and not parsed_args.password:
                raise exceptions.CommandError(
                    'Password should be provided via --password or entered '
                    'interactively with --password-prompt')

            if parsed_args.password and parsed_args.username:
                extra = {
                    'user': parsed_args.username,
                    'password': parsed_args.password
                }
            else:
                extra = None

            data = client.job_binaries.create(
                name=parsed_args.name,
                url=parsed_args.url,
                description=parsed_args.description,
                extra=extra,
                is_public=parsed_args.public,
                is_protected=parsed_args.protected).to_dict()

        data = utils.prepare_data(data, JOB_BINARY_FIELDS)

        return self.dict2columns(data)
コード例 #12
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.project:
            project_id = utils.find_resource(
                identity_client.tenants,
                parsed_args.project,
            ).id
        else:
            project_id = None

        enabled = True
        if parsed_args.disable:
            enabled = False
        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if not parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        try:
            user = identity_client.users.create(
                parsed_args.name,
                parsed_args.password,
                parsed_args.email,
                tenant_id=project_id,
                enabled=enabled,
            )
        except ks_exc.Conflict:
            if parsed_args.or_show:
                user = utils.find_resource(
                    identity_client.users,
                    parsed_args.name,
                )
                LOG.info(_('Returning existing user %s'), user.name)
            else:
                raise

        # NOTE(dtroyer): The users.create() method wants 'tenant_id' but
        #                the returned resource has 'tenantId'.  Sigh.
        #                We're using project_id now inside OSC so there.
        if 'tenantId' in user._info:
            user._info.update(
                {'project_id': user._info.pop('tenantId')}
            )

        info = {}
        info.update(user._info)
        return zip(*sorted(six.iteritems(info)))
コード例 #13
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)" % parsed_args)
        client = self.app.client_manager.data_processing

        if parsed_args.json:
            blob = osc_utils.read_blob_file_contents(parsed_args.json)
            try:
                template = jsonutils.loads(blob)
            except ValueError as e:
                raise exceptions.CommandError(
                    'An error occurred when reading '
                    'template from file %s: %s' % (parsed_args.json, e))
            data = client.job_binaries.create(**template).to_dict()
        else:
            if parsed_args.data:
                data = open(parsed_args.data).read()
                jbi_id = client.job_binary_internals.create(
                    parsed_args.name, data).id
                parsed_args.url = 'internal-db://' + jbi_id

            if parsed_args.password_prompt:
                parsed_args.password = osc_utils.get_password(
                    self.app.stdin, confirm=False)

            if parsed_args.password and not parsed_args.username:
                raise exceptions.CommandError(
                    'Username via --username should be provided with password')

            if parsed_args.username and not parsed_args.password:
                raise exceptions.CommandError(
                    'Password should be provided via --password or entered '
                    'interactively with --password-prompt')

            if parsed_args.password and parsed_args.username:
                extra = {
                    'user': parsed_args.username,
                    'password': parsed_args.password
                }
            else:
                extra = None

            data = client.job_binaries.create(
                name=parsed_args.name, url=parsed_args.url,
                description=parsed_args.description, extra=extra,
                is_public=parsed_args.public,
                is_protected=parsed_args.protected).to_dict()

        data = utils.prepare_data(data, JOB_BINARY_FIELDS)

        return self.dict2columns(data)
コード例 #14
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.project:
            project_id = utils.find_resource(
                identity_client.tenants,
                parsed_args.project,
            ).id
        else:
            project_id = None

        enabled = True
        if parsed_args.disable:
            enabled = False
        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if not parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        try:
            user = identity_client.users.create(
                parsed_args.name,
                parsed_args.password,
                parsed_args.email,
                tenant_id=project_id,
                enabled=enabled,
            )
        except ks_exc.Conflict:
            if parsed_args.or_show:
                user = utils.find_resource(
                    identity_client.users,
                    parsed_args.name,
                )
                LOG.info(_('Returning existing user %s'), user.name)
            else:
                raise

        # NOTE(dtroyer): The users.create() method wants 'tenant_id' but
        #                the returned resource has 'tenantId'.  Sigh.
        #                We're using project_id now inside OSC so there.
        if 'tenantId' in user._info:
            user._info.update(
                {'project_id': user._info.pop('tenantId')}
            )

        info = {}
        info.update(user._info)
        return zip(*sorted(six.iteritems(info)))
コード例 #15
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if '' == parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        user_str = common._get_token_resource(identity_client, 'user',
                                              parsed_args.user,
                                              parsed_args.domain)
        if parsed_args.domain:
            domain = common.find_domain(identity_client, parsed_args.domain)
            user = utils.find_resource(identity_client.users,
                                       user_str,
                                       domain_id=domain.id)
        else:
            user = utils.find_resource(
                identity_client.users,
                parsed_args.user,
            )

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        if parsed_args.password:
            kwargs['password'] = parsed_args.password
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id
            kwargs['default_project'] = project_id
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        options = _get_options_for_user(identity_client, parsed_args)
        if options:
            kwargs['options'] = options

        identity_client.users.update(user.id, **kwargs)
コード例 #16
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if '' == parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        user_str = common._get_token_resource(identity_client, 'user',
                                              parsed_args.user,
                                              parsed_args.domain)
        if parsed_args.domain:
            domain = common.find_domain(identity_client, parsed_args.domain)
            user = utils.find_resource(identity_client.users,
                                       user_str,
                                       domain_id=domain.id)
        else:
            user = utils.find_resource(
                identity_client.users,
                parsed_args.user,
            )

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        if parsed_args.password:
            kwargs['password'] = parsed_args.password
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id
            kwargs['default_project'] = project_id
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
        if user.name == 'admin' and 'password' in kwargs :
            print("Warning: '%s' password changed. Please wait 5 minutes "
                  "before Locking/Unlocking the controllers for the password "
                  "change to come into effect\n" %(user.name))
コード例 #17
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        project_id = None
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id

        domain_id = None
        if parsed_args.domain:
            domain_id = common.find_domain(identity_client,
                                           parsed_args.domain).id

        enabled = True
        if parsed_args.disable:
            enabled = False
        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if not parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))
        options = _get_options_for_user(identity_client, parsed_args)

        try:
            user = identity_client.users.create(
                name=parsed_args.name,
                domain=domain_id,
                default_project=project_id,
                password=parsed_args.password,
                email=parsed_args.email,
                description=parsed_args.description,
                enabled=enabled,
                options=options,
            )
        except ks_exc.Conflict:
            if parsed_args.or_show:
                user = utils.find_resource(identity_client.users,
                                           parsed_args.name,
                                           domain_id=domain_id)
                LOG.info(_('Returning existing user %s'), user.name)
            else:
                raise

        user._info.pop('links')
        return zip(*sorted(user._info.items()))
コード例 #18
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        project_id = None
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id

        domain_id = None
        if parsed_args.domain:
            domain_id = common.find_domain(identity_client,
                                           parsed_args.domain).id

        enabled = True
        if parsed_args.disable:
            enabled = False
        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if not parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        try:
            user = identity_client.users.create(
                name=parsed_args.name,
                domain=domain_id,
                default_project=project_id,
                password=parsed_args.password,
                email=parsed_args.email,
                description=parsed_args.description,
                enabled=enabled
            )
        except ks_exc.Conflict:
            if parsed_args.or_show:
                user = utils.find_resource(identity_client.users,
                                           parsed_args.name,
                                           domain_id=domain_id)
                LOG.info(_('Returning existing user %s'), user.name)
            else:
                raise

        user._info.pop('links')
        return zip(*sorted(six.iteritems(user._info)))
コード例 #19
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if '' == parsed_args.password:
            LOG.warning(
                _("No password was supplied, authentication will fail "
                  "when a user does not have a password."))

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )

        if parsed_args.password:
            identity_client.users.update_password(
                user.id,
                parsed_args.password,
            )

        if parsed_args.project:
            project = utils.find_resource(
                identity_client.tenants,
                parsed_args.project,
            )
            identity_client.users.update_tenant(
                user.id,
                project.id,
            )

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #20
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if (not parsed_args.name
                and not parsed_args.name
                and not parsed_args.password
                and not parsed_args.email
                and not parsed_args.project
                and not parsed_args.description
                and not parsed_args.enable
                and not parsed_args.disable):
            sys.stderr.write(_("Incorrect set of arguments provided. "
                               "See openstack --help for more details\n"))
            return

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )
        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        if parsed_args.password:
            kwargs['password'] = parsed_args.password
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id
            kwargs['default_project'] = project_id
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #21
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        if '' == parsed_args.password:
            LOG.warning(_("No password was supplied, authentication will fail "
                          "when a user does not have a password."))

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )

        if parsed_args.password:
            identity_client.users.update_password(
                user.id,
                parsed_args.password,
            )

        if parsed_args.project:
            project = utils.find_resource(
                identity_client.tenants,
                parsed_args.project,
            )
            identity_client.users.update_tenant(
                user.id,
                project.id,
            )

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #22
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        project_id = None
        if parsed_args.project:
            project_id = common.find_project(identity_client,
                                             parsed_args.project,
                                             parsed_args.project_domain).id

        domain_id = None
        if parsed_args.domain:
            domain_id = common.find_domain(identity_client,
                                           parsed_args.domain).id

        enabled = True
        if parsed_args.disable:
            enabled = False
        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        try:
            user = identity_client.users.create(
                name=parsed_args.name,
                domain=domain_id,
                default_project=project_id,
                password=parsed_args.password,
                email=parsed_args.email,
                description=parsed_args.description,
                enabled=enabled)
        except ks_exc.Conflict:
            if parsed_args.or_show:
                user = utils.find_resource(identity_client.users,
                                           parsed_args.name,
                                           domain_id=domain_id)
                LOG.info(_('Returning existing user %s'), user.name)
            else:
                raise

        user._info.pop('links')
        return zip(*sorted(six.iteritems(user._info)))
コード例 #23
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )

        if parsed_args.password:
            identity_client.users.update_password(
                user.id,
                parsed_args.password,
            )

        if parsed_args.project:
            project = utils.find_resource(
                identity_client.tenants,
                parsed_args.project,
            )
            identity_client.users.update_tenant(
                user.id,
                project.id,
            )

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #24
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        if parsed_args.password_prompt:
            parsed_args.password = utils.get_password(self.app.stdin)

        user = utils.find_resource(
            identity_client.users,
            parsed_args.user,
        )

        if parsed_args.password:
            identity_client.users.update_password(
                user.id,
                parsed_args.password,
            )

        if parsed_args.project:
            project = utils.find_resource(
                identity_client.tenants,
                parsed_args.project,
            )
            identity_client.users.update_tenant(
                user.id,
                project.id,
            )

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.email:
            kwargs['email'] = parsed_args.email
        kwargs['enabled'] = user.enabled
        if parsed_args.enable:
            kwargs['enabled'] = True
        if parsed_args.disable:
            kwargs['enabled'] = False

        identity_client.users.update(user.id, **kwargs)
コード例 #25
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity
        image_client = self.app.client_manager.image

        for deadopt in self.deadopts:
            if getattr(parsed_args, deadopt.replace('-', '_'), None):
                raise exceptions.CommandError(
                    _("ERROR: --%s was given, which is an Image v1 option"
                      " that is no longer supported in Image v2") % deadopt)

        # Build an attribute dict from the parsed args, only include
        # attributes that were actually set on the command line
        kwargs = {}
        copy_attrs = ('name', 'id', 'container_format', 'disk_format',
                      'min_disk', 'min_ram', 'tags', 'visibility')
        for attr in copy_attrs:
            if attr in parsed_args:
                val = getattr(parsed_args, attr, None)
                if val:
                    # Only include a value in kwargs for attributes that
                    # are actually present on the command line
                    kwargs[attr] = val

        # properties should get flattened into the general kwargs
        if getattr(parsed_args, 'properties', None):
            for k, v in six.iteritems(parsed_args.properties):
                kwargs[k] = str(v)

        # Handle exclusive booleans with care
        # Avoid including attributes in kwargs if an option is not
        # present on the command line.  These exclusive booleans are not
        # a single value for the pair of options because the default must be
        # to do nothing when no options are present as opposed to always
        # setting a default.
        if parsed_args.protected:
            kwargs['protected'] = True
        if parsed_args.unprotected:
            kwargs['protected'] = False
        if parsed_args.public:
            kwargs['visibility'] = 'public'
        if parsed_args.private:
            kwargs['visibility'] = 'private'
        if parsed_args.community:
            kwargs['visibility'] = 'community'
        if parsed_args.shared:
            kwargs['visibility'] = 'shared'
        # Handle deprecated --owner option
        project_arg = parsed_args.project
        if parsed_args.owner:
            project_arg = parsed_args.owner
            LOG.warning(
                _('The --owner option is deprecated, '
                  'please use --project instead.'))
        if project_arg:
            kwargs['owner'] = common.find_project(
                identity_client,
                project_arg,
                parsed_args.project_domain,
            ).id

        # open the file first to ensure any failures are handled before the
        # image is created
        fp = gc_utils.get_data_file(parsed_args)
        info = {}
        if fp is not None and parsed_args.volume:
            raise exceptions.CommandError(
                _("Uploading data and using "
                  "container are not allowed at "
                  "the same time"))

        if fp is None and parsed_args.file:
            LOG.warning(_("Failed to get an image file."))
            return {}, {}

        if parsed_args.owner:
            kwargs['owner'] = common.find_project(
                identity_client,
                parsed_args.owner,
                parsed_args.project_domain,
            ).id

        # sign an image using a given local private key file
        if parsed_args.sign_key_path or parsed_args.sign_cert_id:
            if not parsed_args.file:
                msg = (_("signing an image requires the --file option, "
                         "passing files via stdin when signing is not "
                         "supported."))
                raise exceptions.CommandError(msg)
            if (len(parsed_args.sign_key_path) < 1
                    or len(parsed_args.sign_cert_id) < 1):
                msg = (_("'sign-key-path' and 'sign-cert-id' must both be "
                         "specified when attempting to sign an image."))
                raise exceptions.CommandError(msg)
            else:
                sign_key_path = parsed_args.sign_key_path
                sign_cert_id = parsed_args.sign_cert_id
                signer = image_signer.ImageSigner()
                try:
                    pw = utils.get_password(
                        self.app.stdin,
                        prompt=("Please enter private key password, leave "
                                "empty if none: "),
                        confirm=False)
                    if not pw or len(pw) < 1:
                        pw = None
                    signer.load_private_key(sign_key_path, password=pw)
                except Exception:
                    msg = (_("Error during sign operation: private key could "
                             "not be loaded."))
                    raise exceptions.CommandError(msg)

                signature = signer.generate_signature(fp)
                signature_b64 = b64encode(signature)
                kwargs['img_signature'] = signature_b64
                kwargs['img_signature_certificate_uuid'] = sign_cert_id
                kwargs['img_signature_hash_method'] = signer.hash_method
                if signer.padding_method:
                    kwargs['img_signature_key_type'] = signer.padding_method

        # If a volume is specified.
        if parsed_args.volume:
            volume_client = self.app.client_manager.volume
            source_volume = utils.find_resource(
                volume_client.volumes,
                parsed_args.volume,
            )
            response, body = volume_client.volumes.upload_to_image(
                source_volume.id,
                parsed_args.force,
                parsed_args.name,
                parsed_args.container_format,
                parsed_args.disk_format,
            )
            info = body['os-volume_upload_image']
            try:
                info['volume_type'] = info['volume_type']['name']
            except TypeError:
                info['volume_type'] = None
        else:
            image = image_client.images.create(**kwargs)

        if fp is not None:
            with fp:
                try:
                    image_client.images.upload(image.id, fp)
                except Exception:
                    # If the upload fails for some reason attempt to remove the
                    # dangling queued image made by the create() call above but
                    # only if the user did not specify an id which indicates
                    # the Image already exists and should be left alone.
                    try:
                        if 'id' not in kwargs:
                            image_client.images.delete(image.id)
                    except Exception:
                        pass  # we don't care about this one
                    raise  # now, throw the upload exception again

                # update the image after the data has been uploaded
                image = image_client.images.get(image.id)

        if not info:
            info = _format_image(image)

        return zip(*sorted(six.iteritems(info)))
コード例 #26
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity
        image_client = self.app.client_manager.image

        for deadopt in self.deadopts:
            if getattr(parsed_args, deadopt.replace('-', '_'), None):
                raise exceptions.CommandError(
                    _("ERROR: --%s was given, which is an Image v1 option"
                      " that is no longer supported in Image v2") % deadopt)

        # Build an attribute dict from the parsed args, only include
        # attributes that were actually set on the command line
        kwargs = {}
        copy_attrs = ('name', 'id',
                      'container_format', 'disk_format',
                      'min_disk', 'min_ram', 'tags', 'visibility')
        for attr in copy_attrs:
            if attr in parsed_args:
                val = getattr(parsed_args, attr, None)
                if val:
                    # Only include a value in kwargs for attributes that
                    # are actually present on the command line
                    kwargs[attr] = val

        # properties should get flattened into the general kwargs
        if getattr(parsed_args, 'properties', None):
            for k, v in six.iteritems(parsed_args.properties):
                kwargs[k] = str(v)

        # Handle exclusive booleans with care
        # Avoid including attributes in kwargs if an option is not
        # present on the command line.  These exclusive booleans are not
        # a single value for the pair of options because the default must be
        # to do nothing when no options are present as opposed to always
        # setting a default.
        if parsed_args.protected:
            kwargs['protected'] = True
        if parsed_args.unprotected:
            kwargs['protected'] = False
        if parsed_args.public:
            kwargs['visibility'] = 'public'
        if parsed_args.private:
            kwargs['visibility'] = 'private'
        if parsed_args.community:
            kwargs['visibility'] = 'community'
        if parsed_args.shared:
            kwargs['visibility'] = 'shared'
        # Handle deprecated --owner option
        project_arg = parsed_args.project
        if parsed_args.owner:
            project_arg = parsed_args.owner
            LOG.warning(_('The --owner option is deprecated, '
                          'please use --project instead.'))
        if project_arg:
            kwargs['owner'] = common.find_project(
                identity_client,
                project_arg,
                parsed_args.project_domain,
            ).id

        # open the file first to ensure any failures are handled before the
        # image is created
        fp = gc_utils.get_data_file(parsed_args)
        info = {}
        if fp is not None and parsed_args.volume:
            raise exceptions.CommandError(_("Uploading data and using "
                                            "container are not allowed at "
                                            "the same time"))

        if fp is None and parsed_args.file:
            LOG.warning(_("Failed to get an image file."))
            return {}, {}

        if parsed_args.owner:
            kwargs['owner'] = common.find_project(
                identity_client,
                parsed_args.owner,
                parsed_args.project_domain,
            ).id

        # sign an image using a given local private key file
        if parsed_args.sign_key_path or parsed_args.sign_cert_id:
            if not parsed_args.file:
                msg = (_("signing an image requires the --file option, "
                         "passing files via stdin when signing is not "
                         "supported."))
                raise exceptions.CommandError(msg)
            if (len(parsed_args.sign_key_path) < 1 or
                    len(parsed_args.sign_cert_id) < 1):
                msg = (_("'sign-key-path' and 'sign-cert-id' must both be "
                         "specified when attempting to sign an image."))
                raise exceptions.CommandError(msg)
            else:
                sign_key_path = parsed_args.sign_key_path
                sign_cert_id = parsed_args.sign_cert_id
                signer = image_signer.ImageSigner()
                try:
                    pw = utils.get_password(
                        self.app.stdin,
                        prompt=("Please enter private key password, leave "
                                "empty if none: "),
                        confirm=False)
                    if not pw or len(pw) < 1:
                        pw = None
                    signer.load_private_key(
                        sign_key_path,
                        password=pw)
                except Exception:
                    msg = (_("Error during sign operation: private key could "
                             "not be loaded."))
                    raise exceptions.CommandError(msg)

                signature = signer.generate_signature(fp)
                signature_b64 = b64encode(signature)
                kwargs['img_signature'] = signature_b64
                kwargs['img_signature_certificate_uuid'] = sign_cert_id
                kwargs['img_signature_hash_method'] = signer.hash_method
                if signer.padding_method:
                    kwargs['img_signature_key_type'] = signer.padding_method

        # If a volume is specified.
        if parsed_args.volume:
            volume_client = self.app.client_manager.volume
            source_volume = utils.find_resource(
                volume_client.volumes,
                parsed_args.volume,
            )
            response, body = volume_client.volumes.upload_to_image(
                source_volume.id,
                parsed_args.force,
                parsed_args.name,
                parsed_args.container_format,
                parsed_args.disk_format,
            )
            info = body['os-volume_upload_image']
            try:
                info['volume_type'] = info['volume_type']['name']
            except TypeError:
                info['volume_type'] = None
        else:
            image = image_client.images.create(**kwargs)

        if fp is not None:
            with fp:
                try:
                    image_client.images.upload(image.id, fp)
                except Exception:
                    # If the upload fails for some reason attempt to remove the
                    # dangling queued image made by the create() call above but
                    # only if the user did not specify an id which indicates
                    # the Image already exists and should be left alone.
                    try:
                        if 'id' not in kwargs:
                            image_client.images.delete(image.id)
                    except Exception:
                        pass  # we don't care about this one
                    raise  # now, throw the upload exception again

                # update the image after the data has been uploaded
                image = image_client.images.get(image.id)

        if not info:
            info = _format_image(image)

        return zip(*sorted(six.iteritems(info)))
コード例 #27
0
ファイル: job_binaries.py プロジェクト: numvc/LuxoftBot
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        client = self.app.client_manager.data_processing

        if parsed_args.json:
            blob = osc_utils.read_blob_file_contents(parsed_args.json)
            try:
                template = jsonutils.loads(blob)
            except ValueError as e:
                raise exceptions.CommandError('An error occurred when reading '
                                              'template from file %s: %s' %
                                              (parsed_args.json, e))
            data = client.job_binaries.create(**template).to_dict()
        else:
            if parsed_args.password_prompt:
                parsed_args.password = osc_utils.get_password(self.app.stdin,
                                                              confirm=False)

            if parsed_args.secret_key_prompt:
                parsed_args.secret_key = osc_utils.get_password(self.app.stdin,
                                                                confirm=False)

            if not parsed_args.password:
                parsed_args.password = parsed_args.secret_key

            if not parsed_args.username:
                parsed_args.username = parsed_args.access_key

            if parsed_args.password and not parsed_args.username:
                raise exceptions.CommandError(
                    'Username via --username, or S3 access key via '
                    '--access-key should be provided with password')

            if parsed_args.username and not parsed_args.password:
                raise exceptions.CommandError(
                    'Password should be provided via --password or '
                    '--secret-key, or entered interactively with '
                    '--password-prompt or --secret-key-prompt')

            if parsed_args.password and parsed_args.username:
                if not parsed_args.url:
                    raise exceptions.CommandError(
                        'URL must be provided via --url')
                if parsed_args.url.startswith('s3'):
                    if not parsed_args.s3_endpoint:
                        raise exceptions.CommandError(
                            'S3 job binaries need an endpoint provided via '
                            '--s3-endpoint')
                    extra = {
                        'accesskey': parsed_args.username,
                        'secretkey': parsed_args.password,
                        'endpoint': parsed_args.s3_endpoint,
                    }

                else:
                    extra = {
                        'user': parsed_args.username,
                        'password': parsed_args.password
                    }
            else:
                extra = None

            data = client.job_binaries.create(
                name=parsed_args.name,
                url=parsed_args.url,
                description=parsed_args.description,
                extra=extra,
                is_public=parsed_args.public,
                is_protected=parsed_args.protected).to_dict()

        data = utils.prepare_data(data, jb_v1.JOB_BINARY_FIELDS)

        return self.dict2columns(data)
コード例 #28
0
 def test_get_password_good(self):
     with mock.patch("getpass.getpass", return_value=PASSWORD):
         mock_stdin = mock.Mock()
         mock_stdin.isatty = mock.Mock()
         mock_stdin.isatty.return_value = True
         self.assertEqual(PASSWORD, utils.get_password(mock_stdin))
コード例 #29
0
ファイル: test_utils.py プロジェクト: dtroyer/osc-lib
 def test_get_password_good(self):
     with mock.patch("getpass.getpass", return_value=PASSWORD):
         mock_stdin = mock.Mock()
         mock_stdin.isatty = mock.Mock()
         mock_stdin.isatty.return_value = True
         self.assertEqual(PASSWORD, utils.get_password(mock_stdin))
コード例 #30
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        client = self.app.client_manager.data_processing

        if parsed_args.json:
            blob = osc_utils.read_blob_file_contents(parsed_args.json)
            try:
                template = jsonutils.loads(blob)
            except ValueError as e:
                raise exceptions.CommandError(
                    'An error occurred when reading '
                    'template from file %s: %s' % (parsed_args.json, e))
            data = client.job_binaries.create(**template).to_dict()
        else:
            if parsed_args.password_prompt:
                parsed_args.password = osc_utils.get_password(
                    self.app.stdin, confirm=False)

            if parsed_args.secret_key_prompt:
                parsed_args.secret_key = osc_utils.get_password(
                    self.app.stdin, confirm=False)

            if not parsed_args.password:
                parsed_args.password = parsed_args.secret_key

            if not parsed_args.username:
                parsed_args.username = parsed_args.access_key

            if parsed_args.password and not parsed_args.username:
                raise exceptions.CommandError(
                    'Username via --username, or S3 access key via '
                    '--access-key should be provided with password')

            if parsed_args.username and not parsed_args.password:
                raise exceptions.CommandError(
                    'Password should be provided via --password or '
                    '--secret-key, or entered interactively with '
                    '--password-prompt or --secret-key-prompt')

            if parsed_args.password and parsed_args.username:
                if not parsed_args.url:
                    raise exceptions.CommandError(
                        'URL must be provided via --url')
                if parsed_args.url.startswith('s3'):
                    if not parsed_args.s3_endpoint:
                        raise exceptions.CommandError(
                            'S3 job binaries need an endpoint provided via '
                            '--s3-endpoint')
                    extra = {
                        'accesskey': parsed_args.username,
                        'secretkey': parsed_args.password,
                        'endpoint': parsed_args.s3_endpoint,
                    }

                else:
                    extra = {
                        'user': parsed_args.username,
                        'password': parsed_args.password
                    }
            else:
                extra = None

            data = client.job_binaries.create(
                name=parsed_args.name, url=parsed_args.url,
                description=parsed_args.description, extra=extra,
                is_public=parsed_args.public,
                is_protected=parsed_args.protected).to_dict()

        data = utils.prepare_data(data, jb_v1.JOB_BINARY_FIELDS)

        return self.dict2columns(data)
コード例 #31
0
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity
        image_client = self.app.client_manager.image

        for deadopt in self.deadopts:
            if getattr(parsed_args, deadopt.replace('-', '_'), None):
                raise exceptions.CommandError(
                    _("ERROR: --%s was given, which is an Image v1 option"
                      " that is no longer supported in Image v2") % deadopt)

        # Build an attribute dict from the parsed args, only include
        # attributes that were actually set on the command line
        kwargs = {}
        copy_attrs = ('name', 'id',
                      'container_format', 'disk_format',
                      'min_disk', 'min_ram', 'tags', 'visibility')
        for attr in copy_attrs:
            if attr in parsed_args:
                val = getattr(parsed_args, attr, None)
                if val:
                    # Only include a value in kwargs for attributes that
                    # are actually present on the command line
                    kwargs[attr] = val

        # properties should get flattened into the general kwargs
        if getattr(parsed_args, 'properties', None):
            for k, v in parsed_args.properties.items():
                kwargs[k] = str(v)

        # Handle exclusive booleans with care
        # Avoid including attributes in kwargs if an option is not
        # present on the command line.  These exclusive booleans are not
        # a single value for the pair of options because the default must be
        # to do nothing when no options are present as opposed to always
        # setting a default.
        if parsed_args.protected:
            kwargs['is_protected'] = True
        if parsed_args.unprotected:
            kwargs['is_protected'] = False
        if parsed_args.public:
            kwargs['visibility'] = 'public'
        if parsed_args.private:
            kwargs['visibility'] = 'private'
        if parsed_args.community:
            kwargs['visibility'] = 'community'
        if parsed_args.shared:
            kwargs['visibility'] = 'shared'
        if parsed_args.project:
            kwargs['owner_id'] = common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id

        if parsed_args.use_import:
            kwargs['use_import'] = True

        # open the file first to ensure any failures are handled before the
        # image is created. Get the file name (if it is file, and not stdin)
        # for easier further handling.
        (fp, fname) = get_data_file(parsed_args)
        info = {}

        if fp is not None and parsed_args.volume:
            raise exceptions.CommandError(_("Uploading data and using "
                                            "container are not allowed at "
                                            "the same time"))
        if fp is None and parsed_args.file:
            LOG.warning(_("Failed to get an image file."))
            return {}, {}
        elif fname:
            kwargs['filename'] = fname
        elif fp:
            kwargs['validate_checksum'] = False
            kwargs['data'] = fp

        # sign an image using a given local private key file
        if parsed_args.sign_key_path or parsed_args.sign_cert_id:
            if not parsed_args.file:
                msg = (_("signing an image requires the --file option, "
                         "passing files via stdin when signing is not "
                         "supported."))
                raise exceptions.CommandError(msg)
            if (len(parsed_args.sign_key_path) < 1 or
                    len(parsed_args.sign_cert_id) < 1):
                msg = (_("'sign-key-path' and 'sign-cert-id' must both be "
                         "specified when attempting to sign an image."))
                raise exceptions.CommandError(msg)
            else:
                sign_key_path = parsed_args.sign_key_path
                sign_cert_id = parsed_args.sign_cert_id
                signer = image_signer.ImageSigner()
                try:
                    pw = utils.get_password(
                        self.app.stdin,
                        prompt=("Please enter private key password, leave "
                                "empty if none: "),
                        confirm=False)

                    if not pw or len(pw) < 1:
                        pw = None
                    else:
                        # load_private_key() requires the password to be
                        # passed as bytes
                        pw = pw.encode()

                    signer.load_private_key(
                        sign_key_path,
                        password=pw)
                except Exception:
                    msg = (_("Error during sign operation: private key "
                             "could not be loaded."))
                    raise exceptions.CommandError(msg)

                signature = signer.generate_signature(fp)
                signature_b64 = b64encode(signature)
                kwargs['img_signature'] = signature_b64
                kwargs['img_signature_certificate_uuid'] = sign_cert_id
                kwargs['img_signature_hash_method'] = signer.hash_method
                if signer.padding_method:
                    kwargs['img_signature_key_type'] = \
                        signer.padding_method

        # If a volume is specified.
        if parsed_args.volume:
            volume_client = self.app.client_manager.volume
            source_volume = utils.find_resource(
                volume_client.volumes,
                parsed_args.volume,
            )
            response, body = volume_client.volumes.upload_to_image(
                source_volume.id,
                parsed_args.force,
                parsed_args.name,
                parsed_args.container_format,
                parsed_args.disk_format,
            )
            info = body['os-volume_upload_image']
            try:
                info['volume_type'] = info['volume_type']['name']
            except TypeError:
                info['volume_type'] = None
        else:
            image = image_client.create_image(**kwargs)

        if not info:
            info = _format_image(image)

        return zip(*sorted(info.items()))