Module cvpysdk.instances.oracleinstance

File for operating on a Oracle Instance.

OracleInstance is the only class defined in this file.

OracleInstance: Derived class from Instance Base class, representing an oracle instance, and to perform operations on that instance

Oracleinstance

init() – Constructor for the class

restore_to_disk – Performs restore to disk(app free restore)

_get_instance_properties() – gets the properties of this instance

_get_instance_properties_json() – gets all the instance related properties of Oracle instance

_restore_common_options_json() – Setter for the Common options in restore JSON

_restore_destination_json() – Setter for the Oracle destination options in restore JSON

_get_live_sync_oracleopt_json() – Constructs JSON with oracle agent specific options for configuring live sync

_live_sync_restore_json() – Constructs oracle live sync restore JSON by combining common and agent specific options

create_live_sync_schedule() – Creates live sync schedule for the given destination oracle instance

configure_data_masking_policy() – Configures data masking policy with given parameters

get_masking_policy_id() – To get policy id of given data masking policy

standalone_data_masking() – Launch standalone data masking job on given instance

delete_data_masking_policy() – Deletes given data masking policy

_get_browse_options – To get browse options for oracle instance

_process_browse_response – To process browse response

log_stream() – Getter for fetching archive log stream count

oracle_home() – Getter for $ORACLE_HOME of this instance

version() – Getter for oracle database version

is_catalog_enabled() – Getter to check if catalog is enabled for backups

catalog_user() – Getter for getting catalog user

catalog_db() – Getter for catalog database name

archive_log_dest() – Getter for archivelog destination

os_user() – Getter for OS user owning oracle software

cmd_sp() – Getter for command line storage policy

log_sp() – Getter for log storage policy

is_autobackup_on() – Getter to check if autobackup is enabled

db_user() – Getter for SYS database user name

tns_name() – Getter for TNS connect string

dbid() – Getter for getting DBID of database

restore() – Performs restore on the instance

_restore_db_dump_option_json() – setter for the oracle dbdump Restore option in restore JSON

_restore_oracle_option_json() – setter for the oracle Restore option in restore JSON

_restore_json() – returns the JSON request to pass to the API as per the options selected by the user

restore_in_place() – restore for oracle logical dump

Expand source code Browse git
# -*- coding: utf-8 -*-

# --------------------------------------------------------------------------
# Copyright Commvault Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# --------------------------------------------------------------------------
"""
File for operating on a Oracle Instance.

OracleInstance is the only class defined in this file.

OracleInstance: Derived class from Instance Base class, representing an
                            oracle instance, and to perform operations on that instance

OracleInstance:

    __init__()                          --  Constructor for the class

    restore_to_disk                     --  Performs restore to disk(app free restore)

    _get_instance_properties()          --  gets the properties of this instance

    _get_instance_properties_json()     --  gets all the instance related properties
                                            of Oracle instance

    _restore_common_options_json()      --  Setter for the Common options in restore JSON

    _restore_destination_json()         --  Setter for the Oracle destination options in restore JSON


    _get_live_sync_oracleopt_json()     --  Constructs JSON with oracle agent specific options
                                            for configuring live sync

    _live_sync_restore_json()           --  Constructs oracle live sync restore JSON
                                            by combining common and agent specific options

    create_live_sync_schedule()         --  Creates live sync schedule for the given
                                            destination oracle instance

    configure_data_masking_policy()     --  Configures data masking
                                            policy with given parameters

    get_masking_policy_id()             --  To get policy id of
                                            given data masking policy

    standalone_data_masking()           --  Launch standalone data masking
                                            job on given instance

    delete_data_masking_policy()        --  Deletes given data masking policy

    _get_browse_options                 --  To get browse options for oracle instance

    _process_browse_response            --  To process browse response

    log_stream()                        --  Getter for fetching archive log stream count

    oracle_home()                       --  Getter for $ORACLE_HOME of this instance

    version()                           --  Getter for oracle database version

    is_catalog_enabled()                --  Getter to check if catalog is enabled for backups

    catalog_user()                      --  Getter for getting catalog user

    catalog_db()                        --  Getter for catalog database name

    archive_log_dest()                  --  Getter for archivelog destination

    os_user()                           --  Getter for OS user owning oracle software

    cmd_sp()                            --  Getter for command line storage policy

    log_sp()                            --  Getter for log storage policy

    is_autobackup_on()                  --  Getter to check if autobackup is enabled

    db_user()                           --  Getter for SYS database user name

    tns_name()                          --  Getter for TNS connect string

    dbid()                              --  Getter for getting DBID of database

    restore()                           --  Performs restore on the instance
    
    _restore_db_dump_option_json()       --  setter for the oracle dbdump Restore option in restore JSON
    
    _restore_oracle_option_json()       --  setter for the oracle Restore option in restore JSON
    
    _restore_json()                     --  returns the JSON request to pass to the API as per
    the options selected by the user
    
    restore_in_place()                  --  restore for oracle logical dump

"""
from __future__ import unicode_literals
from base64 import b64encode
import json
from ..exception import SDKException
from .dbinstance import DatabaseInstance



