Example #1
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.load_config()

        self.account = AzureAccount(self.config)

        container_name = self.account.storage_container()

        self.storage = Storage(self.account, container_name)

        # default to 1 minute ago (skew around 'now')
        if self.command_args['--start-datetime'] == 'now':
            start = datetime.datetime.utcnow() - datetime.timedelta(minutes=1)
        else:
            start = self.validate_date('--start-datetime')

        # default to 30 days from now
        if self.command_args['--expiry-datetime'] == '30 days from start':
            expiry = start + datetime.timedelta(days=30)
        else:
            expiry = self.validate_date('--expiry-datetime')

        self.validate_sas_permissions('--permissions')

        if self.command_args['upload']:
            self.__upload()
        elif self.command_args['delete']:
            self.__delete()
        elif self.command_args['sas']:
            self.__sas(container_name, start, expiry,
                       self.command_args['--permissions'])
Example #2
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)

        self.image = Image(self.account)
        if self.command_args['list']:
            self.__list()
        if self.command_args['show']:
            self.__show()
        elif self.command_args['create']:
            self.__create()
        elif self.command_args['delete']:
            self.__delete()
        elif self.command_args['replicate']:
            self.__replicate()
        elif self.command_args['replication-status']:
            self.__replication_status(self.command_args['--name'])
        elif self.command_args['unreplicate']:
            self.__unreplicate()
        elif self.command_args['publish']:
            self.__publish()
        elif self.command_args['update']:
            self.__update()
Example #3
0
class ComputeRequestTask(CliTask):
    """
        Process request status
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)

        request_id = format(self.command_args['--id'])

        if self.command_args['status']:
            self.result.add('request:' + request_id,
                            self.request_status(request_id))
            self.out.display()
        elif self.command_args['wait']:
            self.request_wait(request_id)

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::compute::request')
        else:
            return False
        return self.manual
Example #4
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        if self.command_args['list']:
            self.__list()
        elif self.command_args['default'] and not self.command_args['region']:
            self.__default()
        else:
            self.__load_account_setup(
                self.command_args['--name']
            )
            if self.command_args['remove']:
                self.__remove()
            elif self.command_args['configure']:
                self.__configure_account()
            elif self.command_args['region'] and self.command_args['add']:
                self.__region_add()
            elif self.command_args['region'] and self.command_args['default']:
                self.__set_region_default()
Example #5
0
    def __init__(self):
        from azurectl.logger import log

        self.cli = Cli()

        # account setup done in command implementation
        self.account = None

        # show main help man page if requested
        if self.cli.show_help():
            manual = Help()
            manual.show('azurectl')
            sys.exit(0)

        # load/import task module
        self.task = self.cli.load_command()

        # get command specific args
        self.command_args = self.cli.get_command_args()

        # get global args
        self.global_args = self.cli.get_global_args()

        # set log level
        if self.global_args['--debug']:
            log.setLevel(logging.DEBUG)
Example #6
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)
        self.endpoint = Endpoint(self.account)
        self.endpoint.set_instance(
            self.command_args['--cloud-service-name'],
            (self.command_args['--instance-name']
             or self.command_args['--cloud-service-name']))

        if self.command_args['list']:
            self.__list()
        if self.command_args['show']:
            self.__show()
        if self.command_args['create']:
            self.__create()
        if self.command_args['update']:
            self.__update()
        if self.command_args['delete']:
            self.__delete()
Example #7
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)
        self.data_disk = DataDisk(self.account)

        if self.command_args['create']:
            self.__create()
        if self.command_args['delete']:
            self.__delete()
        if self.command_args['attach']:
            self.__attach()
        if self.command_args['detach']:
            self.__detach()
        if self.command_args['attached']:
            if self.command_args['show']:
                self.__show_attached()
        else:
            if self.command_args['list']:
                self.__list()
            if self.command_args['show']:
                self.__show()
Example #8
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)
        self.reserved_ip = ReservedIp(self.account)

        if self.command_args['list']:
            self.__list()
        if self.command_args['show']:
            self.__show()
        if self.command_args['create']:
            self.__create()
        if self.command_args['delete']:
            self.__delete()
        if self.command_args['associate']:
            self.__associate()
        if self.command_args['disassociate']:
            self.__disassociate()
Example #9
0
class TestHelp:
    def setup(self):
        self.help = Help()

    def test_show(self):
        with raises(AzureHelpNoCommandGiven):
            self.help.show(None)

    @patch('subprocess.call')
    def test_show_command(self, mock_process):
        self.help.show('foo')
        mock_process.assert_called_once_with('man foo', shell=True)
Example #10
0
class StorageShareTask(CliTask):
    """
        Process file share commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)

        self.fileshare = FileShare(self.account)

        if self.command_args['list']:
            self.__share_list()
        elif self.command_args['create']:
            self.__share_create()
        elif self.command_args['delete']:
            self.__share_delete()

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::storage::share')
        else:
            return False
        return self.manual

    def __share_list(self):
        self.result.add('share_names', self.fileshare.list())
        self.out.display()

    def __share_create(self):
        share_name = self.command_args['--name']
        self.fileshare.create(share_name)
        log.info('Created Files Share %s', share_name)

    def __share_delete(self):
        share_name = self.command_args['--name']
        self.fileshare.delete(share_name)
        log.info('Deleted Files Share %s', share_name)
