Beispiel #1
0
    def call_api(self,
                 resource_path,
                 method,
                 path_params=None,
                 query_params=None,
                 header_params=None,
                 body=None,
                 response_type=None,
                 enforce_content_headers=True):
        """
        Makes the HTTP request and return the deserialized data.

        :param resource_path: Path to the resource (e.g. /instance)
        :param method: HTTP method
        :param path_params: (optional) Path parameters in the url.
        :param query_params: (optional) Query parameters in the url.
        :param header_params: (optional) Request header params.
        :param body: (optional) Request body.
        :param response_type: (optional) Response data type.
        :param enforce_content_headers: (optional) Whether content headers should be added for
            PUT and POST requests when not present.  Defaults to True.
        :return: A Response object, or throw in the case of an error.

        """

        if path_params is not None:
            for k, v in path_params.items():
                replacement = six.moves.urllib.parse.quote(v)
                resource_path = resource_path.\
                    replace('{' + k + '}', replacement)

        response = self.pool_manager.request(
            method,
            '{}{}{}'.format(self._endpoint, self._base_path, resource_path),
            body=json.dumps(body),
            headers=header_params)

        request = Request(method=method,
                          url=self._endpoint + self._base_path + resource_path,
                          query_params=query_params,
                          header_params=header_params,
                          body=body,
                          response_type=response_type,
                          enforce_content_headers=enforce_content_headers)
        if not 200 <= response.status <= 299:
            raise exceptions.ServiceError(response.status,
                                          None,
                                          response.headers,
                                          str(response.data),
                                          original_request=request)

        data = response.data
        try:
            data = json.loads(response.data.decode("utf-8"))
        except Exception as e:
            pass
        return Response(response.status, dict(response.getheaders()), data,
                        request)
Beispiel #2
0
def validate_upload_user_credentials(ctx, upload_bucket):
    """
    There are two users, the admin user and the upload user
    The admin user is the one who has access to the user's tenancy and can perform operations like creating a job,
    requesting an appliance, etc.
    The upload user has enough permissions to just upload data to a particular user bucket. The upload user cannot
    delete objects from the bucket nor can it make modifications to the bucket or account. In essence it is a
    restricted user.
    The upload user is defined in ~/.oci/config_upload_user under the [DEFAULT] section. There is no way to change
    the file and the section. These are standards that are expected
    The idea of validation is to check whether the upload user has the ability to create objects, inspect the object
    and read the object's meta data from Oracle Cloud Infrastructure
    The procedure is this:
    1. Admin user tries to get the test object and delete it if it is present.
      - This is more of an error check when there is a stale object present from a previous failed run
      - Only the admin user, NOT the upload user, can delete an object
    2. Upload user creates the test object
    3. Upload user overwrites the test object
    4. Upload user gets the checksum of the test object
    5. Upload user gets the metadata of the test bucket
    6. Admin user deletes the test object
    :param upload_bucket: The bucket to upload to
    :return: None
    """
    admin_user = oci_config.from_file(ctx.obj['config_file'])['user']
    # Overriding any endpoint that was set. Need to get to the endpoint based on the config file, not based on the
    # override parameter
    ctx.endpoint = None
    ctx.obj['endpoint'] = None
    object_storage_admin_client = cli_util.build_client('object_storage', ctx)
    # A bit hacky but gets the job done. Only two parameters need to be changed to get the upload user context,
    # the profile and the config file. All other parameters remain the same
    upload_user_ctx = ctx
    upload_user_ctx.obj['profile'] = 'DEFAULT'
    upload_user_ctx.obj['config_file'] = APPLIANCE_UPLOAD_USER_CONFIG_PATH
    # Overriding any endpoint that was set. Need to get to the endpoint based on the config_upload_user file
    upload_user_ctx.endpoint = None
    object_storage_upload_client = cli_util.build_client(
        'object_storage', upload_user_ctx)

    namespace = object_storage_admin_client.get_namespace().data
    try:
        try:
            object_storage_admin_client.head_object(namespace, upload_bucket,
                                                    TEST_OBJECT)
            click.echo("Found test object in bucket. Deleting  it...")
            object_storage_admin_client.delete_object(namespace, upload_bucket,
                                                      TEST_OBJECT)
        except exceptions.ServiceError as se:
            if se.status != 404:
                raise se
    except Exception as e:
        raise exceptions.RequestException(
            "Admin user {} failed to delete the test object {}: {}".format(
                admin_user, TEST_OBJECT, str(e)))

    test_object_content = "Bulk Data Transfer Test"

    operation = None
    test_object_exists = False
    try:
        operation = "Create object {} in bucket {} using upload user".format(
            TEST_OBJECT, upload_bucket)
        object_storage_upload_client.put_object(namespace, upload_bucket,
                                                TEST_OBJECT,
                                                test_object_content)
        click.echo(operation)
        test_object_exists = True

        operation = "Overwrite object {} in bucket {} using upload user".format(
            TEST_OBJECT, upload_bucket)
        object_storage_upload_client.put_object(namespace, upload_bucket,
                                                TEST_OBJECT,
                                                test_object_content)
        click.echo(operation)

        operation = "Inspect object {} in bucket {} using upload user".format(
            TEST_OBJECT, upload_bucket)
        object_storage_upload_client.head_object(namespace, upload_bucket,
                                                 TEST_OBJECT)
        click.echo(operation)

        operation = "Read bucket metadata {} using upload user".format(
            upload_bucket)
        metadata = object_storage_upload_client.get_bucket(
            namespace, upload_bucket).data.metadata
        click.echo(operation)
    except exceptions.ServiceError as se:
        raise exceptions.RequestException(
            "Failed to {} in tenancy {} as upload user: {}".format(
                operation, namespace, se.message))
    finally:
        if test_object_exists:
            try:
                object_storage_admin_client.delete_object(
                    namespace, upload_bucket, TEST_OBJECT)
            except exceptions.ServiceError as se:
                raise exceptions.ServiceError(
                    "Failed to delete test object {} as admin user {}: {}".
                    format(TEST_OBJECT, admin_user, se.message))