class OracleInstance(DatabaseInstance):
    """
    Class to represent a standalone Oracle Instance
    """

    def __init__(self, agent_object, instance_name, instance_id=None):
        """
        Constructor for the class

        Args:
            agent_object    -- instance of the Agent class
            instance_name   -- name of the instance
            instance_id     --  id of the instance

        """
        super(OracleInstance, self).__init__(
            agent_object, instance_name, instance_id)
        self._LIVE_SYNC = self._commcell_object._services['LIVE_SYNC']
        self._dbDump_restore_json = None
        self._oracle_restore_json = None

    def restore_to_disk(self,
                        destination_client,
                        destination_path,
                        backup_job_ids,
                        user_name,
                        password):
        """
        Perform restore to disk [Application free restore] for Oracle

            Args:
                destination_client          (str)   --  destination client name

                destination_path:           (str)   --  destination path

                backup_job_ids              (list)  --  list of backup job IDs
                                                        to be used for disk restore

                user_name                   (str)   --  impersonation user name to
                                                        restore to destination client

                password                    (str)   --  impersonation user password

            Returns:
                object -     Job containing restore details

            Raises:
                SDKException
                    if backup_job_ids not given as list of items

        """
        if not isinstance(backup_job_ids, list):
            raise SDKException('Instance', '101')
        request_json = self._get_restore_to_disk_json(destination_client,
                                                      destination_path,
                                                      backup_job_ids,
                                                      user_name,
                                                      password)
        return self._process_restore_response(request_json)

    def _get_instance_properties(self):
        """Gets the properties of this instance.

            Raises:
                SDKException:
                    if response is empty

                    if response is not success

        """
        super(OracleInstance, self)._get_instance_properties()
        self._instanceprop = self._properties['oracleInstance']

    def _get_instance_properties_json(self):
        """ Gets all the instance related properties of Informix instance.

           Returns:
                dict - all instance properties put inside a dict

        """
        instance_json = {
            "instanceProperties":
                {
                    "instance": self._instance,
                    "oracleInstance": self._instanceprop
                }
        }
        return instance_json

    @property
    def log_stream(self):
        """
        Getter to fetch log stream count at instance level

            Returns:
                    int     --  log stream count atinstance level

        """
        return self._instanceprop.get("numberOfArchiveLogBackupStreams")

    @log_stream.setter
    def log_stream(self, log_stream=1):
        """
        Setter to set log stream count at instance level

            Args:
                log_stream    (int)    --  log stream count at instance level
                                           default = 1
        """
        self._set_instance_properties(
            "_instanceprop['numberOfArchiveLogBackupStreams']", log_stream)

    def _restore_common_options_json(self, value):
        """
        Setter for the Common options in restore JSON

            Args:
                value   (dict)  --  dict of common options
                                    for restore json

        """
        if not isinstance(value, dict):
            raise SDKException('Instance', '101')
        super()._restore_common_options_json(value)
        if value.get("baseline_jobid"):
            self._commonoption_restore_json = (
                {
                    "clusterDBBackedup": value.get("clusterDBBackedup", False),
                    "restoreToDisk": value.get("restoreToDisk", False),
                    "baselineBackup": 1,
                    "baselineRefTime": value.get("baseline_ref_time", ""),
                    "isDBArchiveRestore": value.get("isDBArchiveRestore", False),
                    "baselineJobId": value.get("baseline_jobid", ""),
                    "copyToObjectStore": value.get("copyToObjectStore", False),
                    "onePassRestore": value.get("onePassRestore", False),
                    "syncRestore": value.get("syncRestore", True)
                })

    def _restore_destination_json(self, value):
        """
        Setter for the Oracle destination options in restore JSON

            Args:
                    value   (dict)  --  dict of values for destination option

        """

        if not isinstance(value, dict):
            raise SDKException('Instance', '101')

        self._destination_restore_json = (
            {
                "noOfStreams": value.get("number_of_streams", 2),
                "destClient": {
                    "clientName": value.get("destination_client", "")
                              },
                "destinationInstance": {
                    "clientName": value.get("destination_client", ""),
                    "instanceName": value.get("destination_instance", ""),
                    "appName": value.get("app_name", "Oracle")
                                       }

            })

    def _get_live_sync_oracleopt_json(self, **kwargs):
        """
               Constructs JSON with oracle agent specific options
               for configuring live sync

               Args:
                    **kwargs    (dict)  -- dict of keyword arguments as follows:

                                           redirect_path   (str)- Path on destination client
                                                        to redirect tablespaces and datafiles

        """

        self._oracle_options = {"renamePathForAllTablespaces":"",
                                "redirectAllItemsSelected": False,
                                "validate": False,
                                "ctrlRestoreFrom": True,
                                "noCatalog": True,
                                "cloneEnv":False,
                                "ctrlFileBackupType": 0,
                                "restoreControlFile": True,
                                "duplicate": False,
                                "tableViewRestore": False,
                                "osID":2,
                                "partialRestore": False,
                                "restoreStream":2,
                                "restoreSPFile": False,
                                "recover": True,
                                "oraExtendedRstOptions": 0,
                                "recoverFrom": 3,
                                "archiveLog": False,
                                "restoreData": True,
                                "restoreFrom": 3,
                                "crossmachineRestoreOptions": {
                                "onlineLogDest": ""
                                    },
                                "liveSyncOpt":{
                                    "restoreInStandby":False
                                }
                                }
        if kwargs.get('redirect_path', None) is not None:
            self._oracle_options.update({"renamePathForAllTablespaces": kwargs.get('redirect_path'),
                                         "redirectAllItemsSelected": True,
                                         "redirectItemsPresent": True
                                         })

    def _live_sync_restore_json(self, dest_client, dest_instance, baseline_jobid, baseline_ref_time,
                                schedule_name, source_backupset_id, **kwargs):
        """
               Constructs oracle live sync restore JSON by combining common
               and agent specific options

                   Args:
                       dest_client  (str)   --  The destination client name for live sync

                       dest_instance    (str)   --  The destination instance name for live sync

                       baseline_jobid   (int)   --  The jobid of the baseline backup job

                       baseline_ref_time    (int)   --  The reference time/start time
                                                        of the baseline backup

                       schedule_name    (str)   --  The name of the live sync schedule to be created

                       source_backupset_id  (int)   --  The ID of the source backupset
                                                        of source oracle instance for which
                                                        live sync needs to be configured

                       **kwargs    (dict)  -- dict of keyword arguments as follows:

                                           redirect_path   (str)- Path on destination client
                                                        to redirect tablespaces and datafiles

                    Returns:
                        (str)  --   The live sync restore JSON that is constructed
                                    using oracle and common options

        """

        restore_json = super()._restore_json(destination_client=dest_client,
                                             destination_instance=dest_instance,
                                             baseline_jobid=baseline_jobid,
                                             baseline_ref_time=baseline_ref_time,
                                             syncRestore=True,
                                             no_of_streams=2,
                                            )
        restore_option = {}
        if restore_json.get("restore_option"):
            restore_option = restore_json["restore_option"]
            for key in restore_json:
                if not key == "restore_option":
                    restore_option[key] = restore_json[key]
        else:
            restore_option.update(restore_json)

        self._get_live_sync_oracleopt_json(**kwargs)
        restore_json['taskInfo']['associations'][0]['subclientId'] = -1
        restore_json['taskInfo']['associations'][0]['backupsetId'] = source_backupset_id
        restore_json['taskInfo']['associations'][0]['subclientName'] = ""
        restore_json['taskInfo']['associations'][0]['backupsetName'] = ""
        restore_json['taskInfo']['associations'][0]['_type_'] = 5
        restore_json['taskInfo']['task']['taskType'] = 2
        restore_json['taskInfo']['subTasks'][0]['subTask']['operationType'] = 1007
        restore_json['taskInfo']['subTasks'][0]['subTask']['subTaskName'] = schedule_name
        restore_json['taskInfo']['subTasks'][0]['pattern'] = {
            "freq_type": 4096
        }
        destinationInstance = {
            "clientName":dest_client,
            "instanceName":dest_instance,
            "appName":"Oracle"
        }
        restore_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["destination"].update({"destinationInstance":destinationInstance})
        restore_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["oracleOpt"] = self._oracle_options
        return restore_json

    def create_live_sync_schedule(self, dest_client, dest_instance, schedule_name,
                                  **kwargs):
        """
               Runs full backup on source oracle instance and
               Creates live sync schdule for the given destination oracle instance

                   Args:
                       dest_client  (str)   --  The destination client name for live sync

                       dest_instance    (str)   --  The destination instance name for live sync

                       schedule_name    (str)   --  The name of the live sync schedule to be created

                       **kwargs    (dict)  -- dict of keyword arguments as follows:

                                            redirect_path   (str) --  Path on destination client
                                                            to redirect tablespaces and datafiles

                   Returns:
                        (object)  --   The job object of the baseline backup that will be replicated

        """
        source_backupset_id = int(self.backupsets.get('default').backupset_id)
        subclient_obj = self.subclients.get('default')
        baseline_job_object = subclient_obj.backup(backup_level='full')
        if not baseline_job_object.wait_for_completion():
            raise SDKException('Instance', '102', baseline_job_object.delay_reason)
        baseline_ref_time = baseline_job_object.summary['jobStartTime']
        baseline_jobid = int(baseline_job_object.job_id)
        request_json = self._live_sync_restore_json(dest_client, dest_instance, baseline_jobid,
                                                    baseline_ref_time, schedule_name,
                                                    source_backupset_id, **kwargs)
        flag, response = self._cvpysdk_object.make_request('POST', self._LIVE_SYNC, request_json)
        if flag:
            if response.json():
                if "taskId" in response.json():
                    return baseline_job_object
                elif "errorCode" in response.json():
                    error_message = response.json()['errorMessage']
                    error_message = 'Live Sync configuration failed\nError: "{0}"'.format(
                        error_message)
                    raise SDKException('Instance', '102', error_message)
                else:
                    raise SDKException('Instance', '102', 'Failed to create schedule')
            else:
                raise SDKException('Instance', '102')
        else:
            raise SDKException('Instance', '101', self._update_response_(response.text))

    def configure_data_masking_policy(self, policy_name, table_list_of_dict):
        """Configures data masking policy with given parameters
        Args:
            policy_name         (str)   --  string representing policy name
            table_list_of_dict  list(dict)  -- list containing one dict item representing
                                                rules for single table
            Sample  list
            Tables:
                    [
                    {
                    "name":"schema_name.table_name",
                    "columns": [ {"name":"column_name", "type":"algorithm_type"},
                                "arguments":[list of strings]…]
                    }
                    ]
                    Sample :
                    [
                    {
                    "name":"HR.NUMNEW",
                    "columns":[{"name":"N1","type":0},{"name":"N2","type":2,
                    "arguments":["1000","2000"]}]
                    },
                    {
                    "name":"HR.CHANGE",
                    "columns":[{"name":"C1","type":1},{"name":"C2","type":1}]
                    }
                    ]
            schema_name , table_name, column_name: str
            Column type key in main dict takes list of dict as value :
            This list of dict represents each column name and type of algorithm
            and arguments if any for that algorithm
            arguments : list of strings

            Choose appropriate algorithm type and pass necessary arguments based
            on column type

            Algorithm       Arguments mandatory       Arguments Format        Algorithm type number

            Shuffling           NA                              NA                      0
            Numeric Range       [min, max]                  ["1000","2000"]             2
            Numeric Variance    [variance percentage]           ["50"]                  3
            FPE                 NA                              NA                      1
            Fixed String        string_to_replace           ["string_to_replace"]       4


            Supported Algorithms :

            Column Type     Algorithms Supported

            Numeric         Shuffling, FPE, Numeric Range, Numeric Variance
            Char            Shuffling , FPE , Fixed String
            Varchar         Shuffling , FPE , Fixed String

        """
        request_json = {
            "opType": 2,
            "policy": {
                "association": {"instanceId": int(self.instance_id)},
                "config": {"tables": table_list_of_dict},
                "policy": {"policyName": policy_name}
            }
        }

        flag, response = self._cvpysdk_object.make_request(
            'POST', self._services['MASKING_POLICY'], request_json
        )
        if flag:
            if response.json():
                error_code = response.json()['errorCode']

                if error_code != 0:
                    error_string = response.json()['errorMessage']
                    raise SDKException(
                        'Instance',
                        '102',
                        'Error while creating Data masking policy\nError: "{0}"'.format(
                            error_string)
                    )
                else:
                    return True

            else:
                raise SDKException('Response', '102')
        else:
            raise SDKException('Response', '101',
                               self._update_response_(response.text))

    def get_masking_policy_id(self, policy_name):
        """Returns policy id of given data masking policy
        Args:
            policy_name          (str)       -- data masking policy name

        Returns:
            policy_id            (int)       -- data masking policy ID

        """
        instance_id = int(self.instance_id)
        flag, response = self._cvpysdk_object.make_request(
            'GET', self._services['MASKING_POLICY'])
        response_json = response.json()
        policy_list = response_json["policies"]
        policy_id = None
        for i in policy_list:
            pname = i["policy"]["policyName"]
            associated_instance_id = i["association"]["instanceId"]
            if (pname == policy_name) and (associated_instance_id == instance_id):
                policy_id = int(i["policy"]["policyId"])
                break
            else:
                continue
        return policy_id

    def delete_data_masking_policy(self, policy_name):
        """Deletes given data masking policy
        Args:
            policy_name         (str)       --  data masking policy name to be deleted

        Returns:
            bool                            -- returns true when deletion succeeds

        Raises:
            Exception

                When deletion of policy fails

                When Invalid policy name under given instance is provided
        """
        source_instance_id = int(self.instance_id)
        policy_id = self.get_masking_policy_id(policy_name)
        if policy_id is None:
            raise SDKException(
                'Instance',
                '106')

        request_json = {
            "opType": 3,
            "policy": {
                "association": {"instanceId": source_instance_id},
                "policy": {"policyId": policy_id, "policyName": policy_name}
            }
        }

        flag, response = self._cvpysdk_object.make_request(
            'POST', self._services['MASKING_POLICY'], request_json
        )
        if flag:
            if response.json():
                error_code = response.json()['errorCode']

                if error_code != 0:
                    raise SDKException(
                        'Instance',
                        '102',
                        'Error while deleting Data masking policy\nError')
                else:
                    return True

            else:
                raise SDKException('Response', '102')
        else:
            raise SDKException('Response', '101',
                               self._update_response_(response.text))

    def standalone_data_masking(
            self,
            policy_name,
            destination_client=None,
            destination_instance=None):
        """Launch standalone data masking job on given instance

        Args:

            policy_name          (str)       -- data masking policy name

            destination_client   (str)       -- destination client in which destination
            instance exists

            destination_instance (str)       -- destination instance to which masking
            to be applied

        Returns:
            object -- Job containing data masking job details


        Raises:
            SDKException
                if policy ID retrieved is None

        """
        if destination_client is None:
            destination_client = self._properties['instance']['clientName']
        if destination_instance is None:
            destination_instance = self.instance_name
        destination_client_object = self._commcell_object.clients.get(
            destination_client)
        destination_agent_object = destination_client_object.agents.get(
            'oracle')
        destination_instance_object = destination_agent_object.instances.get(
            destination_instance)
        destination_instance_id = int(destination_instance_object.instance_id)
        source_instance_id = int(self.instance_id)
        policy_id = self.get_masking_policy_id(policy_name)
        if policy_id is None:
            raise SDKException(
                'Instance',
                '106')
        request_json = self._restore_json(paths=r'/')
        destination_instance_json = {
            "clientName": destination_client,
            "instanceName": destination_instance,
            "instanceId": destination_instance_id
        }
        data_masking_options = {
            "isStandalone": True,
            "enabled": True,
            "dbDMPolicy": {
                "association": {
                    "instanceId": source_instance_id},
                "policy": {
                    "policyId": policy_id,
                    "policyName": policy_name}}}
        request_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["destination"]["destClient"]["clientName"] = destination_client
        request_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["destination"]["destinationInstance"] = destination_instance_json
        request_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["dbDataMaskingOptions"] = data_masking_options
        del request_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["fileOption"]
        return self._process_restore_response(request_json)

    def _get_oracle_restore_json(self, destination_client,
                                 instance_name, tablespaces,
                                 files, browse_option,
                                 common_options, oracle_options, destination=None):
        """
        Gets the basic restore JSON from base class and modifies it for oracle

        Args:
            destination_client  (str)   --  Destination client name

            instance_name   (str)   --  instance name to restore

            tablespaces (list)  --  tablespace name list

            files   (dict)  --  fileOptions

            browse_option   (dict)  --  dict containing browse options

            common_options  (dict)  --  dict containing common options

            oracle_options  (dict)  --  dict containing other oracle options

            destination     (dict)  --  dictionary with destination client and instance names
                default" None

        Returns:
            (dict) -- JSON formatted options to restore the oracle database

        Raises:
            SDKException:
                if tablespace is passed as a list
                if files is not passed as a dictionary

        """
        if not isinstance(tablespaces, list):
            raise SDKException(
                'Instance',
                '101', 'Expecting a list for tablespaces')
        if files is not None:
            if not isinstance(files, dict):
                raise SDKException(
                    'Instance',
                    '101', 'Expecting a dict for files')

        destination_id = int(self._commcell_object.clients.get(
            destination_client).client_id)
        tslist = ["SID: {0} Tablespace: {1}".format(
            instance_name, ts) for ts in tablespaces]
        restore_json = self._restore_json(paths=r'/')
        if common_options is not None:
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"][
                "commonOptions"] = common_options
        restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"][
            "oracleOpt"] = oracle_options
        if destination:
            if not isinstance(destination, dict):
                raise SDKException(
                    'Instance',
                    '101', 'Expecting a dict for destination details')
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["destination"] = destination
        if files is None:
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["fileOption"] = {
                "sourceItem": tslist
            }
        else:
            restore_json["taskInfo"]["subTasks"][0]["options"][
                "restoreOptions"]["fileOption"] = files

        if browse_option is not None:
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"][
                "browseOption"] = browse_option
        return restore_json

    def _get_browse_options(self):
        """Returns the database instance properties for browse and restore"""
        return {
            "path": "/",
            "entity": {
                "appName": self._properties['instance']['appName'],
                "instanceId": int(self.instance_id),
                "applicationId": int(self._properties['instance']['applicationId']),
                "clientId": int(self._properties['instance']['clientId']),
                "instanceName": self._properties['instance']['instanceName'],
                "clientName": self._properties['instance']['clientName']
            }
        }

    def _process_browse_response(self, request_json):
        """Runs the DBBrowse API with the request JSON provided for Browse,
            and returns the contents after parsing the response.

            Args:
                request_json    (dict)  --  JSON request to run for the API

            Returns:
                list - list containing tablespaces for the instance

            Raises:
                SDKException:
                    if browse job failed

                    if browse is empty

                    if browse is not success
        """
        if 'tablespaces' in self._instanceprop:
            return self._instanceprop['tablespaces']

        browse_service = self._commcell_object._services['ORACLE_INSTANCE_BROWSE'] % (
            self.instance_id
        )

        flag, response = self._commcell_object._cvpysdk_object.make_request(
            'POST', browse_service, request_json
        )

        if flag:
            response_data = json.loads(response.text)
            if response_data:
                if "oracleContent" in response_data:
                    self._instanceprop['tablespaces'] = response_data["oracleContent"]
                    return self._instanceprop['tablespaces']
                elif "errorCode" in response_data:
                    error_message = response_data['errorMessage']
                    o_str = 'Browse job failed\nError: "{0}"'.format(
                        error_message)
                    raise SDKException('Instance', '102', o_str)
            else:
                raise SDKException('Response', '102')
        else:
            response_string = self._commcell_object._update_response_(
                response.text)
            raise SDKException('Response', '101', response_string)

    @property
    def oracle_home(self):
        """
        getter for oracle home

        Returns:
            string - string of oracle_home

        """
        return self._properties['oracleInstance']['oracleHome']

    @property
    def is_catalog_enabled(self):
        """
        Getter to check if catalog has been enabled

        Returns:
            Bool - True if catalog is enabled. Else False.

        """
        return self._properties['oracleInstance']['useCatalogConnect']

    @property
    def catalog_user(self):
        """
        Getter for catalog user

        Returns:
            string  - String containing catalog user

        Raises:
            SDKException:
                if not set

                if catalog is not enabled

        """
        if not self.is_catalog_enabled:
            raise SDKException('Instance', r'102', 'Catalog is not enabled.')
        try:
            return self._properties['oracleInstance']['catalogConnect']['userName']
        except KeyError as error_str:
            raise SDKException('Instance', r'102',
                               'Catalog user not set - {}'.format(error_str))

    @property
    def catalog_db(self):
        """
        Getter for catalog database

        Returns:
            string  - String containing catalog database

        Raises:
            SDKException:
                if not set

                if catalog is not enabled

        """
        if not self.is_catalog_enabled:
            raise SDKException('Instance', r'102', 'Catalog is not enabled.')
        try:
            return self._properties['oracleInstance']['catalogConnect']['domainName']
        except KeyError as error_str:
            raise SDKException('Instance', r'102',
                               'Catalog database not set - {}'.format(error_str))

    @property
    def os_user(self):
        """
        Getter for oracle software owner

        Returns:
            string - string of oracle software owner

        """
        return self._properties['oracleInstance']['oracleUser']['userName']

    @property
    def version(self):
        """
        Getter for oracle version

        Returns:
            string - string of oracle instance version

        """
        return self._properties['version']

    @property
    def archive_log_dest(self):
        """
        Getter for the instance's archive log dest

        Returns:
            string - string for archivelog location

        """
        return self._properties['oracleInstance']['archiveLogDest']

    @property
    def cmd_sp(self):
        """
        Getter for Command Line storage policy

        Returns:
            string - string for command line storage policy

        """
        return self._properties['oracleInstance']['oracleStorageDevice'][
            'commandLineStoragePolicy']['storagePolicyName']

    @property
    def log_sp(self):
        """
        Oracle Instance's Log Storage Poplicy

        Returns:
            string  -- string containing log storage policy

        """
        return self._properties['oracleInstance']['oracleStorageDevice'][
            'logBackupStoragePolicy']['storagePolicyName']

    @property
    def is_autobackup_on(self):
        """
        Getter to check whether autobackup is set to ON

        Returns:
            Bool - True if autobackup is set to ON. Else False.

        """
        return True if self._properties['oracleInstance']['ctrlFileAutoBackup'] == 1 else False

    @property
    def db_user(self):
        """
        Getter to get the database user used to log into the database

        Returns: Oracle database user for the instance

        """
        return self._properties['oracleInstance']['sqlConnect']['userName']

    @property
    def tns_name(self):
        """
        Getter to get the TNS Names of the database

        Returns:
            string  -- TNS name of the instance configured

        Raises:
            SDKException:
                if not set

        """
        try:
            return self._properties['oracleInstance']['sqlConnect']['domainName']
        except KeyError as error_str:
            raise SDKException('Instance', r'102',
                               'Instance TNS Entry not set - {}'.format(error_str))

    @property
    def dbid(self):
        """
        Getter to get the DBID of the database instance

        Returns: DBID of the oracle database

        """
        return self._properties['oracleInstance']['DBID']

    @property
    def tablespaces(self):
        """
        Getter for listing out all tablespaces for the instance

        Returns:
            list -- list containing tablespace names for the database

        """
        return [ts['tableSpace'] for ts in self.browse()]

    def browse(self, *args, **kwargs):
        """Overridden method to browse oracle database tablespaces"""
        if args and isinstance(args[0], dict):
            options = args[0]
        elif kwargs:
            options = kwargs
        else:
            options = self._get_browse_options()
        return self._process_browse_response(options)

    def backup(self, subclient_name=r"default"):
        """Uses the default subclient to backup the database

        Args:
            subclient_name (str) -- name of subclient to use
                default: default
        """
        return self.subclients.get(subclient_name).backup(r'full')

    def restore(
            self,
            files=None,
            destination_client=None,
            common_options=None,
            browse_option=None,
            oracle_options={},
            tag=None,
            destination_instance=None,
            streams=2):
        """
        Perform restore full/partial database using latest backup or backup copy

        Args:
            files               (dict)      --  fileOption for restore

            destination_client  (str)       --  destination client name

            common_options      (dict)      --  dictionary containing common options
                default:    None

            browse_option       (dict)      --  dictionary containing browse options

            oracle_options      (dict)      --  dictionary containing other oracle options
                default:    By default it restores the controlfile and datafiles from latest backup

                Example:{
                            "resetLogs": 1,
                            "switchDatabaseMode": True,
                            "noCatalog": True,
                            "restoreControlFile": True,
                            "recover": True,
                            "recoverFrom": 3,
                            "restoreData": True,
                            "restoreFrom": 3
                        }

            tag                 (str)       --  Type of the restore to be performed
                default:    None

            destination_instance(str)       --  destination instance name
                default:    None (in place restore)

            streams             (int)       --  number of streams for restore
                default: 2


        Returns:
            object  --  Job containing restore details

        Raises:
            SDKException:
                If oracle options can't be set

                If destination_client can't be set

        """
        options = {
            "resetLogs": 1,
            "switchDatabaseMode": True,
            "noCatalog": True,
            "recover": True,
            "recoverFrom": 3,
            "restoreData": True,
            "restoreFrom": 3
        }
        options.update(oracle_options)
        oracle_options = options.copy()

        if tag and tag.lower() == 'snap':
            opt = {
                "useSnapRestore": True,
                "cleanupAuxiliary": True,
                "restoreControlFile": True,
            }
            oracle_options.update(opt)

        try:
            if destination_client is None or destination_instance is None:
                destination_client = self._properties['instance']['clientName']
                destination_instance = self._properties['instance']['instanceName']
            destination = {
                "destination_client": destination_client,
                "destination_instance": destination_instance
            }
            if tag and tag.lower()=="rac":
                stream_allocation = self._get_rac_stream_allocation(
                    destination_client, destination_instance, streams)
                oracle_options.update(stream_allocation)
                destination["app_name"] = "Oracle RAC"
            self._restore_destination_json(destination)
        except SDKException:
            raise SDKException("Instance", "105")
        else:
            # subclient = self.subclients.get(subclient_name)
            if destination_client and destination_instance:
                options = self._get_oracle_restore_json(destination_client=destination_client,
                                                        destination=self._destination_restore_json,
                                                        instance_name=self.instance_name,
                                                        tablespaces=self.tablespaces,
                                                        files=files,
                                                        browse_option=browse_option,
                                                        common_options=common_options,
                                                        oracle_options=oracle_options)
            else:
                options = self._get_oracle_restore_json(destination_client=destination_client,
                                                        instance_name=self.instance_name,
                                                        tablespaces=self.tablespaces,
                                                        files=files,
                                                        browse_option=browse_option,
                                                        common_options=common_options,
                                                        oracle_options=oracle_options)
            return self._process_restore_response(options)
            
    def _get_rac_stream_allocation(self, destination_client, destination_instance, streams):
        """setter for RAC stream allocation on nodes data population in oracle options for restore
            Args:
                destination_client  (str) -- Name of the destination client
                destination_instance(str) -- Name of the destination RAC instance
                streams             (int)    -- Number of streams for restore
        """
        destination_client_obj = self._commcell_object.clients.get(destination_client)
        destination_instance_obj = destination_client_obj.agents.get("Oracle RAC").instances.get(destination_instance)
        rac_stream_allocation = {"racDataStreamAllcation": []}
        for node in destination_instance_obj.properties['oracleRACInstance']['racDBInstance']:
            rac_stream_allocation["racDataStreamAllcation"].append(f"{node['racDbInstanceId']} {streams}")
        return rac_stream_allocation

    def _restore_db_dump_option_json(self,value):
        """setter for the oracle dbdump Restore option in restore JSON
            Args:
                value   (dict)  --  Dictionary of options need to be set for restore
        """
        if not isinstance(value,dict):
            raise SDKException('Instance','101')
            
        self._db_dump_restore_json = {
            "importToDatabase": True,
            "parallelism": 2,
            "restorePath": value.get("destination_path", ""),
            "overwriteTable": False,
            "enabled": True,
            "connectDetails": {
                "password": b64encode(value.get("db_password", "").encode()).decode(),
                "domainName": (self._properties.get("oracleInstance", {}).
                    get("sqlConnect", {}).get("domainName", "")),
                "userName": (self._properties.get("oracleInstance", {}).
                    get("sqlConnect", {}).get("userName", ""))
            }
        }


    def _restore_oracle_option_json(self, value):
        """setter for the oracle Restore option in restore JSON
        Args:
                value   (dict)  --  Dictionary of options need to be set for restore
        """
        if not isinstance(value,dict):
            raise SDKException('Instance','101')

        self._oracle_restore_json = {
            "validate": False,
            "noCatalog": False,
            "duplicateToName": "",
            "cloneEnv": False,
            "restoreControlFile": False,
            "duplicate": False,
            "tableViewRestore": False,
            "osID": 2,
            "partialRestore": False,
            "restoreStream": 2,
            "restoreSPFile": False,
            "recover": True,
            "recoverFrom": 4,
            "archiveLog": False,
            "restoreData": True,
            "restoreFrom": 0,
            "timeZone": {
                "TimeZoneName": "(UTC) Coordinated Universal Time"
            },
            "recoverTime": {},
            "sourcePaths": [
                "//**"
            ],
            "restoreTime": {}
        }

        if value.get("restore_oracle_options_type") == "restore_archivelogs_norecover":
            self._oracle_restore_json = {
                "resetLogs": 0,
                "backupValidationOnly": False,
                "threadId": 1,
                "deviceType": 0,
                "restoreFailover": True,
                "resetDatabase": False,
                "noCatalog": True,
                "ctrlRestoreFrom": False,
                "controlFilePath": "",
                "specifyControlFileTime": False,
                "restoreDataTag": False,
                "useEndLSN": False,
                "useStartLSN": False,
                "restoreTablespace": False,
                "archiveLogBy": 1,
                "ctrlFileBackupType": 0,
                "restoreControlFile": False,
                "restoreInstanceLog": False,
                "duplicate": False,
                "startLSNNum": "",
                "checkReadOnly": False,
                "osID": 2,
                "specifyControlFile": False,
                "setDBId": False,
                "partialRestore": False,
                "restoreStream": 2,
                "specifySPFile": False,
                "restoreSPFile": False,
                "recover": False,
                "recoverFrom": 4,
                "archiveLog": True,
                "endLSNNum": "",
                "autoDetectDevice": True,
                "useEndLog": False,
                "isDeviceTypeSelected": False,
                "useStartLog": True,
                "logTarget": "",
                "restoreData": False,
                "restoreFrom": 0,
                "duplicateToSkipReadOnly": False
            }
            if value.get("start_lsn", None):
                self._oracle_restore_json["useStartLSN"] = True
                self._oracle_restore_json["startLSNNum"] = value.get("start_lsn")
            if value.get("end_lsn", None):
                self._oracle_restore_json["useEndLSN"] = True
                self._oracle_restore_json["endLSNNum"] = value.get("end_lsn")
            if value.get("log_dest", None):
                self._oracle_restore_json["logTarget"] = value.get("log_dest")

    def _restore_json(self, **kwargs):
        """Returns the JSON request to pass to the API as per the options selected by the user.

            Args:
                kwargs   (dict)  --  Dictionary of options need to be set for restore

            Returns:
                dict             -- JSON request to pass to the API

        """
        rest_json = super(OracleInstance, self)._restore_json(**kwargs)
        restore_option = {}
        if kwargs.get("restore_option"):
            restore_option = kwargs["restore_option"]
            for key in kwargs:
                if not key == "restore_option":
                    restore_option[key] = kwargs[key]
        else:
            restore_option.update(kwargs)

        self._restore_db_dump_option_json(restore_option)
        self._restore_oracle_option_json(restore_option)
        rest_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["dbDumpOptions"] = self._db_dump_restore_json
        rest_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["oracleOpt"] = self._oracle_restore_json

        return rest_json

    def restore_in_place(
            self,
            db_password,
            path,
            dest_client_name,
            dest_instance_name,
            dest_path=None,
            restore_oracle_options_type=None,
            start_lsn=None, end_lsn=None,
            log_dest=None):
        """Restores the oracle logical dump data/log files specified in the input paths
        list to the same location.

            Args:
                
                db_password             (str)  -- password for oracle database
                
                path                    (list)  --  list of database/databases to be restored

                dest_client_name        (str)   --  destination client name where files are to be
                restored

                dest_instance_name      (str)   --  destination postgres instance name of
                destination client

                dest_path        (str)   --  destinath path for restore

                    default: None

            Returns:
                object - instance of the Job class for this restore job

            Raises:
                SDKException:
                    if paths is not a list

                    if failed to initialize job

                    if response is empty

                    if response is not success

        """
        if not (isinstance(path, list) and
                isinstance(db_password, str)):
            raise SDKException('Instance', '101')
        if not path:
            raise SDKException('Instance','103')
        

        request_json = self._restore_json(
            db_password=db_password,
            paths=path,
            destination_client=dest_client_name,
            destination_instance=dest_instance_name,
            destination_path=dest_path,
            restore_oracle_options_type=restore_oracle_options_type,
            start_lsn=start_lsn, end_lsn=end_lsn,
            log_dest=log_dest)

        return self._process_restore_response(request_json)