Example #11
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)

        # default to 1 minute ago (skew around 'now')
        if self.command_args['--start-datetime'] == 'now':
            start = datetime.datetime.utcnow() - datetime.timedelta(minutes=1)
        else:
            start = self.validate_date('--start-datetime')

        # default to 30 days from now
        if self.command_args['--expiry-datetime'] == '30 days from start':
            expiry = start + datetime.timedelta(days=30)
        else:
            expiry = self.validate_date('--expiry-datetime')

        self.validate_sas_permissions('--permissions')

        self.container = Container(self.account)

        if self.command_args['list']:
            self.__container_list()
        elif self.command_args['show']:
            self.__container_content()
        elif self.command_args['create']:
            self.__container_create()
        elif self.command_args['delete']:
            self.__container_delete()
        elif self.command_args['sas']:
            self.__container_sas(
                start, expiry, self.command_args['--permissions']
            )
Example #12
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)

        request_id = format(self.command_args['--id'])

        if self.command_args['status']:
            self.result.add('request:' + request_id,
                            self.request_status(request_id))
            self.out.display()
        elif self.command_args['wait']:
            self.request_wait(request_id)
Example #13
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)

        if self.command_args['types']:
            self.__list_instance_types()
        elif self.command_args['regions']:
            self.__list_locations()
        elif self.command_args['show']:
            self.cloud_service = CloudService(self.account)
            self.__show_cloud_service_properties()
        else:
            self.vm = VirtualMachine(self.account)
            self.cloud_service = CloudService(self.account)
            if self.command_args['create']:
                self.__create_cloud_service()
                self.__create_instance()
            elif self.command_args['delete']:
                if self.command_args['--instance-name']:
                    self.__delete_instance()
                else:
                    self.__delete_cloud_service()
            elif self.command_args['reboot']:
                self.__reboot_instance()
            elif self.command_args['shutdown']:
                self.__shutdown_instance()
            elif self.command_args['start']:
                self.__start_instance()
            elif self.command_args['status']:
                self.__operate_on_instance_state()
Example #14
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)
        self.storage_account = StorageAccount(self.account)

        if self.command_args['--name']:
            self.validate_account_name()
        if self.command_args['--description']:
            self.validate_description()
        if self.command_args['--label']:
            self.validate_label()

        if self.command_args['create']:
            self.__create()
        elif self.command_args['update']:
            self.__update()
        elif self.command_args['show']:
            self.__show()
        elif self.command_args['list']:
            self.__list()
        elif self.command_args['delete']:
            self.__delete()
        elif self.command_args['regions']:
            self.__list_locations()
        self.out.display()
Example #15
0
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)

        self.fileshare = FileShare(self.account)

        if self.command_args['list']:
            self.__share_list()
        elif self.command_args['create']:
            self.__share_create()
        elif self.command_args['delete']:
            self.__share_delete()
Example #16
0
 def setup(self):
     self.help = Help()