Beispiel #3
0
def validate_upload_user_credentials(ctx,
                                     upload_bucket,
                                     upload_user_config=None):
    """
    There are two users, the admin user and the upload user
    The admin user is the one who has access to the user's tenancy and can perform operations like creating a job,
    requesting an appliance, etc.
    The upload user has enough permissions to just upload data to a particular user bucket. The upload user cannot
    delete objects from the bucket nor can it make modifications to the bucket or account. In essence it is a
    restricted user.
    The upload user is defined in ~/.oci/config_upload_user under the [DEFAULT] section. There is no way to change
    the file and the section. These are standards that are expected
    The idea of validation is to check whether the upload user has the ability to create objects, inspect the object
    and read the object's meta data from Oracle Cloud Infrastructure
    The procedure is this:
    1. Admin user tries to get the test object and delete it if it is present.
      - This is more of an error check when there is a stale object present from a previous failed run
      - Only the admin user, NOT the upload user, can delete an object
    2. Upload user creates the test object
    3. Upload user overwrites the test object
    4. Upload user gets the checksum of the test object
    5. Upload user gets the metadata of the test bucket
    6. Admin user deletes the test object
    :param upload_bucket: The bucket to upload to
    :param upload_user_config: config built from APPLIANCE_UPLOAD_USER_CONFIG_PATH
    :return: None
    """
    # Overriding any endpoint that was set. Need to get to the endpoint based on the config file, not based on the
    # override parameter
    ctx.endpoint = None
    ctx.obj['endpoint'] = None
    # To support cross region uploads. get the region from the Upload User file
    # For example, let's say the config file had us-phoenix-1 as the region and config_upload_user had us-ashburn-1
    # If the region is not changed in the context, the admin client would be talking to us-phoenix-1 whereas the
    # upload client would be talking to us-ashburn-1. That's not what we want.
    try:
        if not upload_user_config:
            upload_user_config = get_upload_user_config()
        oci_config.validate_config(upload_user_config)

    except exceptions.ProfileNotFound as e:
        error_message_wrapper(
            'ProfileNotFound: Unable to parse the upload user config file %s: %s'
            % (APPLIANCE_UPLOAD_USER_CONFIG_PATH, e))

    except exceptions.InvalidConfig as bad_config:
        table = render_config_errors(bad_config)
        template = "InvalidConfig: The config file at {config_file} is invalid:\n\n{errors}"
        error_message_wrapper(
            template.format(config_file=APPLIANCE_UPLOAD_USER_CONFIG_PATH,
                            errors=table))

    admin_user = get_user(ctx)

    region = get_upload_user_region()

    if 'config' in ctx.obj:  # config loaded/present
        if 'region' in ctx.obj['config'] and ctx.obj['config'][
                'region']:  # region present in ~/.oci/config
            if region:  # region present in APPLIANCE_UPLOAD_USER_CONFIG_PATH
                if ctx.obj['config']['region'].strip() != region.strip():
                    confirm_prompt = "WARNING: The config file under {config_path}/config: '{config_region}' has different region than "\
                                     "{upload_user_path}: '{upload_user_region}'. Are you sure you want to continue with "  \
                                     "'{upload_user_region}'?".format(config_path=CONFIG_DIR,
                                                                      upload_user_path=APPLIANCE_UPLOAD_USER_CONFIG_PATH,
                                                                      config_region=ctx.obj['config']['region'], upload_user_region=region)
                    if not click.confirm(
                            click.style(confirm_prompt, fg="yellow")):
                        error_message_wrapper("Aborted. Exiting...")

                ctx.obj['region'] = region
                ctx.obj['config']['region'] = region
                object_storage_admin_client = create_obj_storage_client(ctx)
                # A bit hacky but gets the job done. Only two parameters need to be changed to get the upload user context,
                # the profile and the config file. All other parameters remain the same
                upload_user_ctx = ctx
                upload_user_ctx.obj['profile'] = 'DEFAULT'
                upload_user_ctx.obj[
                    'config_file'] = APPLIANCE_UPLOAD_USER_CONFIG_PATH
                # Overriding any endpoint that was set. Need to get to the endpoint based on the config_upload_user file
                upload_user_ctx.endpoint = None
                object_storage_upload_client = create_obj_storage_client(
                    upload_user_ctx)
                namespace = object_storage_admin_client.get_namespace().data
                try:
                    try:
                        object_storage_admin_client.head_object(
                            namespace, upload_bucket, TEST_OBJECT)
                        click.echo(
                            "Found test object in bucket. Deleting  it...")
                        object_storage_admin_client.delete_object(
                            namespace, upload_bucket, TEST_OBJECT)
                    except exceptions.ServiceError as se:
                        if se.status != 404:
                            raise se
                except Exception as e:
                    raise exceptions.RequestException(
                        "Admin user {} failed to delete the test object {}: {}"
                        .format(admin_user, TEST_OBJECT, str(e)))

                test_object_content = "Bulk Data Transfer Test"

                operation = None
                test_object_exists = False
                try:
                    operation = "Create object {} in bucket {} using upload user".format(
                        TEST_OBJECT, upload_bucket)
                    object_storage_upload_client.put_object(
                        namespace, upload_bucket, TEST_OBJECT,
                        test_object_content)
                    click.echo(operation)
                    test_object_exists = True

                    operation = "Overwrite object {} in bucket {} using upload user".format(
                        TEST_OBJECT, upload_bucket)
                    object_storage_upload_client.put_object(
                        namespace, upload_bucket, TEST_OBJECT,
                        test_object_content)
                    click.echo(operation)

                    operation = "Inspect object {} in bucket {} using upload user".format(
                        TEST_OBJECT, upload_bucket)
                    object_storage_upload_client.head_object(
                        namespace, upload_bucket, TEST_OBJECT)
                    click.echo(operation)

                    operation = "Read bucket metadata {} using upload user".format(
                        upload_bucket)
                    metadata = object_storage_upload_client.get_bucket(
                        namespace, upload_bucket).data.metadata
                    click.echo(operation)
                except exceptions.ServiceError as se:
                    raise exceptions.RequestException(
                        "Failed to {} in tenancy {} as upload user: {}".format(
                            operation, namespace, se.message))
                finally:
                    if test_object_exists:
                        try:
                            object_storage_admin_client.delete_object(
                                namespace, upload_bucket, TEST_OBJECT)
                        except exceptions.ServiceError as se:
                            raise exceptions.ServiceError(
                                "Failed to delete test object {} as admin user {}: {}"
                                .format(TEST_OBJECT, admin_user, se.message))
            else:
                error_message_wrapper(
                    'Unable to parse the upload user config file. Region not found in %s'
                    % APPLIANCE_UPLOAD_USER_CONFIG_PATH)
        else:
            error_message_wrapper(
                'Unable to parse the config file. Region not found in %s/config'
                % CONFIG_DIR)
    else:
        error_message_wrapper('Unable to parse the config file at %s/config' %
                              CONFIG_DIR)