Classes

class OracleInstance (agent_object, instance_name, instance_id=None)

Class to represent a standalone Oracle Instance

Constructor for the class

Args

agent_object – instance of the Agent class instance_name – name of the instance instance_id – id of the instance

Expand source code Browse git
class OracleInstance(DatabaseInstance):
    """
    Class to represent a standalone Oracle Instance
    """

    def __init__(self, agent_object, instance_name, instance_id=None):
        """
        Constructor for the class

        Args:
            agent_object    -- instance of the Agent class
            instance_name   -- name of the instance
            instance_id     --  id of the instance

        """
        super(OracleInstance, self).__init__(
            agent_object, instance_name, instance_id)
        self._LIVE_SYNC = self._commcell_object._services['LIVE_SYNC']
        self._dbDump_restore_json = None
        self._oracle_restore_json = None

    def restore_to_disk(self,
                        destination_client,
                        destination_path,
                        backup_job_ids,
                        user_name,
                        password):
        """
        Perform restore to disk [Application free restore] for Oracle

            Args:
                destination_client          (str)   --  destination client name

                destination_path:           (str)   --  destination path

                backup_job_ids              (list)  --  list of backup job IDs
                                                        to be used for disk restore

                user_name                   (str)   --  impersonation user name to
                                                        restore to destination client

                password                    (str)   --  impersonation user password

            Returns:
                object -     Job containing restore details

            Raises:
                SDKException
                    if backup_job_ids not given as list of items

        """
        if not isinstance(backup_job_ids, list):
            raise SDKException('Instance', '101')
        request_json = self._get_restore_to_disk_json(destination_client,
                                                      destination_path,
                                                      backup_job_ids,
                                                      user_name,
                                                      password)
        return self._process_restore_response(request_json)

    def _get_instance_properties(self):
        """Gets the properties of this instance.

            Raises:
                SDKException:
                    if response is empty

                    if response is not success

        """
        super(OracleInstance, self)._get_instance_properties()
        self._instanceprop = self._properties['oracleInstance']

    def _get_instance_properties_json(self):
        """ Gets all the instance related properties of Informix instance.

           Returns:
                dict - all instance properties put inside a dict

        """
        instance_json = {
            "instanceProperties":
                {
                    "instance": self._instance,
                    "oracleInstance": self._instanceprop
                }
        }
        return instance_json

    @property
    def log_stream(self):
        """
        Getter to fetch log stream count at instance level

            Returns:
                    int     --  log stream count atinstance level

        """
        return self._instanceprop.get("numberOfArchiveLogBackupStreams")

    @log_stream.setter
    def log_stream(self, log_stream=1):
        """
        Setter to set log stream count at instance level

            Args:
                log_stream    (int)    --  log stream count at instance level
                                           default = 1
        """
        self._set_instance_properties(
            "_instanceprop['numberOfArchiveLogBackupStreams']", log_stream)

    def _restore_common_options_json(self, value):
        """
        Setter for the Common options in restore JSON

            Args:
                value   (dict)  --  dict of common options
                                    for restore json

        """
        if not isinstance(value, dict):
            raise SDKException('Instance', '101')
        super()._restore_common_options_json(value)
        if value.get("baseline_jobid"):
            self._commonoption_restore_json = (
                {
                    "clusterDBBackedup": value.get("clusterDBBackedup", False),
                    "restoreToDisk": value.get("restoreToDisk", False),
                    "baselineBackup": 1,
                    "baselineRefTime": value.get("baseline_ref_time", ""),
                    "isDBArchiveRestore": value.get("isDBArchiveRestore", False),
                    "baselineJobId": value.get("baseline_jobid", ""),
                    "copyToObjectStore": value.get("copyToObjectStore", False),
                    "onePassRestore": value.get("onePassRestore", False),
                    "syncRestore": value.get("syncRestore", True)
                })

    def _restore_destination_json(self, value):
        """
        Setter for the Oracle destination options in restore JSON

            Args:
                    value   (dict)  --  dict of values for destination option

        """

        if not isinstance(value, dict):
            raise SDKException('Instance', '101')

        self._destination_restore_json = (
            {
                "noOfStreams": value.get("number_of_streams", 2),
                "destClient": {
                    "clientName": value.get("destination_client", "")
                              },
                "destinationInstance": {
                    "clientName": value.get("destination_client", ""),
                    "instanceName": value.get("destination_instance", ""),
                    "appName": value.get("app_name", "Oracle")
                                       }

            })

    def _get_live_sync_oracleopt_json(self, **kwargs):
        """
               Constructs JSON with oracle agent specific options
               for configuring live sync

               Args:
                    **kwargs    (dict)  -- dict of keyword arguments as follows:

                                           redirect_path   (str)- Path on destination client
                                                        to redirect tablespaces and datafiles

        """

        self._oracle_options = {"renamePathForAllTablespaces":"",
                                "redirectAllItemsSelected": False,
                                "validate": False,
                                "ctrlRestoreFrom": True,
                                "noCatalog": True,
                                "cloneEnv":False,
                                "ctrlFileBackupType": 0,
                                "restoreControlFile": True,
                                "duplicate": False,
                                "tableViewRestore": False,
                                "osID":2,
                                "partialRestore": False,
                                "restoreStream":2,
                                "restoreSPFile": False,
                                "recover": True,
                                "oraExtendedRstOptions": 0,
                                "recoverFrom": 3,
                                "archiveLog": False,
                                "restoreData": True,
                                "restoreFrom": 3,
                                "crossmachineRestoreOptions": {
                                "onlineLogDest": ""
                                    },
                                "liveSyncOpt":{
                                    "restoreInStandby":False
                                }
                                }
        if kwargs.get('redirect_path', None) is not None:
            self._oracle_options.update({"renamePathForAllTablespaces": kwargs.get('redirect_path'),
                                         "redirectAllItemsSelected": True,
                                         "redirectItemsPresent": True
                                         })

    def _live_sync_restore_json(self, dest_client, dest_instance, baseline_jobid, baseline_ref_time,
                                schedule_name, source_backupset_id, **kwargs):
        """
               Constructs oracle live sync restore JSON by combining common
               and agent specific options

                   Args:
                       dest_client  (str)   --  The destination client name for live sync

                       dest_instance    (str)   --  The destination instance name for live sync

                       baseline_jobid   (int)   --  The jobid of the baseline backup job

                       baseline_ref_time    (int)   --  The reference time/start time
                                                        of the baseline backup

                       schedule_name    (str)   --  The name of the live sync schedule to be created

                       source_backupset_id  (int)   --  The ID of the source backupset
                                                        of source oracle instance for which
                                                        live sync needs to be configured

                       **kwargs    (dict)  -- dict of keyword arguments as follows:

                                           redirect_path   (str)- Path on destination client
                                                        to redirect tablespaces and datafiles

                    Returns:
                        (str)  --   The live sync restore JSON that is constructed
                                    using oracle and common options

        """

        restore_json = super()._restore_json(destination_client=dest_client,
                                             destination_instance=dest_instance,
                                             baseline_jobid=baseline_jobid,
                                             baseline_ref_time=baseline_ref_time,
                                             syncRestore=True,
                                             no_of_streams=2,
                                            )
        restore_option = {}
        if restore_json.get("restore_option"):
            restore_option = restore_json["restore_option"]
            for key in restore_json:
                if not key == "restore_option":
                    restore_option[key] = restore_json[key]
        else:
            restore_option.update(restore_json)

        self._get_live_sync_oracleopt_json(**kwargs)
        restore_json['taskInfo']['associations'][0]['subclientId'] = -1
        restore_json['taskInfo']['associations'][0]['backupsetId'] = source_backupset_id
        restore_json['taskInfo']['associations'][0]['subclientName'] = ""
        restore_json['taskInfo']['associations'][0]['backupsetName'] = ""
        restore_json['taskInfo']['associations'][0]['_type_'] = 5
        restore_json['taskInfo']['task']['taskType'] = 2
        restore_json['taskInfo']['subTasks'][0]['subTask']['operationType'] = 1007
        restore_json['taskInfo']['subTasks'][0]['subTask']['subTaskName'] = schedule_name
        restore_json['taskInfo']['subTasks'][0]['pattern'] = {
            "freq_type": 4096
        }
        destinationInstance = {
            "clientName":dest_client,
            "instanceName":dest_instance,
            "appName":"Oracle"
        }
        restore_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["destination"].update({"destinationInstance":destinationInstance})
        restore_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["oracleOpt"] = self._oracle_options
        return restore_json

    def create_live_sync_schedule(self, dest_client, dest_instance, schedule_name,
                                  **kwargs):
        """
               Runs full backup on source oracle instance and
               Creates live sync schdule for the given destination oracle instance

                   Args:
                       dest_client  (str)   --  The destination client name for live sync

                       dest_instance    (str)   --  The destination instance name for live sync

                       schedule_name    (str)   --  The name of the live sync schedule to be created

                       **kwargs    (dict)  -- dict of keyword arguments as follows:

                                            redirect_path   (str) --  Path on destination client
                                                            to redirect tablespaces and datafiles

                   Returns:
                        (object)  --   The job object of the baseline backup that will be replicated

        """
        source_backupset_id = int(self.backupsets.get('default').backupset_id)
        subclient_obj = self.subclients.get('default')
        baseline_job_object = subclient_obj.backup(backup_level='full')
        if not baseline_job_object.wait_for_completion():
            raise SDKException('Instance', '102', baseline_job_object.delay_reason)
        baseline_ref_time = baseline_job_object.summary['jobStartTime']
        baseline_jobid = int(baseline_job_object.job_id)
        request_json = self._live_sync_restore_json(dest_client, dest_instance, baseline_jobid,
                                                    baseline_ref_time, schedule_name,
                                                    source_backupset_id, **kwargs)
        flag, response = self._cvpysdk_object.make_request('POST', self._LIVE_SYNC, request_json)
        if flag:
            if response.json():
                if "taskId" in response.json():
                    return baseline_job_object
                elif "errorCode" in response.json():
                    error_message = response.json()['errorMessage']
                    error_message = 'Live Sync configuration failed\nError: "{0}"'.format(
                        error_message)
                    raise SDKException('Instance', '102', error_message)
                else:
                    raise SDKException('Instance', '102', 'Failed to create schedule')
            else:
                raise SDKException('Instance', '102')
        else:
            raise SDKException('Instance', '101', self._update_response_(response.text))

    def configure_data_masking_policy(self, policy_name, table_list_of_dict):
        """Configures data masking policy with given parameters
        Args:
            policy_name         (str)   --  string representing policy name
            table_list_of_dict  list(dict)  -- list containing one dict item representing
                                                rules for single table
            Sample  list
            Tables:
                    [
                    {
                    "name":"schema_name.table_name",
                    "columns": [ {"name":"column_name", "type":"algorithm_type"},
                                "arguments":[list of strings]…]
                    }
                    ]
                    Sample :
                    [
                    {
                    "name":"HR.NUMNEW",
                    "columns":[{"name":"N1","type":0},{"name":"N2","type":2,
                    "arguments":["1000","2000"]}]
                    },
                    {
                    "name":"HR.CHANGE",
                    "columns":[{"name":"C1","type":1},{"name":"C2","type":1}]
                    }
                    ]
            schema_name , table_name, column_name: str
            Column type key in main dict takes list of dict as value :
            This list of dict represents each column name and type of algorithm
            and arguments if any for that algorithm
            arguments : list of strings

            Choose appropriate algorithm type and pass necessary arguments based
            on column type

            Algorithm       Arguments mandatory       Arguments Format        Algorithm type number

            Shuffling           NA                              NA                      0
            Numeric Range       [min, max]                  ["1000","2000"]             2
            Numeric Variance    [variance percentage]           ["50"]                  3
            FPE                 NA                              NA                      1
            Fixed String        string_to_replace           ["string_to_replace"]       4


            Supported Algorithms :

            Column Type     Algorithms Supported

            Numeric         Shuffling, FPE, Numeric Range, Numeric Variance
            Char            Shuffling , FPE , Fixed String
            Varchar         Shuffling , FPE , Fixed String

        """
        request_json = {
            "opType": 2,
            "policy": {
                "association": {"instanceId": int(self.instance_id)},
                "config": {"tables": table_list_of_dict},
                "policy": {"policyName": policy_name}
            }
        }

        flag, response = self._cvpysdk_object.make_request(
            'POST', self._services['MASKING_POLICY'], request_json
        )
        if flag:
            if response.json():
                error_code = response.json()['errorCode']

                if error_code != 0:
                    error_string = response.json()['errorMessage']
                    raise SDKException(
                        'Instance',
                        '102',
                        'Error while creating Data masking policy\nError: "{0}"'.format(
                            error_string)
                    )
                else:
                    return True

            else:
                raise SDKException('Response', '102')
        else:
            raise SDKException('Response', '101',
                               self._update_response_(response.text))

    def get_masking_policy_id(self, policy_name):
        """Returns policy id of given data masking policy
        Args:
            policy_name          (str)       -- data masking policy name

        Returns:
            policy_id            (int)       -- data masking policy ID

        """
        instance_id = int(self.instance_id)
        flag, response = self._cvpysdk_object.make_request(
            'GET', self._services['MASKING_POLICY'])
        response_json = response.json()
        policy_list = response_json["policies"]
        policy_id = None
        for i in policy_list:
            pname = i["policy"]["policyName"]
            associated_instance_id = i["association"]["instanceId"]
            if (pname == policy_name) and (associated_instance_id == instance_id):
                policy_id = int(i["policy"]["policyId"])
                break
            else:
                continue
        return policy_id

    def delete_data_masking_policy(self, policy_name):
        """Deletes given data masking policy
        Args:
            policy_name         (str)       --  data masking policy name to be deleted

        Returns:
            bool                            -- returns true when deletion succeeds

        Raises:
            Exception

                When deletion of policy fails

                When Invalid policy name under given instance is provided
        """
        source_instance_id = int(self.instance_id)
        policy_id = self.get_masking_policy_id(policy_name)
        if policy_id is None:
            raise SDKException(
                'Instance',
                '106')

        request_json = {
            "opType": 3,
            "policy": {
                "association": {"instanceId": source_instance_id},
                "policy": {"policyId": policy_id, "policyName": policy_name}
            }
        }

        flag, response = self._cvpysdk_object.make_request(
            'POST', self._services['MASKING_POLICY'], request_json
        )
        if flag:
            if response.json():
                error_code = response.json()['errorCode']

                if error_code != 0:
                    raise SDKException(
                        'Instance',
                        '102',
                        'Error while deleting Data masking policy\nError')
                else:
                    return True

            else:
                raise SDKException('Response', '102')
        else:
            raise SDKException('Response', '101',
                               self._update_response_(response.text))

    def standalone_data_masking(
            self,
            policy_name,
            destination_client=None,
            destination_instance=None):
        """Launch standalone data masking job on given instance

        Args:

            policy_name          (str)       -- data masking policy name

            destination_client   (str)       -- destination client in which destination
            instance exists

            destination_instance (str)       -- destination instance to which masking
            to be applied

        Returns:
            object -- Job containing data masking job details


        Raises:
            SDKException
                if policy ID retrieved is None

        """
        if destination_client is None:
            destination_client = self._properties['instance']['clientName']
        if destination_instance is None:
            destination_instance = self.instance_name
        destination_client_object = self._commcell_object.clients.get(
            destination_client)
        destination_agent_object = destination_client_object.agents.get(
            'oracle')
        destination_instance_object = destination_agent_object.instances.get(
            destination_instance)
        destination_instance_id = int(destination_instance_object.instance_id)
        source_instance_id = int(self.instance_id)
        policy_id = self.get_masking_policy_id(policy_name)
        if policy_id is None:
            raise SDKException(
                'Instance',
                '106')
        request_json = self._restore_json(paths=r'/')
        destination_instance_json = {
            "clientName": destination_client,
            "instanceName": destination_instance,
            "instanceId": destination_instance_id
        }
        data_masking_options = {
            "isStandalone": True,
            "enabled": True,
            "dbDMPolicy": {
                "association": {
                    "instanceId": source_instance_id},
                "policy": {
                    "policyId": policy_id,
                    "policyName": policy_name}}}
        request_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["destination"]["destClient"]["clientName"] = destination_client
        request_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["destination"]["destinationInstance"] = destination_instance_json
        request_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["dbDataMaskingOptions"] = data_masking_options
        del request_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["fileOption"]
        return self._process_restore_response(request_json)

    def _get_oracle_restore_json(self, destination_client,
                                 instance_name, tablespaces,
                                 files, browse_option,
                                 common_options, oracle_options, destination=None):
        """
        Gets the basic restore JSON from base class and modifies it for oracle

        Args:
            destination_client  (str)   --  Destination client name

            instance_name   (str)   --  instance name to restore

            tablespaces (list)  --  tablespace name list

            files   (dict)  --  fileOptions

            browse_option   (dict)  --  dict containing browse options

            common_options  (dict)  --  dict containing common options

            oracle_options  (dict)  --  dict containing other oracle options

            destination     (dict)  --  dictionary with destination client and instance names
                default" None

        Returns:
            (dict) -- JSON formatted options to restore the oracle database

        Raises:
            SDKException:
                if tablespace is passed as a list
                if files is not passed as a dictionary

        """
        if not isinstance(tablespaces, list):
            raise SDKException(
                'Instance',
                '101', 'Expecting a list for tablespaces')
        if files is not None:
            if not isinstance(files, dict):
                raise SDKException(
                    'Instance',
                    '101', 'Expecting a dict for files')

        destination_id = int(self._commcell_object.clients.get(
            destination_client).client_id)
        tslist = ["SID: {0} Tablespace: {1}".format(
            instance_name, ts) for ts in tablespaces]
        restore_json = self._restore_json(paths=r'/')
        if common_options is not None:
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"][
                "commonOptions"] = common_options
        restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"][
            "oracleOpt"] = oracle_options
        if destination:
            if not isinstance(destination, dict):
                raise SDKException(
                    'Instance',
                    '101', 'Expecting a dict for destination details')
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["destination"] = destination
        if files is None:
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["fileOption"] = {
                "sourceItem": tslist
            }
        else:
            restore_json["taskInfo"]["subTasks"][0]["options"][
                "restoreOptions"]["fileOption"] = files

        if browse_option is not None:
            restore_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"][
                "browseOption"] = browse_option
        return restore_json

    def _get_browse_options(self):
        """Returns the database instance properties for browse and restore"""
        return {
            "path": "/",
            "entity": {
                "appName": self._properties['instance']['appName'],
                "instanceId": int(self.instance_id),
                "applicationId": int(self._properties['instance']['applicationId']),
                "clientId": int(self._properties['instance']['clientId']),
                "instanceName": self._properties['instance']['instanceName'],
                "clientName": self._properties['instance']['clientName']
            }
        }

    def _process_browse_response(self, request_json):
        """Runs the DBBrowse API with the request JSON provided for Browse,
            and returns the contents after parsing the response.

            Args:
                request_json    (dict)  --  JSON request to run for the API

            Returns:
                list - list containing tablespaces for the instance

            Raises:
                SDKException:
                    if browse job failed

                    if browse is empty

                    if browse is not success
        """
        if 'tablespaces' in self._instanceprop:
            return self._instanceprop['tablespaces']

        browse_service = self._commcell_object._services['ORACLE_INSTANCE_BROWSE'] % (
            self.instance_id
        )

        flag, response = self._commcell_object._cvpysdk_object.make_request(
            'POST', browse_service, request_json
        )

        if flag:
            response_data = json.loads(response.text)
            if response_data:
                if "oracleContent" in response_data:
                    self._instanceprop['tablespaces'] = response_data["oracleContent"]
                    return self._instanceprop['tablespaces']
                elif "errorCode" in response_data:
                    error_message = response_data['errorMessage']
                    o_str = 'Browse job failed\nError: "{0}"'.format(
                        error_message)
                    raise SDKException('Instance', '102', o_str)
            else:
                raise SDKException('Response', '102')
        else:
            response_string = self._commcell_object._update_response_(
                response.text)
            raise SDKException('Response', '101', response_string)

    @property
    def oracle_home(self):
        """
        getter for oracle home

        Returns:
            string - string of oracle_home

        """
        return self._properties['oracleInstance']['oracleHome']

    @property
    def is_catalog_enabled(self):
        """
        Getter to check if catalog has been enabled

        Returns:
            Bool - True if catalog is enabled. Else False.

        """
        return self._properties['oracleInstance']['useCatalogConnect']

    @property
    def catalog_user(self):
        """
        Getter for catalog user

        Returns:
            string  - String containing catalog user

        Raises:
            SDKException:
                if not set

                if catalog is not enabled

        """
        if not self.is_catalog_enabled:
            raise SDKException('Instance', r'102', 'Catalog is not enabled.')
        try:
            return self._properties['oracleInstance']['catalogConnect']['userName']
        except KeyError as error_str:
            raise SDKException('Instance', r'102',
                               'Catalog user not set - {}'.format(error_str))

    @property
    def catalog_db(self):
        """
        Getter for catalog database

        Returns:
            string  - String containing catalog database

        Raises:
            SDKException:
                if not set

                if catalog is not enabled

        """
        if not self.is_catalog_enabled:
            raise SDKException('Instance', r'102', 'Catalog is not enabled.')
        try:
            return self._properties['oracleInstance']['catalogConnect']['domainName']
        except KeyError as error_str:
            raise SDKException('Instance', r'102',
                               'Catalog database not set - {}'.format(error_str))

    @property
    def os_user(self):
        """
        Getter for oracle software owner

        Returns:
            string - string of oracle software owner

        """
        return self._properties['oracleInstance']['oracleUser']['userName']

    @property
    def version(self):
        """
        Getter for oracle version

        Returns:
            string - string of oracle instance version

        """
        return self._properties['version']

    @property
    def archive_log_dest(self):
        """
        Getter for the instance's archive log dest

        Returns:
            string - string for archivelog location

        """
        return self._properties['oracleInstance']['archiveLogDest']

    @property
    def cmd_sp(self):
        """
        Getter for Command Line storage policy

        Returns:
            string - string for command line storage policy

        """
        return self._properties['oracleInstance']['oracleStorageDevice'][
            'commandLineStoragePolicy']['storagePolicyName']

    @property
    def log_sp(self):
        """
        Oracle Instance's Log Storage Poplicy

        Returns:
            string  -- string containing log storage policy

        """
        return self._properties['oracleInstance']['oracleStorageDevice'][
            'logBackupStoragePolicy']['storagePolicyName']

    @property
    def is_autobackup_on(self):
        """
        Getter to check whether autobackup is set to ON

        Returns:
            Bool - True if autobackup is set to ON. Else False.

        """
        return True if self._properties['oracleInstance']['ctrlFileAutoBackup'] == 1 else False

    @property
    def db_user(self):
        """
        Getter to get the database user used to log into the database

        Returns: Oracle database user for the instance

        """
        return self._properties['oracleInstance']['sqlConnect']['userName']

    @property
    def tns_name(self):
        """
        Getter to get the TNS Names of the database

        Returns:
            string  -- TNS name of the instance configured

        Raises:
            SDKException:
                if not set

        """
        try:
            return self._properties['oracleInstance']['sqlConnect']['domainName']
        except KeyError as error_str:
            raise SDKException('Instance', r'102',
                               'Instance TNS Entry not set - {}'.format(error_str))

    @property
    def dbid(self):
        """
        Getter to get the DBID of the database instance

        Returns: DBID of the oracle database

        """
        return self._properties['oracleInstance']['DBID']

    @property
    def tablespaces(self):
        """
        Getter for listing out all tablespaces for the instance

        Returns:
            list -- list containing tablespace names for the database

        """
        return [ts['tableSpace'] for ts in self.browse()]

    def browse(self, *args, **kwargs):
        """Overridden method to browse oracle database tablespaces"""
        if args and isinstance(args[0], dict):
            options = args[0]
        elif kwargs:
            options = kwargs
        else:
            options = self._get_browse_options()
        return self._process_browse_response(options)

    def backup(self, subclient_name=r"default"):
        """Uses the default subclient to backup the database

        Args:
            subclient_name (str) -- name of subclient to use
                default: default
        """
        return self.subclients.get(subclient_name).backup(r'full')

    def restore(
            self,
            files=None,
            destination_client=None,
            common_options=None,
            browse_option=None,
            oracle_options={},
            tag=None,
            destination_instance=None,
            streams=2):
        """
        Perform restore full/partial database using latest backup or backup copy

        Args:
            files               (dict)      --  fileOption for restore

            destination_client  (str)       --  destination client name

            common_options      (dict)      --  dictionary containing common options
                default:    None

            browse_option       (dict)      --  dictionary containing browse options

            oracle_options      (dict)      --  dictionary containing other oracle options
                default:    By default it restores the controlfile and datafiles from latest backup

                Example:{
                            "resetLogs": 1,
                            "switchDatabaseMode": True,
                            "noCatalog": True,
                            "restoreControlFile": True,
                            "recover": True,
                            "recoverFrom": 3,
                            "restoreData": True,
                            "restoreFrom": 3
                        }

            tag                 (str)       --  Type of the restore to be performed
                default:    None

            destination_instance(str)       --  destination instance name
                default:    None (in place restore)

            streams             (int)       --  number of streams for restore
                default: 2


        Returns:
            object  --  Job containing restore details

        Raises:
            SDKException:
                If oracle options can't be set

                If destination_client can't be set

        """
        options = {
            "resetLogs": 1,
            "switchDatabaseMode": True,
            "noCatalog": True,
            "recover": True,
            "recoverFrom": 3,
            "restoreData": True,
            "restoreFrom": 3
        }
        options.update(oracle_options)
        oracle_options = options.copy()

        if tag and tag.lower() == 'snap':
            opt = {
                "useSnapRestore": True,
                "cleanupAuxiliary": True,
                "restoreControlFile": True,
            }
            oracle_options.update(opt)

        try:
            if destination_client is None or destination_instance is None:
                destination_client = self._properties['instance']['clientName']
                destination_instance = self._properties['instance']['instanceName']
            destination = {
                "destination_client": destination_client,
                "destination_instance": destination_instance
            }
            if tag and tag.lower()=="rac":
                stream_allocation = self._get_rac_stream_allocation(
                    destination_client, destination_instance, streams)
                oracle_options.update(stream_allocation)
                destination["app_name"] = "Oracle RAC"
            self._restore_destination_json(destination)
        except SDKException:
            raise SDKException("Instance", "105")
        else:
            # subclient = self.subclients.get(subclient_name)
            if destination_client and destination_instance:
                options = self._get_oracle_restore_json(destination_client=destination_client,
                                                        destination=self._destination_restore_json,
                                                        instance_name=self.instance_name,
                                                        tablespaces=self.tablespaces,
                                                        files=files,
                                                        browse_option=browse_option,
                                                        common_options=common_options,
                                                        oracle_options=oracle_options)
            else:
                options = self._get_oracle_restore_json(destination_client=destination_client,
                                                        instance_name=self.instance_name,
                                                        tablespaces=self.tablespaces,
                                                        files=files,
                                                        browse_option=browse_option,
                                                        common_options=common_options,
                                                        oracle_options=oracle_options)
            return self._process_restore_response(options)
            
    def _get_rac_stream_allocation(self, destination_client, destination_instance, streams):
        """setter for RAC stream allocation on nodes data population in oracle options for restore
            Args:
                destination_client  (str) -- Name of the destination client
                destination_instance(str) -- Name of the destination RAC instance
                streams             (int)    -- Number of streams for restore
        """
        destination_client_obj = self._commcell_object.clients.get(destination_client)
        destination_instance_obj = destination_client_obj.agents.get("Oracle RAC").instances.get(destination_instance)
        rac_stream_allocation = {"racDataStreamAllcation": []}
        for node in destination_instance_obj.properties['oracleRACInstance']['racDBInstance']:
            rac_stream_allocation["racDataStreamAllcation"].append(f"{node['racDbInstanceId']} {streams}")
        return rac_stream_allocation

    def _restore_db_dump_option_json(self,value):
        """setter for the oracle dbdump Restore option in restore JSON
            Args:
                value   (dict)  --  Dictionary of options need to be set for restore
        """
        if not isinstance(value,dict):
            raise SDKException('Instance','101')
            
        self._db_dump_restore_json = {
            "importToDatabase": True,
            "parallelism": 2,
            "restorePath": value.get("destination_path", ""),
            "overwriteTable": False,
            "enabled": True,
            "connectDetails": {
                "password": b64encode(value.get("db_password", "").encode()).decode(),
                "domainName": (self._properties.get("oracleInstance", {}).
                    get("sqlConnect", {}).get("domainName", "")),
                "userName": (self._properties.get("oracleInstance", {}).
                    get("sqlConnect", {}).get("userName", ""))
            }
        }


    def _restore_oracle_option_json(self, value):
        """setter for the oracle Restore option in restore JSON
        Args:
                value   (dict)  --  Dictionary of options need to be set for restore
        """
        if not isinstance(value,dict):
            raise SDKException('Instance','101')

        self._oracle_restore_json = {
            "validate": False,
            "noCatalog": False,
            "duplicateToName": "",
            "cloneEnv": False,
            "restoreControlFile": False,
            "duplicate": False,
            "tableViewRestore": False,
            "osID": 2,
            "partialRestore": False,
            "restoreStream": 2,
            "restoreSPFile": False,
            "recover": True,
            "recoverFrom": 4,
            "archiveLog": False,
            "restoreData": True,
            "restoreFrom": 0,
            "timeZone": {
                "TimeZoneName": "(UTC) Coordinated Universal Time"
            },
            "recoverTime": {},
            "sourcePaths": [
                "//**"
            ],
            "restoreTime": {}
        }

        if value.get("restore_oracle_options_type") == "restore_archivelogs_norecover":
            self._oracle_restore_json = {
                "resetLogs": 0,
                "backupValidationOnly": False,
                "threadId": 1,
                "deviceType": 0,
                "restoreFailover": True,
                "resetDatabase": False,
                "noCatalog": True,
                "ctrlRestoreFrom": False,
                "controlFilePath": "",
                "specifyControlFileTime": False,
                "restoreDataTag": False,
                "useEndLSN": False,
                "useStartLSN": False,
                "restoreTablespace": False,
                "archiveLogBy": 1,
                "ctrlFileBackupType": 0,
                "restoreControlFile": False,
                "restoreInstanceLog": False,
                "duplicate": False,
                "startLSNNum": "",
                "checkReadOnly": False,
                "osID": 2,
                "specifyControlFile": False,
                "setDBId": False,
                "partialRestore": False,
                "restoreStream": 2,
                "specifySPFile": False,
                "restoreSPFile": False,
                "recover": False,
                "recoverFrom": 4,
                "archiveLog": True,
                "endLSNNum": "",
                "autoDetectDevice": True,
                "useEndLog": False,
                "isDeviceTypeSelected": False,
                "useStartLog": True,
                "logTarget": "",
                "restoreData": False,
                "restoreFrom": 0,
                "duplicateToSkipReadOnly": False
            }
            if value.get("start_lsn", None):
                self._oracle_restore_json["useStartLSN"] = True
                self._oracle_restore_json["startLSNNum"] = value.get("start_lsn")
            if value.get("end_lsn", None):
                self._oracle_restore_json["useEndLSN"] = True
                self._oracle_restore_json["endLSNNum"] = value.get("end_lsn")
            if value.get("log_dest", None):
                self._oracle_restore_json["logTarget"] = value.get("log_dest")

    def _restore_json(self, **kwargs):
        """Returns the JSON request to pass to the API as per the options selected by the user.

            Args:
                kwargs   (dict)  --  Dictionary of options need to be set for restore

            Returns:
                dict             -- JSON request to pass to the API

        """
        rest_json = super(OracleInstance, self)._restore_json(**kwargs)
        restore_option = {}
        if kwargs.get("restore_option"):
            restore_option = kwargs["restore_option"]
            for key in kwargs:
                if not key == "restore_option":
                    restore_option[key] = kwargs[key]
        else:
            restore_option.update(kwargs)

        self._restore_db_dump_option_json(restore_option)
        self._restore_oracle_option_json(restore_option)
        rest_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["dbDumpOptions"] = self._db_dump_restore_json
        rest_json["taskInfo"]["subTasks"][0]["options"][
            "restoreOptions"]["oracleOpt"] = self._oracle_restore_json

        return rest_json

    def restore_in_place(
            self,
            db_password,
            path,
            dest_client_name,
            dest_instance_name,
            dest_path=None,
            restore_oracle_options_type=None,
            start_lsn=None, end_lsn=None,
            log_dest=None):
        """Restores the oracle logical dump data/log files specified in the input paths
        list to the same location.

            Args:
                
                db_password             (str)  -- password for oracle database
                
                path                    (list)  --  list of database/databases to be restored

                dest_client_name        (str)   --  destination client name where files are to be
                restored

                dest_instance_name      (str)   --  destination postgres instance name of
                destination client

                dest_path        (str)   --  destinath path for restore

                    default: None

            Returns:
                object - instance of the Job class for this restore job

            Raises:
                SDKException:
                    if paths is not a list

                    if failed to initialize job

                    if response is empty

                    if response is not success

        """
        if not (isinstance(path, list) and
                isinstance(db_password, str)):
            raise SDKException('Instance', '101')
        if not path:
            raise SDKException('Instance','103')
        

        request_json = self._restore_json(
            db_password=db_password,
            paths=path,
            destination_client=dest_client_name,
            destination_instance=dest_instance_name,
            destination_path=dest_path,
            restore_oracle_options_type=restore_oracle_options_type,
            start_lsn=start_lsn, end_lsn=end_lsn,
            log_dest=log_dest)

        return self._process_restore_response(request_json)

