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
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)
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)
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)
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 )
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()
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()
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()
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)
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'))
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')
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)
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()