def init_environment(config_filepath=BASE_CONFIG_FILEPATH): """Set up module variables according to config dict. :param str config_filepath: """ global AMQP_USERNAME, AMQP_PASSWORD, CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, TEARDOWN_INSTALLATION, TEARDOWN_CLUSTERS, \ TEST_ALL_TEMPLATES config = testutils.yaml_to_dict(config_filepath) CLIENT = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], utils.SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) org = utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = utils.get_vdc(CLIENT, config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href CATALOG_NAME = config['broker']['catalog'] AMQP_USERNAME = config['amqp']['username'] AMQP_PASSWORD = config['amqp']['password'] test_config = config.get('test') if test_config is not None: TEARDOWN_INSTALLATION = test_config.get('teardown_installation', True) TEARDOWN_CLUSTERS = test_config.get('teardown_clusters', True) TEST_ALL_TEMPLATES = test_config.get('test_all_templates', False)
def init_environment(config_filepath=BASE_CONFIG_FILEPATH): """Set up module variables according to config dict. :param str config_filepath: """ global AMQP_USERNAME, AMQP_PASSWORD, CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, DEV_MODE config = testutils.yaml_to_dict(config_filepath) CLIENT = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], utils.SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) org = utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = utils.get_vdc(CLIENT, config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href CATALOG_NAME = config['broker']['catalog'] AMQP_USERNAME = config['amqp']['username'] AMQP_PASSWORD = config['amqp']['password'] try: DEV_MODE = config['test']['developer_mode'] except KeyError: pass
def info_ovdc_for_k8s(self, ovdc_name, org_name=None): """Disable ovdc for k8s for the given container provider. :param str ovdc_name: Name of the ovdc to be enabled :param str org_name: Name of organization that belongs to ovdc_name :return: response object :rtype: dict """ method = 'GET' ovdc = get_vdc(self.client, ovdc_name, org_name=org_name, is_admin_operation=True) ovdc_id = utils.extract_id(ovdc.resource.get('id')) uri = f'{self._uri}/ovdc/{ovdc_id}/info' response = self.client._do_request_prim( method, uri, self.client._session, contents=None, media_type=None, accept_type='application/*+json') return process_response(response)
def disable_ovdc_for_k8s(self, ovdc_name, org_name=None): """Disable ovdc for k8s for the given container provider. :param str ovdc_name: Name of the ovdc to be enabled :param str org_name: Name of organization that belongs to ovdc_name :return: response object :rtype: dict """ method = 'PUT' ovdc = get_vdc(self.client, ovdc_name, org_name=org_name, is_admin_operation=True) ovdc_id = utils.extract_id(ovdc.resource.get('id')) uri = f'{self._uri}/ovdc/{ovdc_id}/info' data = { 'ovdc_id': ovdc_id, 'ovdc_name': ovdc_name, K8S_PROVIDER_KEY: K8sProviders.NONE, 'pks_plans': None, 'org_name': org_name, 'disable': True } response = self.client._do_request_prim( method, uri, self.client._session, contents=data, media_type='application/json', accept_type='application/*+json') return process_response(response)
def set_ovdc_container_provider_metadata(self, ovdc_name, ovdc_id=None, org_name=None, container_provider=None, pks_plans=''): """Set the container provider metadata of given ovdc. :param str ovdc_name: name of the ovdc :param str ovdc_id: unique id of the ovdc :param str org_name: specific org to use if @org is not given. If None, uses currently logged-in org from @client. :param str container_provider: name of container provider for which the ovdc is being enabled to deploy k8 clusters on. :param str pks_plans: PKS plans for deployment. If container provider is vCD or None, pks_plans are not applicable. """ metadata = dict() org = get_org(self.client, org_name=org_name) if ovdc_id is None: ovdc = get_vdc(self.client, ovdc_name, org=org, is_admin_operation=True) ovdc_id = utils.extract_id(ovdc.resource.get('id')) else: ovdc = self._get_vdc_by_id(ovdc_id) if container_provider != 'pks': LOGGER.debug(f'Remove metadata for ovdc:{ovdc_name}') self._remove_metadata(ovdc, self.__ovdc_metadata_keys) metadata['container_provider'] = container_provider or '' else: # Get resource pool resource_pool = f"{ovdc.name} ({ovdc_id})" # Get pvdc and pks information from pvdc cache org_name = org.resource.get('name') pvdc_element = ovdc.resource.ProviderVdcReference pvdc_id = pvdc_element.get('id') pvdc_info = self.pvdc_cache.get_pvdc_info(pvdc_id) pks_info = self.pvdc_cache.get_pks_info(org_name, pvdc_info['vc']) # construct ovdc metadata metadata['name'] = pvdc_info['name'] metadata['vc'] = pvdc_info['vc'] metadata['rp_path'] = ','.join(f'{rp_path}/{resource_pool}' for rp_path in pvdc_info['rp_path']) metadata['host'] = pks_info['host'] metadata['port'] = pks_info['port'] metadata['uaac_port'] = pks_info['uaac_port'] metadata['pks_plans'] = pks_plans or '' metadata['container_provider'] = container_provider pks_compute_profile_name = f"{org_name}-{ovdc_name}-{ovdc_id}" metadata['pks_compute_profile_name'] = pks_compute_profile_name # set ovdc metadata into Vcd LOGGER.debug(f"Setting below metadata on ovdc {ovdc_name}:{metadata}") return ovdc.set_multiple_metadata(metadata, MetadataDomain.SYSTEM, MetadataVisibility.PRIVATE)
def setUpClass(cls): """Runs once for this class, before all test methods. Tasks: - Initialize client, config, and other attributes. - Restore VCD AMQP settings to defaults. - Delete any pre-existing CSE entities. """ cls._config = yaml_to_dict(BASE_CONFIG_FILEPATH) cls._client = Client(cls._config['vcd']['host'], api_version=cls._config['vcd']['api_version'], verify_ssl_certs=cls._config['vcd']['verify']) credentials = BasicLoginCredentials(cls._config['vcd']['username'], SYSTEM_ORG_NAME, cls._config['vcd']['password']) cls._client.set_credentials(credentials) assert cls._client is not None cls._org = get_org(cls._client, org_name=cls._config['broker']['org']) assert cls._org is not None cls._vdc = get_vdc(cls._client, cls._config['broker']['vdc'], org=cls._org) assert cls._vdc is not None cls._api_extension = APIExtension(cls._client) assert cls._api_extension is not None cls._amqp_service = AmqpService(cls._client) assert cls._amqp_service is not None cls._runner = CliRunner() assert cls._runner is not None cls._ssh_key_filepath = f"{Path.home() / '.ssh' / 'id_rsa.pub'}" configure_vcd_amqp(cls._client, 'vcdext', cls._config['amqp']['host'], cls._config['amqp']['port'], 'vcd', cls._config['amqp']['ssl_accept_all'], cls._config['amqp']['ssl'], '/', cls._config['amqp']['username'], cls._config['amqp']['password'], quiet=True) cls._default_amqp_settings = to_dict(cls._amqp_service.get_settings()) assert cls._default_amqp_settings is not None cls._amqp_username = cls._config['amqp']['username'] assert cls._amqp_username is not None cls._amqp_password = cls._config['amqp']['password'] assert cls._amqp_password is not None CSEServerInstallationTest.delete_cse_entities()
def get_ovdc(self, ovdc_name=None, ovdc_id=None, org_name=None): if ovdc_id is None: org = get_org(self.client, org_name=org_name) return get_vdc(self.client, ovdc_name, org=org, is_admin_operation=True) else: return get_vdc_by_id(self.client, ovdc_id)
def get_ovdc_container_provider_metadata(self, ovdc_name, ovdc_id=None, org_name=None): """Get metadata of given ovdc, pertaining to the container provider. :param str ovdc_name: name of the ovdc :param str org_name: specific org to use if @org is not given. If None, uses currently logged-in org from @client. :return: metadata of the ovdc :rtype: dict :raises EntityNotFoundException: if the ovdc could not be found. """ # Get pvdc and pks information from pvdc cache if ovdc_id is None: ovdc = get_vdc(self.client, ovdc_name, org_name=org_name, is_admin_operation=True) else: # TODO() - Implement this in pyvcloud ovdc = self._get_vdc_by_id(ovdc_id) all_metadata = utils.metadata_to_dict(ovdc.get_all_metadata()) if 'container_provider' not in all_metadata: container_provider = None else: container_provider = \ all_metadata['container_provider'] if container_provider == 'pks': # Filter out container provider metadata into a dict metadata = { metadata_key: all_metadata[metadata_key] for metadata_key in self.__ovdc_metadata_keys } pvdc_element = ovdc.resource.ProviderVdcReference pvdc_id = pvdc_element.get('id') pvdc_info = self.pvdc_cache.get_pvdc_info(pvdc_id) pks_info = self.pvdc_cache.get_pks_info(ovdc.name, pvdc_info['vc']) # Get ovdc metadata from vcd; copy the credentials from pvdc cache metadata['rp_path'] = metadata['rp_path'].split(',') metadata['pks_plans'] = metadata['pks_plans'].split(',') metadata['username'] = pks_info['username'] metadata['secret'] = pks_info['secret'] else: metadata = {'container_provider': container_provider} return metadata
def enable_ovdc_for_k8s(self, ovdc_name, k8s_provider=None, pks_plan=None, pks_cluster_domain=None, org_name=None): """Enable ovdc for k8s for the given container provider. :param str ovdc_name: Name of the ovdc to be enabled :param str k8s_provider: Name of the container provider :param str pks_plan: PKS plan :param str pks_cluster_domain: Suffix of the domain name, which will be used to construct FQDN of the clusters. :param str org_name: Name of organization that belongs to ovdc_name :return: response object :rtype: dict """ method = 'PUT' ovdc = get_vdc(self.client, ovdc_name, org_name=org_name, is_admin_operation=True) ovdc_id = utils.extract_id(ovdc.resource.get('id')) uri = f'{self._uri}/ovdc/{ovdc_id}/info' data = { 'ovdc_id': ovdc_id, 'ovdc_name': ovdc_name, K8S_PROVIDER_KEY: k8s_provider, 'pks_plans': pks_plan, 'pks_cluster_domain': pks_cluster_domain, 'org_name': org_name, 'enable': True } response = self.client._do_request_prim( method, uri, self.client._session, contents=data, media_type='application/json', accept_type='application/*+json') return process_response(response)
def create_template(ctx, client, config, template_config, update=False, no_capture=False, ssh_key=None, org=None, vdc=None): """Handles template creation phase during CSE installation. :param click.core.Context ctx: click context object. :param pyvcloud.vcd.client.Client client: :param dict config: CSE config. :param dict template_config: specific template section of @config. :param bool update: if True and templates already exist in vCD, overwrites existing templates. :param bool no_capture: if True, temporary vApp will not be captured or destroyed, so the user can ssh into the VM and debug. :param str ssh_key: public ssh key to place into the template vApp(s). :param pyvcloud.vcd.org.Org org: specific org to use. If None, uses org specified in @config. :param pyvcloud.vcd.vdc.VDC vdc: specific vdc to use. If None, uses vdc specified in @config. """ if org is None: org = get_org(client, org_name=config['broker']['org']) if vdc is None: vdc = get_vdc(client, config['broker']['vdc'], org=org) ctx.obj = {'client': client} catalog_name = config['broker']['catalog'] template_name = template_config['catalog_item'] vapp_name = template_config['temp_vapp'] ova_name = template_config['source_ova_name'] if not update and catalog_item_exists(org, catalog_name, template_name): msg = f"Found template '{template_name}' in catalog '{catalog_name}'" click.secho(msg, fg='green') LOGGER.info(msg) return # if update flag is set, delete existing template/ova file/temp vapp if update: msg = f"--update flag set. If template, source ova file, " \ f"and temporary vApp exist, they will be deleted" click.secho(msg, fg='yellow') LOGGER.info(msg) try: org.delete_catalog_item(catalog_name, template_name) wait_for_catalog_item_to_resolve(client, catalog_name, template_name, org=org) org.reload() msg = "Deleted vApp template" click.secho(msg, fg='green') LOGGER.info(msg) except EntityNotFoundException: pass try: org.delete_catalog_item(catalog_name, ova_name) wait_for_catalog_item_to_resolve(client, catalog_name, ova_name, org=org) org.reload() msg = "Deleted ova file" click.secho(msg, fg='green') LOGGER.info(msg) except EntityNotFoundException: pass try: task = vdc.delete_vapp(vapp_name, force=True) stdout(task, ctx=ctx) vdc.reload() msg = "Deleted temporary vApp" click.secho(msg, fg='green') LOGGER.info(msg) except EntityNotFoundException: pass # if needed, upload ova and create temp vapp msg = f"Creating template '{template_name}' in catalog '{catalog_name}'" click.secho(msg, fg='yellow') LOGGER.info(msg) temp_vapp_exists = True try: vapp = VApp(client, resource=vdc.get_vapp(vapp_name)) msg = f"Found vApp '{vapp_name}'" click.secho(msg, fg='green') LOGGER.info(msg) except EntityNotFoundException: temp_vapp_exists = False # flag is used to hide previous try/except error if an error occurs below if not temp_vapp_exists: if catalog_item_exists(org, catalog_name, ova_name): msg = f"Found ova file '{ova_name}' in catalog '{catalog_name}'" click.secho(msg, fg='green') LOGGER.info(msg) else: # download/upload files to catalog if necessary ova_filepath = f"cse_cache/{ova_name}" download_file(template_config['source_ova'], ova_filepath, sha256=template_config['sha256_ova'], logger=LOGGER) upload_ova_to_catalog(client, catalog_name, ova_filepath, org=org, logger=LOGGER) vapp = _create_temp_vapp(ctx, client, vdc, config, template_config, ssh_key) if no_capture: msg = f"'--no-capture' flag set. " \ f"Not capturing vApp '{vapp.name}' as a template" click.secho(msg, fg='yellow') LOGGER.info(msg) return # capture temp vapp as template msg = f"Creating template '{template_name}' from vApp '{vapp.name}'" click.secho(msg, fg='yellow') LOGGER.info(msg) capture_vapp_to_template(ctx, vapp, catalog_name, template_name, org=org, desc=template_config['description'], power_on=not template_config['cleanup']) msg = f"Created template '{template_name}' from vApp '{vapp_name}'" click.secho(msg, fg='green') LOGGER.info(msg) # delete temp vapp if template_config['cleanup']: msg = f"Deleting vApp '{vapp_name}'" click.secho(msg, fg='yellow') LOGGER.info(msg) task = vdc.delete_vapp(vapp_name, force=True) stdout(task, ctx=ctx) vdc.reload() msg = f"Deleted vApp '{vapp_name}'" click.secho(msg, fg='green') LOGGER.info(msg)