Ancestors

Instance variables

var archive_log_dest

Getter for the instance's archive log dest

Returns

string - string for archivelog location

Expand source code Browse git
@property
def archive_log_dest(self):
    """
    Getter for the instance's archive log dest

    Returns:
        string - string for archivelog location

    """
    return self._properties['oracleInstance']['archiveLogDest']
var catalog_db

Getter for catalog database

Returns

string - String containing catalog database

Raises

SDKException: if not set

if catalog is not enabled
Expand source code Browse git
@property
def catalog_db(self):
    """
    Getter for catalog database

    Returns:
        string  - String containing catalog database

    Raises:
        SDKException:
            if not set

            if catalog is not enabled

    """
    if not self.is_catalog_enabled:
        raise SDKException('Instance', r'102', 'Catalog is not enabled.')
    try:
        return self._properties['oracleInstance']['catalogConnect']['domainName']
    except KeyError as error_str:
        raise SDKException('Instance', r'102',
                           'Catalog database not set - {}'.format(error_str))
var catalog_user

Getter for catalog user

Returns

string - String containing catalog user

Raises

SDKException: if not set

if catalog is not enabled
Expand source code Browse git
@property
def catalog_user(self):
    """
    Getter for catalog user

    Returns:
        string  - String containing catalog user

    Raises:
        SDKException:
            if not set

            if catalog is not enabled

    """
    if not self.is_catalog_enabled:
        raise SDKException('Instance', r'102', 'Catalog is not enabled.')
    try:
        return self._properties['oracleInstance']['catalogConnect']['userName']
    except KeyError as error_str:
        raise SDKException('Instance', r'102',
                           'Catalog user not set - {}'.format(error_str))