Example #17
0
class StorageAccountTask(CliTask):
    """
        Process commands on storage accounts
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)
        self.storage_account = StorageAccount(self.account)

        if self.command_args['--name']:
            self.validate_account_name()
        if self.command_args['--description']:
            self.validate_description()
        if self.command_args['--label']:
            self.validate_label()

        if self.command_args['create']:
            self.__create()
        elif self.command_args['update']:
            self.__update()
        elif self.command_args['show']:
            self.__show()
        elif self.command_args['list']:
            self.__list()
        elif self.command_args['delete']:
            self.__delete()
        elif self.command_args['regions']:
            self.__list_locations()
        self.out.display()

    # argument validation
    def validate_account_name(self, cmd_arg='--name'):
        valid_chars = set(string.ascii_lowercase + string.digits)
        if (set(self.command_args[cmd_arg]) - valid_chars):
            raise AzureInvalidCommand(
                '%s contains invalid characters. ' % cmd_arg +
                'Only lowercase letters and digits are allowed.')
        self.validate_min_length(cmd_arg, 3)
        self.validate_max_length(cmd_arg, 24)

    def validate_description(self, cmd_arg='--description'):
        self.validate_max_length(cmd_arg, 1024)

    def validate_label(self, cmd_arg='--label'):
        self.validate_max_length(cmd_arg, 100)

    # tasks
    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::storage::account')
        else:
            return False
        return self.manual

    def __create(self):
        request_id = self.storage_account.create(
            self.command_args['--name'],
            self.command_args['--description'],
            self.command_args['--label'],
            Defaults.account_type_for_docopts(self.command_args)
        )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            'storage_account:' + self.command_args['--name'],
            request_id
        )

    def __update(self):
        request_id = self.storage_account.update(
            self.command_args['--name'],
            self.command_args['--description'],
            self.command_args['--label'],
            Defaults.account_type_for_docopts(self.command_args, False),
            self.command_args['--new-primary-key'],
            self.command_args['--new-secondary-key']
        )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            'storage_account:' + self.command_args['--name'],
            request_id
        )

    def __show(self):
        self.result.add(
            'storage_account:' + self.command_args['--name'],
            self.storage_account.show(self.command_args['--name'])
        )

    def __list(self):
        self.result.add('storage_accounts', self.storage_account.list())

    def __delete(self):
        request_id = self.storage_account.delete(
            self.command_args['--name']
        )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            'storage_account:' + self.command_args['--name'],
            request_id
        )

    def __list_locations(self):
        self.result.add('regions', self.account.locations('Storage'))
Example #18
0
class ComputeDataDiskTask(CliTask):
    """
        Process image commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)
        self.data_disk = DataDisk(self.account)

        if self.command_args['create']:
            self.__create()
        if self.command_args['delete']:
            self.__delete()
        if self.command_args['attach']:
            self.__attach()
        if self.command_args['detach']:
            self.__detach()
        if self.command_args['attached']:
            if self.command_args['show']:
                self.__show_attached()
        else:
            if self.command_args['list']:
                self.__list()
            if self.command_args['show']:
                self.__show()

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::compute::data_disk')
        else:
            return False
        return self.manual

    def __create(self):
        self.data_disk.create(self.command_args['--disk-basename'],
                              self.command_args['--size'],
                              self.command_args['--label'])
        log.info('Created new data disk %s',
                 self.data_disk.data_disk_name.replace('.vhd', ''))

    def __show(self):
        self.result.add('data-disk',
                        self.data_disk.show(self.command_args['--disk-name']))
        self.out.display()

    def __show_attached(self):
        request_params = [
            self.command_args['--cloud-service-name'],
            (self.command_args['--instance-name']
             or self.command_args['--cloud-service-name']),
            self.command_args['--lun'] or 'on_all_luns'
        ]
        self.result.add(
            'data-disk:%s:%s:%s' % tuple(request_params),
            self.data_disk.show_attached(
                self.command_args['--cloud-service-name'],
                self.command_args['--instance-name'],
                self.command_args['--lun']))
        self.out.display()

    def __delete(self):
        self.data_disk.delete(self.command_args['--disk-name'])
        log.info('Deleted data disk %s', self.command_args['--disk-name'])

    def __attach(self):
        self.validate_at_least_one_argument_is_set(
            ['--disk-name', '--blob-name'])
        optional_args = {}
        if self.command_args['--label']:
            optional_args['label'] = self.command_args['--label']
        if self.command_args['--lun']:
            optional_args['lun'] = int(self.command_args['--lun'])
        if self.command_args['--blob-name']:
            optional_args['blob_name'] = self.command_args['--blob-name']
        if (self.command_args['--no-cache']
                or self.command_args['--read-only-cache']
                or self.command_args['--read-write-cache']):
            optional_args['host_caching'] = Defaults.host_caching_for_docopts(
                self.command_args)
        request_id = self.data_disk.attach(
            self.command_args['--disk-name'],
            self.command_args['--cloud-service-name'],
            self.command_args['--instance-name'], **optional_args)
        request_params = [
            self.command_args['--cloud-service-name'],
            (self.command_args['--instance-name']
             or self.command_args['--cloud-service-name']),
            int(self.data_disk.attached_lun)
        ]
        self.result.add('data-disk attach:%s:%s:%d' % tuple(request_params),
                        request_id)
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.out.display()

    def __detach(self):
        request_params = [
            self.command_args['--cloud-service-name'],
            (self.command_args['--instance-name']
             or self.command_args['--cloud-service-name']),
            int(self.command_args['--lun'])
        ]
        request_id = self.result.add(
            'data-disk detach:%s:%s:%d' % tuple(request_params),
            self.data_disk.detach(int(self.command_args['--lun']),
                                  self.command_args['--cloud-service-name'],
                                  self.command_args['--instance-name']))
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.out.display()

    def __list(self):
        self.result.add('data-disks', self.data_disk.list())
        self.out.display()
