def validate_region(region): if not (is_region(region) or is_valid_region_index(region)): click.echo("Unrecognized region: {}. Please enter a number between 1 to {}, or valid regions can be found here: https://docs.cloud.oracle.com/Content/General/Concepts/regions.htm".format(region, len(REGIONS))) if not click.confirm("Continue with unrecognized region? (Enter 'n' to re-enter region)"): return None return region
def validate_region(region): if not is_region(region): click.echo( "Unrecognized region: {}. Valid regions can be found here: https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm" .format(region)) if not click.confirm( "Continue with unrecognized region? (Enter 'n' to re-enter region)" ): return None return region
def create_user_session(region='', tenancy_name=None): if region == '': region = cli_setup.prompt_for_region() # try to set up http server so we can fail early if the required port is in use try: server_address = ('', BOOTSTRAP_SERVICE_PORT) httpd = StoppableHttpServer(server_address, StoppableHttpRequestHandler) except OSError as e: if e.errno == errno.EADDRINUSE: click.echo( "Could not complete bootstrap process because port {port} is already in use." .format(port=BOOTSTRAP_SERVICE_PORT)) sys.exit(1) raise e # create new key pair # this key pair is used to get the initial token and also uploaded as a new API key for the user private_key = cli_util.generate_key() public_key = private_key.public_key() fingerprint = cli_setup.public_key_to_fingerprint(public_key) key = cli_util.to_jwk(public_key) jwk_content = key bytes_jwk_content = jwk_content.encode('UTF-8') b64_jwk_content = base64.urlsafe_b64encode(bytes_jwk_content).decode( 'UTF-8') public_key_jwk = b64_jwk_content query = { 'action': 'login', 'client_id': 'iaas_console', 'response_type': 'token id_token', 'nonce': uuid.uuid4(), 'scope': 'openid', 'public_key': public_key_jwk, 'redirect_uri': 'http://localhost:{}'.format(BOOTSTRAP_SERVICE_PORT) } if tenancy_name: query['tenant'] = tenancy_name if region in regions.REGIONS_SHORT_NAMES: region = regions.REGIONS_SHORT_NAMES[region] if regions.is_region(region): console_url = CONSOLE_AUTH_URL_FORMAT.format( region=region, realm=regions.REALMS[regions.REGION_REALMS[region]]) else: click.echo( 'Error: {} is not a valid region. Valid regions are \n{}'.format( region, regions.REGIONS)) sys.exit(1) query_string = urlencode(query) url = "{console_auth_url}?{query_string}".format( console_auth_url=console_url, query_string=query_string) # attempt to open browser to console log in page try: if webbrowser.open_new(url): click.echo( ' Please switch to newly opened browser window to log in!') click.echo( ' You can also open the following URL in a web browser window to continue:' ) click.echo('%s' % url) else: click.echo( ' Open the following URL in a web browser window to continue:' ) click.echo('%s' % url) except webbrowser.Error as e: click.echo( 'Could not launch web browser to complete login process, exiting bootstrap command. Error: {exc_info}.' .format(exc_info=str(e))) sys.exit(1) # start up http server which will handle capturing auth redirect from console token = httpd.serve_forever() click.echo(' Completed browser authentication process!') # get user / tenant info out of token token_data = jwt.decode(token, verify=False) user_ocid = token_data['sub'] tenancy_ocid = token_data['tenant'] return UserSession(user_ocid, tenancy_ocid, region, token, public_key, private_key, fingerprint)
def copy_stack(ctx, from_json, stack_id, destination_region, destination_compartment_id, display_name, description, freeform_tags, defined_tags, variables, access_token): if isinstance(stack_id, six.string_types) and len(stack_id.strip()) == 0: raise click.UsageError( 'Parameter --stack-id cannot be whitespace or empty string') if destination_region is not None and not is_region(destination_region): raise click.UsageError( "Unrecognized region: {}. Review valid regions at https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm" .format(destination_region)) inner_kwargs = {} inner_kwargs['opc_request_id'] = cli_util.use_or_generate_request_id( ctx.obj['request_id']) client = cli_util.build_client('resource_manager', 'resource_manager', ctx) # GET Stack source_stack_response = client.get_stack(stack_id=stack_id, **inner_kwargs) source_region = ctx.obj['config']['region'] if destination_region is not None and get_realm_from_region( destination_region) != get_realm_from_region(source_region): raise click.UsageError( "Invalid region. Destination region must be in the same realm {}. Review valid regions at https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm" .format(destination_region)) copy_display_name_prefix = "[copy-from-" + source_region + "]-" if destination_region is not None and destination_region == source_region: destination_region = None # Prepare Stack Metadata if source_stack_response is None or source_stack_response.data is None: raise Exception("Could not retrieve stack object", inner_kwargs['opc_request_id']) source_stack = source_stack_response.data _details = copy_stack_metadata(source_stack, destination_compartment_id, display_name, description, freeform_tags, defined_tags, variables, copy_display_name_prefix) # get config source metadata for stack _details['configSource'] = get_config_source_metadata_for_stack( source_stack, destination_region, access_token) is_zip_upload = source_stack.config_source.config_source_type == oci.resource_manager.models.ConfigSource.CONFIG_SOURCE_TYPE_ZIP_UPLOAD or source_stack.config_source.config_source_type == oci.resource_manager.models.ConfigSource.CONFIG_SOURCE_TYPE_COMPARTMENT_CONFIG_SOURCE is_git_config = source_stack.config_source.config_source_type == oci.resource_manager.models.ConfigSource.CONFIG_SOURCE_TYPE_GIT_CONFIG_SOURCE if not is_zip_upload and not is_git_config: raise Exception( "Only zip-upload config, git-configuration-source and create-from-compartment stacks are supported for copy stack", inner_kwargs['opc_request_id']) # GET TF Config if is_zip_upload: stack_tf_config_response = client.get_stack_tf_config( stack_id=stack_id, **inner_kwargs) if stack_tf_config_response is None or stack_tf_config_response.data is None: raise Exception("Could not retrieve stack TF config", inner_kwargs['opc_request_id']) base64encoded_stack_tf_config = get_source_stack_tf_config_base64encoded_zip( stack_id, stack_tf_config_response) _details['configSource'][ 'zipFileBase64Encoded'] = base64encoded_stack_tf_config # Setup Cross region if destination_region is not None and is_git_config: _get_config_details = {} # GET config source provider get_config_source_provider_response = client.get_configuration_source_provider( configuration_source_provider_id=source_stack.config_source. configuration_source_provider_id, **inner_kwargs) if get_config_source_provider_response is None or get_config_source_provider_response.data is None: raise Exception("Unable to get git config source provider", inner_kwargs['opc_request_id']) _get_config_details.update( copy_git_config_source_provider_metadata( get_config_source_provider_response.data, access_token, copy_display_name_prefix)) # Change region client.base_client.set_region(destination_region) # CREATE config source provider in new region create_config_source_provider_response = client.create_configuration_source_provider( create_configuration_source_provider_details=_get_config_details, **inner_kwargs) if create_config_source_provider_response is None or create_config_source_provider_response.data is None: raise Exception("Unable to copy Git configuration source provider", inner_kwargs['opc_request_id']) cli_util.render_response(create_config_source_provider_response, ctx) _details['configSource'][ 'configurationSourceProviderId'] = create_config_source_provider_response.data.id elif destination_region is not None: # Change region client.base_client.set_region(destination_region) try: # CREATE stack result = client.create_stack(create_stack_details=_details, **inner_kwargs) cli_util.render_response(result, ctx) except Exception as e: print("Failed to copy stack: ", stack_id) print(e) if destination_region is not None and is_git_config: print("Deleting copied configuration source provider: ", create_config_source_provider_response.data.id) # delete config source provider delete_config_source = client.delete_configuration_source_provider( configuration_source_provider_id= create_config_source_provider_response.data.id, **inner_kwargs)