var cmd_sp

Getter for Command Line storage policy

Returns

string - string for command line storage policy

Expand source code Browse git
@property
def cmd_sp(self):
    """
    Getter for Command Line storage policy

    Returns:
        string - string for command line storage policy

    """
    return self._properties['oracleInstance']['oracleStorageDevice'][
        'commandLineStoragePolicy']['storagePolicyName']
var db_user

Getter to get the database user used to log into the database

Returns: Oracle database user for the instance

Expand source code Browse git
@property
def db_user(self):
    """
    Getter to get the database user used to log into the database

    Returns: Oracle database user for the instance

    """
    return self._properties['oracleInstance']['sqlConnect']['userName']
var dbid

Getter to get the DBID of the database instance

Returns: DBID of the oracle database

Expand source code Browse git
@property
def dbid(self):
    """
    Getter to get the DBID of the database instance

    Returns: DBID of the oracle database

    """
    return self._properties['oracleInstance']['DBID']
var is_autobackup_on

Getter to check whether autobackup is set to ON

Returns

Bool - True if autobackup is set to ON. Else False.

Expand source code Browse git
@property
def is_autobackup_on(self):
    """
    Getter to check whether autobackup is set to ON

    Returns:
        Bool - True if autobackup is set to ON. Else False.

    """
    return True if self._properties['oracleInstance']['ctrlFileAutoBackup'] == 1 else False
