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