Example #19
0
class ComputeEndpointTask(CliTask):
    """
        Process image commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)
        self.endpoint = Endpoint(self.account)
        self.endpoint.set_instance(
            self.command_args['--cloud-service-name'],
            (self.command_args['--instance-name']
             or self.command_args['--cloud-service-name']))

        if self.command_args['list']:
            self.__list()
        if self.command_args['show']:
            self.__show()
        if self.command_args['create']:
            self.__create()
        if self.command_args['update']:
            self.__update()
        if self.command_args['delete']:
            self.__delete()

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::compute::endpoint')
        else:
            return False
        return self.manual

    def __list(self):
        self.result.add('endpoints', self.endpoint.list())
        self.out.display()

    def __show(self):
        self.result.add('endpoint',
                        self.endpoint.show(self.command_args['--name']))
        self.out.display()

    def __create(self):
        request_id = self.endpoint.create(
            self.command_args['--name'], self.command_args['--port'],
            (self.command_args['--instance-port']
             or self.command_args['--port']),
            ('udp' if self.command_args['--udp'] else 'tcp'),
            (self.command_args['--idle-timeout'] or '4'))
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add('endpoint:' + self.command_args['--name'], request_id)
        self.out.display()

    def __update(self):
        if self.command_args['--udp']:
            protocol = 'udp'
        elif self.command_args['--tcp']:
            protocol = 'tcp'
        else:
            protocol = None

        request_id = self.endpoint.update(self.command_args['--name'],
                                          self.command_args['--port'],
                                          (self.command_args['--instance-port']
                                           or self.command_args['--port']),
                                          protocol,
                                          self.command_args['--idle-timeout'])
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add('endpoint:' + self.command_args['--name'], request_id)
        self.out.display()

    def __delete(self):
        request_id = self.endpoint.delete(self.command_args['--name'], )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add('endpoint:' + self.command_args['--name'], request_id)
        self.out.display()
Example #20
0
class StorageDiskTask(CliTask):
    """
        Process disk commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.load_config()

        self.account = AzureAccount(self.config)

        container_name = self.account.storage_container()

        self.storage = Storage(self.account, container_name)

        # default to 1 minute ago (skew around 'now')
        if self.command_args['--start-datetime'] == 'now':
            start = datetime.datetime.utcnow() - datetime.timedelta(minutes=1)
        else:
            start = self.validate_date('--start-datetime')

        # default to 30 days from now
        if self.command_args['--expiry-datetime'] == '30 days from start':
            expiry = start + datetime.timedelta(days=30)
        else:
            expiry = self.validate_date('--expiry-datetime')

        self.validate_sas_permissions('--permissions')

        if self.command_args['upload']:
            self.__upload()
        elif self.command_args['delete']:
            self.__delete()
        elif self.command_args['sas']:
            self.__sas(container_name, start, expiry,
                       self.command_args['--permissions'])

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::storage::disk')
        else:
            return False
        return self.manual

    def __upload(self):
        if self.command_args['--quiet']:
            self.__upload_no_progress()
        else:
            self.__upload_with_progress()

    def __upload_no_progress(self):
        try:
            self.__process_upload()
        except (KeyboardInterrupt):
            raise SystemExit('azurectl aborted by keyboard interrupt')

    def __upload_with_progress(self):
        image = self.command_args['--source']
        progress = BackgroundScheduler(timezone=utc)
        progress.add_job(self.storage.print_upload_status,
                         'interval',
                         seconds=3)
        progress.start()
        try:
            self.__process_upload()
            self.storage.print_upload_status()
            progress.shutdown()
        except (KeyboardInterrupt):
            progress.shutdown()
            raise SystemExit('azurectl aborted by keyboard interrupt')
        print()
        log.info('Uploaded %s', image)

    def __process_upload(self):
        self.storage.upload(self.command_args['--source'],
                            self.command_args['--blob-name'],
                            self.command_args['--max-chunk-size'])

    def __sas(self, container_name, start, expiry, permissions):
        result = DataCollector()
        out = DataOutput(result, self.global_args['--output-format'],
                         self.global_args['--output-style'])

        result.add(
            self.command_args['--blob-name'] + ':sas_url',
            self.storage.disk_image_sas(container_name,
                                        self.command_args['--blob-name'],
                                        start, expiry, permissions))
        out.display()

    def __delete(self):
        image = self.command_args['--blob-name']
        self.storage.delete(image)
        log.info('Deleted %s', image)