var is_catalog_enabled

Getter to check if catalog has been enabled

Returns

Bool - True if catalog is enabled. Else False.

Expand source code Browse git
@property
def is_catalog_enabled(self):
    """
    Getter to check if catalog has been enabled

    Returns:
        Bool - True if catalog is enabled. Else False.

    """
    return self._properties['oracleInstance']['useCatalogConnect']
var log_sp

Oracle Instance's Log Storage Poplicy

Returns

string – string containing log storage policy

Expand source code Browse git
@property
def log_sp(self):
    """
    Oracle Instance's Log Storage Poplicy

    Returns:
        string  -- string containing log storage policy

    """
    return self._properties['oracleInstance']['oracleStorageDevice'][
        'logBackupStoragePolicy']['storagePolicyName']
var log_stream

Getter to fetch log stream count at instance level

Returns:
        int     --  log stream count atinstance level
Expand source code Browse git
@property
def log_stream(self):
    """
    Getter to fetch log stream count at instance level

        Returns:
                int     --  log stream count atinstance level

    """
    return self._instanceprop.get("numberOfArchiveLogBackupStreams")
var oracle_home

getter for oracle home

Returns

string - string of oracle_home

Expand source code Browse git
@property
def oracle_home(self):
    """
    getter for oracle home

    Returns:
        string - string of oracle_home

    """
    return self._properties['oracleInstance']['oracleHome']
