Recognise usernames in --account args (or similar)
authorStavros Sachtouris <saxtouri@admin.grnet.gr>
Wed, 5 Feb 2014 13:16:05 +0000 (15:16 +0200)
committerStavros Sachtouris <saxtouri@admin.grnet.gr>
Wed, 5 Feb 2014 13:16:05 +0000 (15:16 +0200)
Refs: #4810

Arguments --account and --to-account can now accept usernames along with uuids
Kamaki attempts to recognise the argument as a uuid. In case of failure, it
attempts to recognise it as a username. If it fails again, it produces and
error.

Also, restore kamaki file publish/unpublish

docs/examplesdir/imageregister.rst
docs/examplesdir/sharing.rst
kamaki/cli/argument/__init__.py
kamaki/cli/commands/image.py
kamaki/cli/commands/pithos.py

index e94444c..6278677 100644 (file)
@@ -303,12 +303,13 @@ A look at the image metadata reveals that the name is changed:
 
 We can use the same idea to change the values of other metadata like disk
 format, container format or status. On the other hand, we cannot modify the
-id, owner, location, checksum and dates. e.g., to publish and unpublish:
+id, owner, location, checksum and dates. e.g., to make an image public or
+private:
 
 .. code-block:: console
 
-    kamaki image modify 7h1rd-1m4g3-1d --publish --name='Debian Base Gama'
-    kamaki image modify 7h1rd-1m4g3-1d --unpublish
+    kamaki image modify 7h1rd-1m4g3-1d --public --name='Debian Base Gama'
+    kamaki image modify 7h1rd-1m4g3-1d --private
 
 The first call publishes the image (set is-public to True) and also restores
 the name to "Debian Base Gama". The second one unpublishes the image (set
index 2e80832..9de1ac9 100644 (file)
@@ -55,8 +55,8 @@ Unpublish info.txt, publish file2upload.txt
 
 .. code-block:: console
 
-    $ kamaki file modify /pithos/info.txt --unpublish
-    $ kamaki file modify /pithos/file2upload.txt --publish
+    $ kamaki file unpublish /pithos/info.txt
+    $ kamaki file publish /pithos/file2upload.txt
     https://example.com/pithos/public/43gdL2df02ld3
 
 Modify permissions
index a374eee..471a392 100644 (file)
@@ -313,6 +313,30 @@ class DataSizeArgument(ValueArgument):
             self._value = self._calculate_limit(new_value)
 
 
+class UserAccountArgument(ValueArgument):
+    """A user UUID or name (if uuid does not exist)"""
+
+    account_client = None
+
+    @property
+    def value(self):
+        return super(UserAccountArgument, self).value
+
+    @value.setter
+    def value(self, uuid_or_name):
+        if uuid_or_name and self.account_client:
+            r = self.account_client.uuids2usernames([uuid_or_name, ])
+            if r:
+                self._value = uuid_or_name
+            else:
+                r = self.account_client.usernames2uuids([uuid_or_name])
+                self._value = r.get(uuid_or_name) if r else None
+            if not self._value:
+                raise raiseCLIError('User name or UUID not found', details=[
+                    '%s is not a known username or UUID' % uuid_or_name,
+                    'Usage:  %s <USER_UUID | USERNAME>' % self.lvalue])
+
+
 class DateArgument(ValueArgument):
 
     DATE_FORMAT = '%a %b %d %H:%M:%S %Y'
index 6ea5864..a583f9c 100644 (file)
@@ -326,8 +326,8 @@ class image_modify(_init_image, _optional_output_cmd):
         container_format=ValueArgument(
             'Change container format', '--container-format'),
         status=ValueArgument('Change status', '--status'),
-        publish=FlagArgument('Publish the image', '--public'),
-        unpublish=FlagArgument('Unpublish the image', '--private'),
+        publish=FlagArgument('Make the image public', '--public'),
+        unpublish=FlagArgument('Make the image private', '--private'),
         property_to_set=KeyValueArgument(
             'set property in key=value form (can be repeated)',
             ('-p', '--property-set')),
index f5652ef..2abe0b9 100644 (file)
@@ -48,7 +48,8 @@ from kamaki.cli.errors import (
     CLISyntaxError)
 from kamaki.cli.argument import (
     FlagArgument, IntArgument, ValueArgument, DateArgument, KeyValueArgument,
-    ProgressBarArgument, RepeatableArgument, DataSizeArgument)
+    ProgressBarArgument, RepeatableArgument, DataSizeArgument,
+    UserAccountArgument)
 from kamaki.cli.utils import (
     format_size, bold, get_path_size, guess_mime_type)
 
@@ -119,8 +120,9 @@ class _pithos_account(_pithos_init):
 
     def __init__(self, arguments={}, auth_base=None, cloud=None):
         super(_pithos_account, self).__init__(arguments, auth_base, cloud)
-        self['account'] = ValueArgument(
-            'Use (a different) user uuid', ('-A', '--account'))
+        self['account'] = UserAccountArgument(
+            'A user UUID or name', ('-A', '--account'))
+        self.arguments['account'].account_client = auth_base
 
     def print_objects(self, object_list):
         for index, obj in enumerate(object_list):