Example #21
0
class ComputeReservedIpTask(CliTask):
    """
        Process image commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)
        self.reserved_ip = ReservedIp(self.account)

        if self.command_args['list']:
            self.__list()
        if self.command_args['show']:
            self.__show()
        if self.command_args['create']:
            self.__create()
        if self.command_args['delete']:
            self.__delete()
        if self.command_args['associate']:
            self.__associate()
        if self.command_args['disassociate']:
            self.__disassociate()

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::compute::reserved_ip')
        else:
            return False
        return self.manual

    def __list(self):
        self.result.add('reserved_ips', self.reserved_ip.list())
        self.out.display()

    def __show(self):
        self.result.add('reserved_ip',
                        self.reserved_ip.show(self.command_args['--name']))
        self.out.display()

    def __create(self):
        request_id = self.reserved_ip.create(self.command_args['--name'],
                                             self.config.get_region_name())
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add('reserved_ip:' + self.command_args['--name'],
                        request_id)
        self.out.display()

    def __delete(self):
        request_id = self.reserved_ip.delete(self.command_args['--name'], )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add('reserved_ip:' + self.command_args['--name'],
                        request_id)
        self.out.display()

    def __associate(self):
        request_id = self.reserved_ip.associate(
            self.command_args['--name'],
            self.command_args['--cloud-service-name'])
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            ''.join([
                'associate reserved_ip:', self.command_args['--name'],
                'with cloud service:',
                self.command_args['--cloud-service-name']
            ]), request_id)
        self.out.display()

    def __disassociate(self):
        request_id = self.reserved_ip.disassociate(
            self.command_args['--name'],
            self.command_args['--cloud-service-name'])
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            ''.join([
                'disassociate reserved_ip:', self.command_args['--name'],
                'from cloud service:',
                self.command_args['--cloud-service-name']
            ]), request_id)
        self.out.display()
Example #22
0
class ComputeImageTask(CliTask):
    """
        Process image commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)

        self.image = Image(self.account)
        if self.command_args['list']:
            self.__list()
        if self.command_args['show']:
            self.__show()
        elif self.command_args['create']:
            self.__create()
        elif self.command_args['delete']:
            self.__delete()
        elif self.command_args['replicate']:
            self.__replicate()
        elif self.command_args['replication-status']:
            self.__replication_status(self.command_args['--name'])
        elif self.command_args['unreplicate']:
            self.__unreplicate()
        elif self.command_args['publish']:
            self.__publish()
        elif self.command_args['update']:
            self.__update()

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::compute::image')
        else:
            return False
        return self.manual

    def __create(self):
        request_id = self.image.create(
            self.command_args['--name'],
            self.command_args['--blob-name'],
            self.command_args['--label'],
            self.account.storage_container()
        )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            'image:' + self.command_args['--name'],
            request_id
        )
        self.out.display()

    def __delete(self):
        request_id = self.image.delete(
            self.command_args['--name'],
            self.command_args['--delete-disk'],
        )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            'image:' + self.command_args['--name'],
            request_id
        )
        self.out.display()

    def __list(self):
        self.result.add('images', self.image.list())
        self.out.display()

    def __show(self):
        self.result.add('image', self.image.show(self.command_args['--name']))
        self.out.display()

    def __replicate(self):
        image_name = self.command_args['--name']
        request_id = self.image.replicate(
            image_name,
            self.command_args['--regions'].split(','),
            self.command_args['--offer'],
            self.command_args['--sku'],
            self.command_args['--image-version']
        )
        self.result.add(
            'replicate:' +
            self.command_args['--name'] + ':' + self.command_args['--regions'],
            request_id
        )
        if not self.command_args['--quiet']:
            self.out.display()
        if self.command_args['--wait']:
            if not self.command_args['--quiet']:
                progress = BackgroundScheduler(timezone=utc)
                progress.add_job(
                    lambda: self.image.print_replication_status(image_name),
                    'interval',
                    minutes=5
                )
            progress.start()
            try:
                self.image.wait_for_replication_completion(image_name)
                self.image.print_replication_status(image_name)
            except KeyboardInterrupt:
                raise SystemExit('azurectl aborted by keyboard interrupt')
            finally:
                progress.shutdown()
        if not self.command_args['--quiet']:
            print()
            log.info('Replicated %s', image_name)

    def __replication_status(self, image_name):
        self.result.add(
            'replication-status:' + image_name,
            self.image.replication_status(image_name)
        )
        self.out.display()

    def __unreplicate(self):
        self.result.add(
            'unreplicate:' + self.command_args['--name'],
            self.image.unreplicate(
                self.command_args['--name']
            )
        )
        self.out.display()

    def __publish(self):
        scope = 'public'
        if self.command_args['--private']:
            scope = 'private'
        elif self.command_args['--msdn']:
            scope = 'msdn'
        request_id = self.image.publish(
            self.command_args['--name'], scope
        )
        if self.command_args['--wait']:
            self.request_wait(request_id)
        self.result.add(
            'publish:' + self.command_args['--name'],
            request_id
        )
        self.out.display()

    def __update(self):
        log.info(
            'Updating image metadata for: %s', self.command_args['--name']
        )
        update_elements = {
            'description':
                self.command_args['--description'],
            'eula':
                self.command_args['--eula'],
            'image_family':
                self.command_args['--image-family'],
            'icon_uri':
                self.command_args['--icon-uri'],
            'label':
                self.command_args['--label'],
            'language':
                self.command_args['--language'],
            'privacy_uri':
                self.command_args['--privacy-uri'],
            'published_date':
                self.command_args['--published-date'],
            'small_icon_uri':
                self.command_args['--small-icon-uri'],
            'recommended_vm_size':
                self.command_args['--recommended-vm-size'],
            'show_in_gui':
                self.command_args['--show-in-gui'],
        }
        for name, value in update_elements.items():
            if value is not None:
                log.info('--> %s = %s', name, value)
        self.image.update(
            self.command_args['--name'], update_elements
        )