var os_user

Getter for oracle software owner

Returns

string - string of oracle software owner

Expand source code Browse git
@property
def os_user(self):
    """
    Getter for oracle software owner

    Returns:
        string - string of oracle software owner

    """
    return self._properties['oracleInstance']['oracleUser']['userName']
var tablespaces

Getter for listing out all tablespaces for the instance

Returns

list – list containing tablespace names for the database

Expand source code Browse git
@property
def tablespaces(self):
    """
    Getter for listing out all tablespaces for the instance

    Returns:
        list -- list containing tablespace names for the database

    """
    return [ts['tableSpace'] for ts in self.browse()]
var tns_name

Getter to get the TNS Names of the database

Returns

string – TNS name of the instance configured

Raises

SDKException: if not set

Expand source code Browse git
@property
def tns_name(self):
    """
    Getter to get the TNS Names of the database

    Returns:
        string  -- TNS name of the instance configured

    Raises:
        SDKException:
            if not set

    """
    try:
        return self._properties['oracleInstance']['sqlConnect']['domainName']
    except KeyError as error_str:
        raise SDKException('Instance', r'102',
                           'Instance TNS Entry not set - {}'.format(error_str))
var version

Getter for oracle version

Returns

string - string of oracle instance version

Expand source code Browse git
@property
def version(self):
    """
    Getter for oracle version

    Returns:
        string - string of oracle instance version

    """
    return self._properties['version']

Methods

def backup(self, subclient_name='default')

Uses the default subclient to backup the database

Args

subclient_name (str) – name of subclient to use default: default

Expand source code Browse git
def backup(self, subclient_name=r"default"):
    """Uses the default subclient to backup the database

    Args:
        subclient_name (str) -- name of subclient to use
            default: default
    """
    return self.subclients.get(subclient_name).backup(r'full')
def browse(self, *args, **kwargs)

Overridden method to browse oracle database tablespaces

Expand source code Browse git
def browse(self, *args, **kwargs):
    """Overridden method to browse oracle database tablespaces"""
    if args and isinstance(args[0], dict):
        options = args[0]
    elif kwargs:
        options = kwargs
    else:
        options = self._get_browse_options()
    return self._process_browse_response(options)
def configure_data_masking_policy(self, policy_name, table_list_of_dict)

Configures data masking policy with given parameters

Args

policy_name (str) – string representing policy name table_list_of_dict list(dict) – list containing one dict item representing rules for single table Sample list Tables: [ { "name":"schema_name.table_name", "columns": [ {"name":"column_name", "type":"algorithm_type"}, "arguments":[list of strings]…] } ] Sample : [ { "name":"HR.NUMNEW", "columns":[{"name":"N1","type":0},{"name":"N2","type":2, "arguments":["1000","2000"]}] }, { "name":"HR.CHANGE", "columns":[{"name":"C1","type":1},{"name":"C2","type":1}] } ] schema_name , table_name, column_name: str Column type key in main dict takes list of dict as value : This list of dict represents each column name and type of algorithm and arguments if any for that algorithm arguments : list of strings

Choose appropriate algorithm type and pass necessary arguments based on column type

Algorithm Arguments mandatory Arguments Format Algorithm type number

Shuffling NA NA 0 Numeric Range [min, max] ["1000","2000"] 2 Numeric Variance [variance percentage] ["50"] 3 FPE NA NA 1 Fixed String string_to_replace ["string_to_replace"] 4

Supported Algorithms :

Column Type Algorithms Supported

Numeric Shuffling, FPE, Numeric Range, Numeric Variance Char Shuffling , FPE , Fixed String Varchar Shuffling , FPE , Fixed String

Expand source code Browse git
def configure_data_masking_policy(self, policy_name, table_list_of_dict):
    """Configures data masking policy with given parameters
    Args:
        policy_name         (str)   --  string representing policy name
        table_list_of_dict  list(dict)  -- list containing one dict item representing
                                            rules for single table
        Sample  list
        Tables:
                [
                {
                "name":"schema_name.table_name",
                "columns": [ {"name":"column_name", "type":"algorithm_type"},
                            "arguments":[list of strings]…]
                }
                ]
                Sample :
                [
                {
                "name":"HR.NUMNEW",
                "columns":[{"name":"N1","type":0},{"name":"N2","type":2,
                "arguments":["1000","2000"]}]
                },
                {
                "name":"HR.CHANGE",
                "columns":[{"name":"C1","type":1},{"name":"C2","type":1}]
                }
                ]
        schema_name , table_name, column_name: str
        Column type key in main dict takes list of dict as value :
        This list of dict represents each column name and type of algorithm
        and arguments if any for that algorithm
        arguments : list of strings

        Choose appropriate algorithm type and pass necessary arguments based
        on column type

        Algorithm       Arguments mandatory       Arguments Format        Algorithm type number

        Shuffling           NA                              NA                      0
        Numeric Range       [min, max]                  ["1000","2000"]             2
        Numeric Variance    [variance percentage]           ["50"]                  3
        FPE                 NA                              NA                      1
        Fixed String        string_to_replace           ["string_to_replace"]       4


        Supported Algorithms :

        Column Type     Algorithms Supported

        Numeric         Shuffling, FPE, Numeric Range, Numeric Variance
        Char            Shuffling , FPE , Fixed String
        Varchar         Shuffling , FPE , Fixed String

    """
    request_json = {
        "opType": 2,
        "policy": {
            "association": {"instanceId": int(self.instance_id)},
            "config": {"tables": table_list_of_dict},
            "policy": {"policyName": policy_name}
        }
    }

    flag, response = self._cvpysdk_object.make_request(
        'POST', self._services['MASKING_POLICY'], request_json
    )
    if flag:
        if response.json():
            error_code = response.json()['errorCode']

            if error_code != 0:
                error_string = response.json()['errorMessage']
                raise SDKException(
                    'Instance',
                    '102',
                    'Error while creating Data masking policy\nError: "{0}"'.format(
                        error_string)
                )
            else:
                return True

        else:
            raise SDKException('Response', '102')
    else:
        raise SDKException('Response', '101',
                           self._update_response_(response.text))
def create_live_sync_schedule(self, dest_client, dest_instance, schedule_name, **kwargs)

Runs full backup on source oracle instance and Creates live sync schdule for the given destination oracle instance

Args:
    dest_client  (str)   --  The destination client name for live sync

    dest_instance    (str)   --  The destination instance name for live sync

    schedule_name    (str)   --  The name of the live sync schedule to be created

    **kwargs    (dict)  -- dict of keyword arguments as follows:

                         redirect_path   (str) --  Path on destination client
                                         to redirect tablespaces and datafiles

Returns:
     (object)  --   The job object of the baseline backup that will be replicated
Expand source code Browse git
def create_live_sync_schedule(self, dest_client, dest_instance, schedule_name,
                              **kwargs):
    """
           Runs full backup on source oracle instance and
           Creates live sync schdule for the given destination oracle instance

               Args:
                   dest_client  (str)   --  The destination client name for live sync

                   dest_instance    (str)   --  The destination instance name for live sync

                   schedule_name    (str)   --  The name of the live sync schedule to be created

                   **kwargs    (dict)  -- dict of keyword arguments as follows:

                                        redirect_path   (str) --  Path on destination client
                                                        to redirect tablespaces and datafiles

               Returns:
                    (object)  --   The job object of the baseline backup that will be replicated

    """
    source_backupset_id = int(self.backupsets.get('default').backupset_id)
    subclient_obj = self.subclients.get('default')
    baseline_job_object = subclient_obj.backup(backup_level='full')
    if not baseline_job_object.wait_for_completion():
        raise SDKException('Instance', '102', baseline_job_object.delay_reason)
    baseline_ref_time = baseline_job_object.summary['jobStartTime']
    baseline_jobid = int(baseline_job_object.job_id)
    request_json = self._live_sync_restore_json(dest_client, dest_instance, baseline_jobid,
                                                baseline_ref_time, schedule_name,
                                                source_backupset_id, **kwargs)
    flag, response = self._cvpysdk_object.make_request('POST', self._LIVE_SYNC, request_json)
    if flag:
        if response.json():
            if "taskId" in response.json():
                return baseline_job_object
            elif "errorCode" in response.json():
                error_message = response.json()['errorMessage']
                error_message = 'Live Sync configuration failed\nError: "{0}"'.format(
                    error_message)
                raise SDKException('Instance', '102', error_message)
            else:
                raise SDKException('Instance', '102', 'Failed to create schedule')
        else:
            raise SDKException('Instance', '102')
    else:
        raise SDKException('Instance', '101', self._update_response_(response.text))
def delete_data_masking_policy(self, policy_name)

Deletes given data masking policy

Args

policy_name (str) – data masking policy name to be deleted

Returns