@@ -329,10 +331,6 @@ class file_modify(_pithos_container):
     """Modify the attributes of a file or directory object"""
 
     arguments = dict(
-        publish=FlagArgument(
-            'Make an object public (returns the public URL)', '--publish'),
-        unpublish=FlagArgument(
-            'Make an object unpublic', '--unpublish'),
         uuid_for_read_permission=RepeatableArgument(
             'Give read access to user/group (can be repeated, accumulative). '
             'Format for users: UUID . Format for groups: UUID:GROUP . '
@@ -349,7 +347,7 @@ class file_modify(_pithos_container):
             'Delete object metadata (can be repeated)', '--metadata-del'),
     )
     required = [
-        'publish', 'unpublish', 'uuid_for_read_permission', 'metadata_to_set',
+        'uuid_for_read_permission', 'metadata_to_set',
         'uuid_for_write_permission', 'no_permissions',
         'metadata_key_to_delete']
 
@@ -358,10 +356,6 @@ class file_modify(_pithos_container):
     @errors.pithos.container
     @errors.pithos.object_path
     def _run(self):
-        if self['publish']:
-            self.writeln(self.client.publish_object(self.path))
-        if self['unpublish']:
-            self.client.unpublish_object(self.path)
         if self['uuid_for_read_permission'] or self[
                 'uuid_for_write_permission']:
             perms = self.client.get_object_sharing(self.path)
@@ -398,6 +392,38 @@ class file_modify(_pithos_container):
         self._run()
 
 
+@command(file_cmds)
+class file_publish(_pithos_container):
+    """Publish an object (creates a public URL)"""
+
+    @errors.generic.all
+    @errors.pithos.connection
+    @errors.pithos.container
+    @errors.pithos.object_path
+    def _run(self):
+        self.writeln(self.client.publish_object(self.path))
+
+    def main(self, path_or_url):
+        super(self.__class__, self)._run(path_or_url)
+        self._run()
+
+
+@command(file_cmds)
+class file_unpublish(_pithos_container):
+    """Unpublish an object"""
+
+    @errors.generic.all
+    @errors.pithos.connection
+    @errors.pithos.container
+    @errors.pithos.object_path
+    def _run(self):
+        self.client.unpublish_object(self.path)
+
+    def main(self, path_or_url):
+        super(self.__class__, self)._run(path_or_url)
+        self._run()
+
+
 def _assert_path(self, path_or_url):
     if not self.path:
         raiseCLIError(
@@ -488,8 +514,8 @@ class file_delete(_pithos_container):
 class _source_destination(_pithos_container, _optional_output_cmd):
 
     sd_arguments = dict(
-        destination_user_uuid=ValueArgument(
-            'default: current user uuid', '--to-account'),
+        destination_user=UserAccountArgument(
+            'UUID or username, default: current user', '--to-account'),
         destination_container=ValueArgument(
             'default: pithos', '--to-container'),
         source_prefix=FlagArgument(
@@ -508,6 +534,7 @@ class _source_destination(_pithos_container, _optional_output_cmd):
         self.arguments.update(self.sd_arguments)
         super(_source_destination, self).__init__(
             self.arguments, auth_base, cloud)
+        self.arguments['destination_user'].account_client = self.auth_base
 
     def _report_transfer(self, src, dst, transfer_name):
         if not dst:
@@ -636,8 +663,7 @@ class _source_destination(_pithos_container, _optional_output_cmd):
             base_url=self.client.base_url, token=self.client.token,
             container=self[
                 'destination_container'] or dst_con or self.client.container,
-            account=self[
-                'destination_user_uuid'] or dst_acc or self.account)
+            account=self['destination_user'] or dst_acc or self.account)
         self.dst_path = dst_path or self.path
 
 
@@ -1640,10 +1666,13 @@ class sharer_info(_pithos_account, _optional_json):
     def _run(self):
         self._print(self.client.get_account_info(), self.print_dict)
 
-    def main(self, account_uuid=None):
+    def main(self, account_uuid_or_name=None):
         super(self.__class__, self)._run()
-        if account_uuid:
-            self.client.account, self.account = account_uuid, account_uuid
+        if account_uuid_or_name:
+            arg = UserAccountArgument('Check', ' ')
+            arg.account_client = self.auth_base
+            arg.value = account_uuid_or_name
+            self.client.account, self.account = arg.value, arg.value
         self._run()
 
 
@@ -1721,25 +1750,3 @@ class group_delete(_pithos_group, _optional_json):
     def main(self, groupname):
         super(self.__class__, self)._run()
         self._run(groupname)
-
-
-#  Deprecated commands
-
-@command(file_cmds)
-class file_publish(_pithos_init):
-    """DEPRECATED, replaced by [kamaki] file modify OBJECT --publish"""
-
-    def main(self, *args):
-        raise CLISyntaxError('DEPRECATED', details=[
-            'This command is replaced by:',
-            '  [kamaki] file modify OBJECT --publish'])
-
-
-@command(file_cmds)
-class file_unpublish(_pithos_init):
-    """DEPRECATED, replaced by [kamaki] file modify OBJECT --unpublish"""
-
-    def main(self, *args):
-        raise CLISyntaxError('DEPRECATED', details=[
-            'This command is replaced by:',
-            '  [kamaki] file modify OBJECT --unpublish'])