Example #23
0
class SetupAccountTask(CliTask):
    """
        Process setup config commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        if self.command_args['list']:
            self.__list()
        elif self.command_args['default'] and not self.command_args['region']:
            self.__default()
        else:
            self.__load_account_setup(
                self.command_args['--name']
            )
            if self.command_args['remove']:
                self.__remove()
            elif self.command_args['configure']:
                self.__configure_account()
            elif self.command_args['region'] and self.command_args['add']:
                self.__region_add()
            elif self.command_args['region'] and self.command_args['default']:
                self.__set_region_default()

    def __help(self):
        if self.command_args['region'] and self.command_args['help']:
            self.manual.show('azurectl::setup::account::region')
        elif self.command_args['help']:
            self.manual.show('azurectl::setup::account')
        else:
            return False
        return self.manual

    def __load_account_setup(self, for_account=None):
        self.setup = AccountSetup(
            Config.get_config_file(account_name=for_account)
        )

    def __default(self):
        Config.set_default_config_file(
            account_name=self.command_args['--name']
        )
        log.info(
            'Account %s has been set as default configuration',
            self.command_args['--name']
        )

    def __check_account_existing_in_default_config(self):
        default_config = None
        try:
            default_config = Config()
        except Exception:
            # ignore exception thrown if no config file exists
            pass
        if default_config:
            account_section_name = 'account:' + self.command_args['--name']
            if default_config.config.has_section(account_section_name):
                raise AzureAccountConfigurationError(
                    'Account %s already configured in file %s' % (
                        self.command_args['--name'],
                        Config.get_config_file()
                    )
                )

    def __configure_account(self):
        self.__check_account_existing_in_default_config()
        self.setup.configure_account(
            self.command_args['--name'],
            self.command_args['--publish-settings-file'],
            self.command_args['--region'],
            self.command_args['--storage-account-name'],
            self.command_args['--container-name'],
            self.command_args['--subscription-id'],
            self.command_args['--management-pem-file'],
            self.command_args['--management-url']
        )
        self.setup.write()
        log.info(
            'Added account %s', self.command_args['--name']
        )
        if self.command_args['--create']:
            self.global_args['--account'] = self.command_args['--name']
            self.load_config()
            self.account = AzureAccount(self.config)
            self.__load_account_setup(
                self.command_args['--name']
            )

            try:
                storage_account_name = \
                    self.command_args['--storage-account-name']
                storage_account = StorageAccount(self.account)
                if not storage_account.exists(storage_account_name):
                    storage_account_request_id = storage_account.create(
                        name=storage_account_name,
                        description=self.command_args['--name'],
                        label=self.command_args['--storage-account-name'],
                        account_type=Defaults.account_type_for_docopts(
                            self.command_args
                        )
                    )
                    self.request_wait(storage_account_request_id)
                    log.info(
                        'Created %s storage account', storage_account_name
                    )
                else:
                    log.info(
                        'Storage account %s already exists',
                        storage_account_name
                    )

                container_name = self.command_args['--container-name']
                container = Container(self.account)
                if not container.exists(container_name):
                    container.create(container_name)
                    log.info(
                        'Created %s container', container_name
                    )
                else:
                    log.info(
                        'Container %s already exists', container_name
                    )
            except Exception as e:
                self.__remove()
                raise AzureAccountConfigurationError(
                    '%s: %s' % (type(e).__name__, format(e))
                )

    def __region_add(self):
        self.setup.add_region(
            self.command_args['--region'],
            self.command_args['--storage-account-name'],
            self.command_args['--container-name']
        )
        self.setup.write()
        log.info('Added region %s', self.command_args['--region'])

    def __set_region_default(self):
        if self.setup.set_default_region(self.command_args['--region']):
            self.setup.write()
            log.info(
                'Region %s is now set as default',
                self.command_args['--region'],
            )

    def __remove(self):
        self.setup.remove()
        log.info('Removed account config file %s', self.setup.filename)

    def __list(self):
        config_files = Config.get_config_file_list()
        default_config_file = config_files[0] or '<missing>'
        if os.path.islink(default_config_file):
            default_config_file = os.readlink(default_config_file)

        self.result.add(
            'default_config_file', default_config_file
        )

        for config_file in config_files:
            if config_file and not os.path.islink(config_file):
                setup = AccountSetup(config_file)
                account_info = setup.list()
                if account_info:
                    self.result.add(config_file, account_info)

        self.out.display()
Example #24
0
class StorageContainerTask(CliTask):
    """
        Process container commands
    """
    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(
            self.result,
            self.global_args['--output-format'],
            self.global_args['--output-style']
        )

        self.load_config()

        self.account = AzureAccount(self.config)

        # default to 1 minute ago (skew around 'now')
        if self.command_args['--start-datetime'] == 'now':
            start = datetime.datetime.utcnow() - datetime.timedelta(minutes=1)
        else:
            start = self.validate_date('--start-datetime')

        # default to 30 days from now
        if self.command_args['--expiry-datetime'] == '30 days from start':
            expiry = start + datetime.timedelta(days=30)
        else:
            expiry = self.validate_date('--expiry-datetime')

        self.validate_sas_permissions('--permissions')

        self.container = Container(self.account)

        if self.command_args['list']:
            self.__container_list()
        elif self.command_args['show']:
            self.__container_content()
        elif self.command_args['create']:
            self.__container_create()
        elif self.command_args['delete']:
            self.__container_delete()
        elif self.command_args['sas']:
            self.__container_sas(
                start, expiry, self.command_args['--permissions']
            )

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::storage::container')
        else:
            return False
        return self.manual

    def __container_sas(self, start, expiry, permissions):
        if self.command_args['--name']:
            container_name = self.command_args['--name']
        else:
            container_name = self.account.storage_container()
        self.result.add(
            self.account.storage_name() + ':container_sas_url',
            self.container.sas(container_name, start, expiry, permissions)
        )
        self.out.display()

    def __container_content(self):
        container_name = self.command_args['--name']
        self.result.add(
            self.account.storage_name() + ':container_content',
            self.container.content(container_name)
        )
        self.out.display()

    def __container_list(self):
        self.result.add(
            self.account.storage_name() + ':containers',
            self.container.list()
        )
        self.out.display()

    def __container_create(self):
        container_name = self.command_args['--name']
        log.info('Request to create container %s', container_name)
        self.container.create(container_name)
        log.info('Created %s container', container_name)

    def __container_delete(self):
        container_name = self.command_args['--name']
        log.info('Request to delete container %s', container_name)
        self.container.delete(container_name)
        log.info('Deleted %s container', container_name)
Example #25
0
class ComputeVmTask(CliTask):
    """
        Process vm commands
    """
    SSH_DEFAULT_PORT = 22

    def process(self):
        self.manual = Help()
        if self.__help():
            return

        self.result = DataCollector()
        self.out = DataOutput(self.result, self.global_args['--output-format'],
                              self.global_args['--output-style'])

        self.load_config()

        self.account = AzureAccount(self.config)

        if self.command_args['types']:
            self.__list_instance_types()
        elif self.command_args['regions']:
            self.__list_locations()
        elif self.command_args['show']:
            self.cloud_service = CloudService(self.account)
            self.__show_cloud_service_properties()
        else:
            self.vm = VirtualMachine(self.account)
            self.cloud_service = CloudService(self.account)
            if self.command_args['create']:
                self.__create_cloud_service()
                self.__create_instance()
            elif self.command_args['delete']:
                if self.command_args['--instance-name']:
                    self.__delete_instance()
                else:
                    self.__delete_cloud_service()
            elif self.command_args['reboot']:
                self.__reboot_instance()
            elif self.command_args['shutdown']:
                self.__shutdown_instance()
            elif self.command_args['start']:
                self.__start_instance()
            elif self.command_args['status']:
                self.__operate_on_instance_state()

    def __help(self):
        if self.command_args['help']:
            self.manual.show('azurectl::compute::vm')
        else:
            return False
        return self.manual

    def __list_instance_types(self):
        self.result.add('instance-types', self.account.instance_types())
        self.out.display()

    def __list_locations(self):
        self.result.add('regions', self.account.locations('PersistentVMRole'))
        self.out.display()

    def __show_cloud_service_properties(self):
        properties = self.cloud_service.get_properties(
            self.command_args['--cloud-service-name'])
        self.result.add(
            'cloud_service:' + self.command_args['--cloud-service-name'],
            properties)
        self.out.display()

    def __create_instance(self):
        instance_type = self.command_args['--instance-type']
        if not instance_type:
            instance_type = 'Small'
        fingerprint = ''
        if self.command_args['--ssh-private-key-file']:
            fingerprint = self.cloud_service.add_certificate(
                self.command_args['--cloud-service-name'],
                self.command_args['--ssh-private-key-file'])
        elif self.command_args['--fingerprint']:
            fingerprint = self.command_args['--fingerprint']
        linux_configuration = self.__prepare_linux_configuration(fingerprint)
        network_configuration = self.__prepare_network()
        request_id = self.vm.create_instance(
            self.command_args['--cloud-service-name'],
            self.command_args['--image-name'],
            linux_configuration,
            network_config=network_configuration,
            label=self.command_args['--label'],
            machine_size=instance_type,
            reserved_ip_name=self.command_args['--reserved-ip-name'])
        if self.command_args['--wait']:
            self.__get_instance_state(requested_state='ReadyRole', wait=True)
        self.result.add('instance', request_id)
        self.out.display()

    def __create_cloud_service(self):
        cloud_service_request_id = self.cloud_service.create(
            self.command_args['--cloud-service-name'],
            self.config.get_region_name())
        if int(cloud_service_request_id, 16) > 0:
            # a new cloud service was created for this instance, waiting
            # for the cloud service to become created. Basically we try
            # to prevent blocking, thus this is an exception to other
            # requests
            self.request_wait(cloud_service_request_id)

    def __delete_cloud_service(self):
        cloud_service = self.command_args['--cloud-service-name']
        complete_deletion = True
        request_id = self.cloud_service.delete(cloud_service,
                                               complete_deletion)
        if self.command_args['--wait']:
            # deletion is done when no instance state exists anymore
            self.__get_instance_state(requested_state='Undefined', wait=True)
        self.result.add('cloud_service:' + cloud_service, request_id)
        self.out.display()

    def __delete_instance(self):
        instance_name = self.command_args['--instance-name']
        request_id = self.vm.delete_instance(
            self.command_args['--cloud-service-name'], instance_name)
        if self.command_args['--wait']:
            # deletion is done when no instance state exists anymore
            self.__get_instance_state(requested_state='Undefined', wait=True)
        self.result.add('instance:' + instance_name, request_id)
        self.out.display()

    def __reboot_instance(self):
        instance_name = self.command_args['--instance-name']
        if not instance_name:
            instance_name = self.command_args['--cloud-service-name']
        request_id = self.vm.reboot_instance(
            self.command_args['--cloud-service-name'], instance_name)
        if self.command_args['--wait']:
            # On soft reboot initiated through the Azure API via a
            # reboot_role_instance request, the status of the VM does
            # not change which means this state change can't be captured
            # through an API request. Thus there is no real chance to
            # wait for this type of soft reboot to complete.
            # The safe default is to wait for the ready role
            self.__get_instance_state(requested_state='ReadyRole', wait=True)
        self.result.add('reboot:' + instance_name, request_id)
        self.out.display()

    def __shutdown_instance(self):
        instance_name = self.command_args['--instance-name']
        if not instance_name:
            instance_name = self.command_args['--cloud-service-name']
        request_id = self.vm.shutdown_instance(
            self.command_args['--cloud-service-name'], instance_name,
            self.command_args['--deallocate-resources'])
        if self.command_args['--wait']:
            if self.command_args['--deallocate-resources']:
                wait_state = 'StoppedDeallocated'
            else:
                wait_state = 'Stopped'
            self.__get_instance_state(requested_state=wait_state, wait=True)
        self.result.add('shutdown:' + instance_name, request_id)
        self.out.display()

    def __start_instance(self):
        instance_name = self.command_args['--instance-name']
        if not instance_name:
            instance_name = self.command_args['--cloud-service-name']
        request_id = self.vm.start_instance(
            self.command_args['--cloud-service-name'], instance_name)
        if self.command_args['--wait']:
            self.__get_instance_state(requested_state='ReadyRole', wait=True)
        self.result.add('start:' + instance_name, request_id)

    def __get_instance_state(self, requested_state=None, wait=False):
        instance_name = self.command_args['--instance-name']
        if not instance_name:
            instance_name = self.command_args['--cloud-service-name']
        status = self.vm.instance_status(
            self.command_args['--cloud-service-name'], instance_name)
        if requested_state and wait:
            request_timeout = 5
            while status != requested_state:
                time.sleep(request_timeout)
                status = self.vm.instance_status(
                    self.command_args['--cloud-service-name'], instance_name)
        return status

    def __operate_on_instance_state(self):
        instance_name = self.command_args['--instance-name']
        if not instance_name:
            instance_name = self.command_args['--cloud-service-name']
        self.result.add('status:' + instance_name, self.__get_instance_state())
        self.out.display()

    def __prepare_linux_configuration(self, fingerprint=''):
        user = self.command_args['--user']
        instance_name = self.command_args['--instance-name']
        password = self.command_args['--password']

        custom_data = self.command_args['--custom-data']
        if (custom_data and os.path.isfile(custom_data)):
            with open(custom_data, 'r') as file:
                custom_data = file.read()

        disable_ssh_password_authentication = False
        if not user:
            # no user specified, use the default Azure user name
            user = '******'
        if not instance_name:
            # no instance name specified, use the cloud service name
            instance_name = self.command_args['--cloud-service-name']
        if not password:
            # no password set, disable ssh user authentication
            disable_ssh_password_authentication = True
        return self.vm.create_linux_configuration(
            user, instance_name, disable_ssh_password_authentication, password,
            custom_data, fingerprint)

    def __prepare_network(self):
        ssh_endpoint = self.__prepare_ssh()
        return self.vm.create_network_configuration([ssh_endpoint])

    def __prepare_ssh(self, ssh_local_port=SSH_DEFAULT_PORT):
        ssh_public_port = self.command_args['--ssh-port']
        if not ssh_public_port:
            # no ssh public port specified, use local port as default
            ssh_public_port = ssh_local_port
        return self.vm.create_network_endpoint('SSH', ssh_public_port,
                                               ssh_local_port, 'TCP')