bool – returns true when deletion succeeds

Raises

Exception

When deletion of policy fails

When Invalid policy name under given instance is provided
Expand source code Browse git
def delete_data_masking_policy(self, policy_name):
    """Deletes given data masking policy
    Args:
        policy_name         (str)       --  data masking policy name to be deleted

    Returns:
        bool                            -- returns true when deletion succeeds

    Raises:
        Exception

            When deletion of policy fails

            When Invalid policy name under given instance is provided
    """
    source_instance_id = int(self.instance_id)
    policy_id = self.get_masking_policy_id(policy_name)
    if policy_id is None:
        raise SDKException(
            'Instance',
            '106')

    request_json = {
        "opType": 3,
        "policy": {
            "association": {"instanceId": source_instance_id},
            "policy": {"policyId": policy_id, "policyName": policy_name}
        }
    }

    flag, response = self._cvpysdk_object.make_request(
        'POST', self._services['MASKING_POLICY'], request_json
    )
    if flag:
        if response.json():
            error_code = response.json()['errorCode']

            if error_code != 0:
                raise SDKException(
                    'Instance',
                    '102',
                    'Error while deleting Data masking policy\nError')
            else:
                return True

        else:
            raise SDKException('Response', '102')
    else:
        raise SDKException('Response', '101',
                           self._update_response_(response.text))
def get_masking_policy_id(self, policy_name)

Returns policy id of given data masking policy

Args

policy_name (str) – data masking policy name

Returns

policy_id (int) – data masking policy ID

Expand source code Browse git
def get_masking_policy_id(self, policy_name):
    """Returns policy id of given data masking policy
    Args:
        policy_name          (str)       -- data masking policy name

    Returns:
        policy_id            (int)       -- data masking policy ID

    """
    instance_id = int(self.instance_id)
    flag, response = self._cvpysdk_object.make_request(
        'GET', self._services['MASKING_POLICY'])
    response_json = response.json()
    policy_list = response_json["policies"]
    policy_id = None
    for i in policy_list:
        pname = i["policy"]["policyName"]
        associated_instance_id = i["association"]["instanceId"]
        if (pname == policy_name) and (associated_instance_id == instance_id):
            policy_id = int(i["policy"]["policyId"])
            break
        else:
            continue
    return policy_id
def restore(self, files=None, destination_client=None, common_options=None, browse_option=None, oracle_options={}, tag=None, destination_instance=None, streams=2)

Perform restore full/partial database using latest backup or backup copy

Args

files (dict) – fileOption for restore

destination_client (str) – destination client name

common_options (dict) – dictionary containing common options default: None

browse_option (dict) – dictionary containing browse options

oracle_options (dict) – dictionary containing other oracle options default: By default it restores the controlfile and datafiles from latest backup

Example:{
            "resetLogs": 1,
            "switchDatabaseMode": True,
            "noCatalog": True,
            "restoreControlFile": True,
            "recover": True,
            "recoverFrom": 3,
            "restoreData": True,
            "restoreFrom": 3
        }

tag (str) – Type of the restore to be performed default: None

destination_instance(str) – destination instance name default: None (in place restore)

streams (int) – number of streams for restore default: 2

Returns

object – Job containing restore details

Raises

SDKException: If oracle options can't be set

If destination_client can't be set
Expand source code Browse git
def restore(
        self,
        files=None,
        destination_client=None,
        common_options=None,
        browse_option=None,
        oracle_options={},
        tag=None,
        destination_instance=None,
        streams=2):
    """
    Perform restore full/partial database using latest backup or backup copy

    Args:
        files               (dict)      --  fileOption for restore

        destination_client  (str)       --  destination client name

        common_options      (dict)      --  dictionary containing common options
            default:    None

        browse_option       (dict)      --  dictionary containing browse options

        oracle_options      (dict)      --  dictionary containing other oracle options
            default:    By default it restores the controlfile and datafiles from latest backup

            Example:{
                        "resetLogs": 1,
                        "switchDatabaseMode": True,
                        "noCatalog": True,
                        "restoreControlFile": True,
                        "recover": True,
                        "recoverFrom": 3,
                        "restoreData": True,
                        "restoreFrom": 3
                    }

        tag                 (str)       --  Type of the restore to be performed
            default:    None

        destination_instance(str)       --  destination instance name
            default:    None (in place restore)

        streams             (int)       --  number of streams for restore
            default: 2


    Returns:
        object  --  Job containing restore details

    Raises:
        SDKException:
            If oracle options can't be set

            If destination_client can't be set

    """
    options = {
        "resetLogs": 1,
        "switchDatabaseMode": True,
        "noCatalog": True,
        "recover": True,
        "recoverFrom": 3,
        "restoreData": True,
        "restoreFrom": 3
    }
    options.update(oracle_options)
    oracle_options = options.copy()

    if tag and tag.lower() == 'snap':
        opt = {
            "useSnapRestore": True,
            "cleanupAuxiliary": True,
            "restoreControlFile": True,
        }
        oracle_options.update(opt)

    try:
        if destination_client is None or destination_instance is None:
            destination_client = self._properties['instance']['clientName']
            destination_instance = self._properties['instance']['instanceName']
        destination = {
            "destination_client": destination_client,
            "destination_instance": destination_instance
        }
        if tag and tag.lower()=="rac":
            stream_allocation = self._get_rac_stream_allocation(
                destination_client, destination_instance, streams)
            oracle_options.update(stream_allocation)
            destination["app_name"] = "Oracle RAC"
        self._restore_destination_json(destination)
    except SDKException:
        raise SDKException("Instance", "105")
    else:
        # subclient = self.subclients.get(subclient_name)
        if destination_client and destination_instance:
            options = self._get_oracle_restore_json(destination_client=destination_client,
                                                    destination=self._destination_restore_json,
                                                    instance_name=self.instance_name,
                                                    tablespaces=self.tablespaces,
                                                    files=files,
                                                    browse_option=browse_option,
                                                    common_options=common_options,
                                                    oracle_options=oracle_options)
        else:
            options = self._get_oracle_restore_json(destination_client=destination_client,
                                                    instance_name=self.instance_name,
                                                    tablespaces=self.tablespaces,
                                                    files=files,
                                                    browse_option=browse_option,
                                                    common_options=common_options,
                                                    oracle_options=oracle_options)
        return self._process_restore_response(options)
def restore_in_place(self, db_password, path, dest_client_name, dest_instance_name, dest_path=None, restore_oracle_options_type=None, start_lsn=None, end_lsn=None, log_dest=None)

Restores the oracle logical dump data/log files specified in the input paths list to the same location.

Args:

    db_password             (str)  -- password for oracle database

    path                    (list)  --  list of database/databases to be restored

    dest_client_name        (str)   --  destination client name where files are to be
    restored

    dest_instance_name      (str)   --  destination postgres instance name of
    destination client

    dest_path        (str)   --  destinath path for restore

        default: None

Returns:
    object - instance of the Job class for this restore job

Raises:
    SDKException:
        if paths is not a list

        if failed to initialize job

        if response is empty

        if response is not success
Expand source code Browse git
def restore_in_place(
        self,
        db_password,
        path,
        dest_client_name,
        dest_instance_name,
        dest_path=None,
        restore_oracle_options_type=None,
        start_lsn=None, end_lsn=None,
        log_dest=None):
    """Restores the oracle logical dump data/log files specified in the input paths
    list to the same location.

        Args:
            
            db_password             (str)  -- password for oracle database
            
            path                    (list)  --  list of database/databases to be restored

            dest_client_name        (str)   --  destination client name where files are to be
            restored

            dest_instance_name      (str)   --  destination postgres instance name of
            destination client

            dest_path        (str)   --  destinath path for restore

                default: None

        Returns:
            object - instance of the Job class for this restore job

        Raises:
            SDKException:
                if paths is not a list

                if failed to initialize job

                if response is empty

                if response is not success

    """
    if not (isinstance(path, list) and
            isinstance(db_password, str)):
        raise SDKException('Instance', '101')
    if not path:
        raise SDKException('Instance','103')
    

    request_json = self._restore_json(
        db_password=db_password,
        paths=path,
        destination_client=dest_client_name,
        destination_instance=dest_instance_name,
        destination_path=dest_path,
        restore_oracle_options_type=restore_oracle_options_type,
        start_lsn=start_lsn, end_lsn=end_lsn,
        log_dest=log_dest)

    return self._process_restore_response(request_json)
def restore_to_disk(self, destination_client, destination_path, backup_job_ids, user_name, password)

Perform restore to disk [Application free restore] for Oracle

Args:
    destination_client          (str)   --  destination client name

    destination_path:           (str)   --  destination path

    backup_job_ids              (list)  --  list of backup job IDs
                                            to be used for disk restore

    user_name                   (str)   --  impersonation user name to
                                            restore to destination client

    password                    (str)   --  impersonation user password

Returns:
    object -     Job containing restore details

Raises:
    SDKException
        if backup_job_ids not given as list of items
Expand source code Browse git
def restore_to_disk(self,
                    destination_client,
                    destination_path,
                    backup_job_ids,
                    user_name,
                    password):
    """
    Perform restore to disk [Application free restore] for Oracle

        Args:
            destination_client          (str)   --  destination client name

            destination_path:           (str)   --  destination path

            backup_job_ids              (list)  --  list of backup job IDs
                                                    to be used for disk restore

            user_name                   (str)   --  impersonation user name to
                                                    restore to destination client

            password                    (str)   --  impersonation user password

        Returns:
            object -     Job containing restore details

        Raises:
            SDKException
                if backup_job_ids not given as list of items

    """
    if not isinstance(backup_job_ids, list):
        raise SDKException('Instance', '101')
    request_json = self._get_restore_to_disk_json(destination_client,
                                                  destination_path,
                                                  backup_job_ids,
                                                  user_name,
                                                  password)
    return self._process_restore_response(request_json)
def standalone_data_masking(self, policy_name, destination_client=None, destination_instance=None)

Launch standalone data masking job on given instance

Args

policy_name (str) – data masking policy name

destination_client (str) – destination client in which destination instance exists

destination_instance (str) – destination instance to which masking to be applied

Returns

object – Job containing data masking job details

Raises

SDKException if policy ID retrieved is None

Expand source code Browse git
def standalone_data_masking(
        self,
        policy_name,
        destination_client=None,
        destination_instance=None):
    """Launch standalone data masking job on given instance

    Args:

        policy_name          (str)       -- data masking policy name

        destination_client   (str)       -- destination client in which destination
        instance exists

        destination_instance (str)       -- destination instance to which masking
        to be applied

    Returns:
        object -- Job containing data masking job details


    Raises:
        SDKException
            if policy ID retrieved is None

    """
    if destination_client is None:
        destination_client = self._properties['instance']['clientName']
    if destination_instance is None:
        destination_instance = self.instance_name
    destination_client_object = self._commcell_object.clients.get(
        destination_client)
    destination_agent_object = destination_client_object.agents.get(
        'oracle')
    destination_instance_object = destination_agent_object.instances.get(
        destination_instance)
    destination_instance_id = int(destination_instance_object.instance_id)
    source_instance_id = int(self.instance_id)
    policy_id = self.get_masking_policy_id(policy_name)
    if policy_id is None:
        raise SDKException(
            'Instance',
            '106')
    request_json = self._restore_json(paths=r'/')
    destination_instance_json = {
        "clientName": destination_client,
        "instanceName": destination_instance,
        "instanceId": destination_instance_id
    }
    data_masking_options = {
        "isStandalone": True,
        "enabled": True,
        "dbDMPolicy": {
            "association": {
                "instanceId": source_instance_id},
            "policy": {
                "policyId": policy_id,
                "policyName": policy_name}}}
    request_json["taskInfo"]["subTasks"][0]["options"][
        "restoreOptions"]["destination"]["destClient"]["clientName"] = destination_client
    request_json["taskInfo"]["subTasks"][0]["options"][
        "restoreOptions"]["destination"]["destinationInstance"] = destination_instance_json
    request_json["taskInfo"]["subTasks"][0]["options"][
        "restoreOptions"]["dbDataMaskingOptions"] = data_masking_options
    del request_json["taskInfo"]["subTasks"][0]["options"]["restoreOptions"]["fileOption"]
    return self._process_restore_response(request_json)

Inherited members