diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..f9dc5b9
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,27 @@
+name: CI
+
+on:
+ pull_request:
+ push:
+ paths-ignore:
+ - '**.md'
+
+jobs:
+ test:
+ name: Run style checks
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python: [3.7]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Setup Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python }}
+ - name: Install Tox and any other packages
+ run: pip install tox
+ - name: Run tox
+ run: tox -- -a
diff --git a/.gitignore b/.gitignore
index 721b3f2..019879a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,12 @@
*.gz
-*.log
*.swp
*.pyc
*.key
*.pub
*.DS_Store
-dxtools.conf
+*.log
+config/dxtools.conf
+venv
+.DS_Store
+**/.idea
+.tox/
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..5c98b42
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/delphixpy-examples.iml b/.idea/delphixpy-examples.iml
new file mode 100644
index 0000000..0e4e9fa
--- /dev/null
+++ b/.idea/delphixpy-examples.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..3c29c38
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..cdd9eab
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.isort.cfg b/.isort.cfg
new file mode 100644
index 0000000..51f0ab3
--- /dev/null
+++ b/.isort.cfg
@@ -0,0 +1,4 @@
+[settings]
+force_single_line=True
+known_first_party=delphixpy,lib
+default_section=THIRDPARTY
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..1ed0e34
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,12 @@
+repos:
+- repo: https://github.com/psf/black
+ rev: 22.10.0
+ hooks:
+ - id: black
+ args:
+ - --fast
+
+- repo: https://github.com/timothycrosley/isort
+ rev: 4.3.21
+ hooks:
+ - id: isort
diff --git a/.swn b/.swn
new file mode 100644
index 0000000..fac3df7
Binary files /dev/null and b/.swn differ
diff --git a/README.md b/README.md
index d18c5b6..4a2ec3f 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,16 @@
# delphixpy-examples
-These are some example python scripts I put together to serve as
-examples for those getting started with Delphix the delphixpy python
-module.
+These are some example python scripts for those getting started
+with the Delphix delphixpy python module.
-## Thanks
-First, a lot of thanks to Corey Brune
-([@mcbrune](https://github.com/mcbrune)) for all of his contributions
-that make this spaghetti look decent.
+## Changes in this Branch
+- This branch requires Python3. All enhancements and break fixes will
+ be committed to this branch and will eventually become the
+ ``master`` branch.
+- We have a new format for dxtools.conf. If you used this repo in the
+ past, please be aware of the new format.
+- All connections use HTTPS by default. Please refer to
+ lib/get\_session.py if using this repo in a production environment.
+- Migrated from Delphix API version 1.8.0 to 1.10.2.
## Wait... What's Delphix?
In the most simplest answer, [Delphix](http://www.delphix.com) is an
@@ -21,20 +25,74 @@ directly invoke the Delphix API via python.
## Where can I get delphixpy?
delphixpy is available on PyPy, so you can install it by invoking pip
- pip install delphixpy
+ pip3 install delphixpy
## How do I use these examples?
Clone this repository to your system where python is installed. Then
install the pip packages in the requirements.txt file:
- pip install --upgrade -r requirements.txt
+ pip3 install --upgrade -r requirements.txt
Once that is complete, you are ready to use the scripts with your
Delphix environment. Each of the scripts have POSIX compliant
help. The options are also explained along with examples. I am going
-to explain more on these scripts in my blog and on [the Delphix
+to explain more on these scripts in @CloudSurgeon and on [the Delphix
community page](https://community.delphix.com)
+## Contribute
+
+1. Fork the project.
+2. Make your bug fix or new feature.
+3. Add tests for your code.
+4. Send a pull request.
+
+Contributions must be signed as `User Name `. Make
+sure to [set up Git with user name and email
+address](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup). Bug
+fixes should branch from the current stable branch
+
+### Formatting
+
+This repository uses the `tox` and `pre-commit` tools to run
+autoformatters on the entire repository. These two tools are the
+industry standard for Python. The goal of these formatters is to
+delegate issues of formatting to the machine so that develeopers and
+code-reviewers can focus on more important things.
+
+The two main autoformatters that we use are
+ - `black`: General Python formatting
+ - `isort`: Import sorting
+
+## Running the formatting
+
+The formatting is automatically run remotely on every Github pull
+request and on every push to Github.
+
+It is possible to run these locally in two ways. Automatically before
+every push and manually.
+
+To have the checks run automatically before every push you can enable
+`pre-commit`.
+
+```
+tox
+.tox/format/bin/pre-commit install --hook-type pre-push
+```
+
+To run the checks manually:
+On the entire repository
+```
+ tox -- --all-files
+```
+on a specific file
+```
+ tox -- --file
+```
+On every file in the most recent commit
+```
+ git diff-tree --no-commit-id --name-only -r HEAD | xargs tox -- --files
+```
+
## Something neat worth noting
Each of the scripts leverage
[docopt](https://github.com/docopt/docopt), which is a great module
diff --git a/add_windows_env.py b/add_windows_env.py
deleted file mode 100755
index 0081c32..0000000
--- a/add_windows_env.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-#Adam Bowen Sept 2016
-VERSION="v.0.0.001"
-#just a quick and dirty example of adding a windows source
-
-from delphixpy.delphix_engine import DelphixEngine
-from delphixpy.web import environment
-from delphixpy.web.vo import HostEnvironmentCreateParameters, EnvironmentUser, PasswordCredential, \
- WindowsHostEnvironment, WindowsHostCreateParameters, WindowsHost
-
-engine_address = "192.168.2.37"
-engine_username = "delphix_admin"
-engine_password = "landshark"
-
-def serversess(f_engine_address, f_engine_username, f_engine_password):
- """
- Function to setup the session with the Delphix Engine
- """
- server_session= DelphixEngine(f_engine_address, f_engine_username, f_engine_password, "DOMAIN")
- return server_session
-
-server = serversess(engine_address, engine_username, engine_password)
-
-envCreateParams = HostEnvironmentCreateParameters()
-
-
-envCreateParams.primary_user = EnvironmentUser()
-envCreateParams.primary_user.name = "delphix\delphix_admin"
-envCreateParams.primary_user.credential = PasswordCredential()
-envCreateParams.primary_user.credential.password = "delphix"
-envCreateParams.host_environment = WindowsHostEnvironment()
-envCreateParams.host_environment.name = "WINDOWSSOURCE"
-envCreateParams.host_environment.proxy = "WINDOWS_HOST-6" #This is the Host ID of the Windows Server that houses the connector
-envCreateParams.host_parameters = WindowsHostCreateParameters()
-envCreateParams.host_parameters.host = WindowsHost()
-envCreateParams.host_parameters.host.address = "WINDOWSSOURCE"
-
-environment.create(server, envCreateParams)
diff --git a/config/dxtools.conf b/config/dxtools.conf
new file mode 100644
index 0000000..9f02d3d
--- /dev/null
+++ b/config/dxtools.conf
@@ -0,0 +1,12 @@
+{
+ "myve2": [
+ {
+ "ip_address": "18.207.2.95",
+ "username": "delphix_admin",
+ "password": "delphix",
+ "use_https": "True",
+ "default": "True",
+ "hostname": "myve2"
+ }
+ ]
+}
diff --git a/delphix_admin_setup.py b/delphix_admin_setup.py
deleted file mode 100755
index 2897434..0000000
--- a/delphix_admin_setup.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python
-'''
-Adam Bowen - Jan 2016
-This script configures the delphix_admin user after domain0 is configured
-Will come back and properly throw this with logging, etc
-'''
-VERSION="v.2.3.002"
-CONTENTDIR="/u02/app/content"
-
-import getopt
-import logging
-from os.path import basename
-import signal
-import sys
-import time
-import traceback
-import untangle
-
-from delphixpy.v1_6_0.delphix_engine import DelphixEngine
-from delphixpy.v1_6_0.exceptions import HttpError, JobError
-from delphixpy.v1_6_0.web import user
-from delphixpy.v1_6_0.web.vo import CredentialUpdateParameters, PasswordCredential, User
-
-
-def serversess(f_engine_address, f_engine_username, f_engine_password):
- '''
- Function to grab the server session
- '''
- server_session= DelphixEngine(f_engine_address, f_engine_username, f_engine_password, "DOMAIN")
- return server_session
-
-def help():
- print("\n" + basename(__file__)+ " [-e ] [-o - Engine must be up, unconfigured, and console screen must be green")
- print("-o - will use this password to initially access the system")
- print("-p - will set the delphix_admin user to this password")
- print("-v - Print version information and exit")
- sys.exit(2)
-
-def logging_est():
- '''
- Establish Logging
- '''
- global debug
- logging.basicConfig(filename='landshark_setup.log',format='%(levelname)s:%(asctime)s:%(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
- print_info("Welcome to " + basename(__file__) + ", version " + VERSION)
- global logger
- debug = True
- logger = logging.getLogger()
- logger.setLevel(10)
- print_info("Debug Logging is enabled.")
-
-def on_exit(sig, func=None):
- print_info("Shutdown Command Received")
- print_info("Shutting down prime_setup.py")
- sys.exit(0)
-
-def print_debug(print_obj):
- '''
- DEBUG Log-level
- '''
- if debug == True:
- print "DEBUG: " + str(print_obj)
- logging.debug(str(print_obj))
-
-def print_error(print_obj):
- '''
- ERROR Log-level
- '''
- print "ERROR: " + str(print_obj)
- logging.error(str(print_obj))
-
-def print_info(print_obj):
- '''
- INFO Log-level
- '''
- print "INFO: " + str(print_obj)
- logging.info(str(print_obj))
-
-def print_warning(print_obj):
- '''
- WARNING Log-level
- '''
- print "WARNING: " + str(print_obj)
- logging.warning(str(print_obj))
-
-def set_exit_handler(func):
- signal.signal(signal.SIGTERM, func)
-
-def time_elapsed():
- elapsed_minutes = round((time.time() - time_start)/60, +1)
- return elapsed_minutes
-
-def version():
- print("Version: " +VERSION)
- logging_est()
- set_exit_handler(on_exit)
- sys.exit(1)
-
-def main(argv):
- try:
- logging_est()
- global time_start
- time_start = time.time()
- engine_ip = ""
- engine_pass = ""
- old_engine_pass = ""
- try:
- opts,args = getopt.getopt(argv,"e:o:p:hv")
- except getopt.GetoptError:
- help()
- for opt, arg in opts:
- if opt == '-h':
- help()
- elif opt == '-e':
- engine_ip = arg
- elif opt == '-o':
- old_engine_pass = arg
- elif opt == '-p':
- engine_pass = arg
- elif opt == '-v':
- version()
-
- if (engine_ip == "" or engine_pass == "" or old_engine_pass == "") :
- help()
-
- server = serversess(engine_ip, "delphix_admin", old_engine_pass)
-
- if user.get(server, "USER-2").email_address == None:
- print_debug("Setting delphix_admin's email address")
- delphix_admin_user = User()
- delphix_admin_user.email_address = "spam@delphix.com"
- user.update(server, 'USER-2', delphix_admin_user)
-
- print_debug("Setting delphix_admin's password")
- delphix_admin_credupdate = CredentialUpdateParameters()
- delphix_admin_credupdate.new_credential = PasswordCredential()
- delphix_admin_credupdate.new_credential.password = engine_pass
- user.update_credential(server, 'USER-2', delphix_admin_credupdate)
- else:
- print_info("The delphix_admin user has already been setup")
-
- except SystemExit as e:
- sys.exit(e)
- except HttpError as e:
- print_error("Connection failed to the Delphix Engine")
- print_error( "Please check the ERROR message below")
- print_error(e.message)
- sys.exit(2)
- except JobError as e:
- print_error("A job failed in the Delphix Engine")
- print_error(e.job)
- elapsed_minutes = time_elapsed()
- print_info("Prime took " + str(elapsed_minutes) + " minutes to get this far.")
- except KeyboardInterrupt:
- print_debug("You sent a CTRL+C to interrupt the process")
- elapsed_minutes = time_elapsed()
- print_info("Prime took " + str(elapsed_minutes) + " minutes to get this far.")
- except:
- print_error(sys.exc_info()[0])
- print_error(traceback.format_exc())
- elapsed_minutes = time_elapsed()
- print_info("Prime took " + str(elapsed_minutes) + " minutes to get this far.")
-
-if __name__ == "__main__":
- main(sys.argv[1:])
diff --git a/delphix_snapshot_group_will_plugin.py b/delphix_snapshot_group_will_plugin.py
deleted file mode 100755
index 89833f2..0000000
--- a/delphix_snapshot_group_will_plugin.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-#For use with HipChat and Will
-#https://github.com/skoczen/will
-
-from will.plugin import WillPlugin
-from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings
-from delphixpy.v1_6_0.delphix_engine import DelphixEngine
-from delphixpy.v1_6_0.web import group, database
-from delphixpy.v1_6_0 import job_context
-
-class DelphixSnapshotPlugin(WillPlugin):
-
- @respond_to("snapshot_group (?P.*)")
- def snapshot_group_will(self, message, v_object=None):
- group_name = v_object
- #database_name = "Employee DB - Dev"
-
- server_session = DelphixEngine("landsharkengine", "delphix_admin", "landshark", "DOMAIN")
-
- all_groups = group.get_all(server_session)
-
- for each in all_groups:
- if group_name == each.name:
- group_reference = each.reference
- break
-
- database_objs = database.get_all(server_session, group=group_reference)
-
- with job_context.async(server_session):
- for obj in database_objs:
- database.sync(server_session, obj.reference)
diff --git a/delphix_will_plugin.py b/delphix_will_plugin.py
deleted file mode 100755
index ba58e07..0000000
--- a/delphix_will_plugin.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-#For use with HipChat and Will
-#https://github.com/skoczen/will
-
-from will.plugin import WillPlugin
-from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings
-from delphixpy.v1_6_0.delphix_engine import DelphixEngine
-from delphixpy.v1_6_0.web import database
-import imp, subprocess, shlex
-
-VERSION=0.001
-
-
-
-class DelphixPlugin(WillPlugin):
-
- @respond_to("listvdbs")
- def list_databases_will(self, message):
- foo = imp.load_source('list_all_databases', 'delphixpy-examples/list_all_databases.py')
- vdblist="\n".join(each.name for each in foo.all_databases)
- will_response = "There are " + str(len(foo.all_databases)) + " databases in the LandsharkEngine\n" + vdblist
- self.reply(message, will_response)
-
- @respond_to("snapshot (?P.*)")
- def snapshot_databases_will(self, message, v_object=None):
- if " in " not in v_object:
- will_response="Please specify group with request. For example:\n \
- snapshot Employee Oracle 11G DB in Sources"
- self.reply(message, will_response)
- else:
- v_object = v_object.split(' in ',1)
- vdb_name = v_object[0]
- vdb_group = v_object[1]
- self.reply(message, "Snapping " + vdb_name + ". Will let you know when it is complete.")
- p = subprocess.Popen(['python', 'delphixpy-examples/dx_snapshot_db.py', '--group', vdb_group, '--name', \
- vdb_name, '--config', 'delphixpy-examples/dxtools.conf'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- self.reply(message, vdb_name + " Snapshot Complete\n" + p.stdout.read())
-
- @respond_to("provision vdb (?P.*)")
- def provision_databases_will(self, message, v_object=None):
- provision_parameters = shlex.split('python delphixpy-examples/dx_provision_vdb.py --config delphixpy-examples/dxtools.conf ' + v_object)
- self.reply(message, str(provision_parameters))
- self.reply(message, "Executing provision job")
- p = subprocess.Popen(provision_parameters, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- self.reply(message, "Provision Request Complete\n" + p.stdout.read())
-
- @respond_to("delete vdb (?P.*)")
- def delete_databases_will(self, message, v_object=None):
- if " in " not in v_object:
- will_response="Please specify group with request. For example:\n \
- delete Employee Oracle 11G DB in Sources"
- self.reply(message, will_response)
- else:
- v_object = v_object.split(' in ',1)
- vdb_name = v_object[0]
- vdb_group = v_object[1]
- self.reply(message, "Deleting " + vdb_name + ". Will let you know when it is complete.")
- p = subprocess.Popen(['python', 'delphixpy-examples/dx_delete_vdb.py', '--group', vdb_group, '--name', \
- vdb_name, '--config', 'delphixpy-examples/dxtools.conf'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- self.reply(message, vdb_name + " Delete Complete\n" + p.stdout.read())
-
- @respond_to("refresh vdb (?P.*)")
- def refresh_vdbs_will(self, message, v_object=None):
- if " in " not in v_object:
- will_response="Please specify group with request. For example:\n \
- refresh autoprod in Analytics"
- self.reply(message, will_response)
- else:
- v_object = v_object.split(' in ',1)
- vdb_name = v_object[0]
- vdb_group = v_object[1]
- self.reply(message, "Refreshing " + vdb_name + ". Will let you know when it is complete.")
- p = subprocess.Popen(['python', 'delphixpy-examples/dx_refresh_db.py', '--group', vdb_group, '--name', \
- vdb_name, '--config', 'delphixpy-examples/dxtools.conf', '--timestamp', '@2016-10-14T20:55:05.995Z'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- self.reply(message, vdb_name + " Refresh Complete\n" + p.stdout.read())
-
- @respond_to("refresh jetstream (?P.*)")
- def refresh_jetstream_will(self, message, v_object=None):
- if " in " not in v_object:
- will_response="Please specify group with request. For example:\n \
- refresh jetstream Sugar Automated Testing Container in Masked SugarCRM Application"
- self.reply(message, will_response)
- else:
- v_object = v_object.split(' in ',1)
- container_name = v_object[0]
- container_template = v_object[1]
- self.reply(message, "Refreshing Jetstream Container: " + container_name + ". Will let you know when it is complete.")
- p = subprocess.Popen(['python', 'delphixpy-examples/dx_jetstream_container.py', '--operation', 'refresh', \
- '--template', container_template, '--container', container_name, '--config', 'delphixpy-examples/dxtools.conf'], \
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- self.reply(message, container_name + " Refresh Complete\n" + p.stdout.read())
-
- @respond_to("bonjour")
- def say_bonjour_will(self, message):
- """bonjour: Landshark parles the Francais!"""
- self.reply(message, "bonjour! Je m'appelle Landshark! Je suis pret a travailler!")
diff --git a/dx_authorization.py b/dx_authorization.py
deleted file mode 100755
index d35dbae..0000000
--- a/dx_authorization.py
+++ /dev/null
@@ -1,447 +0,0 @@
-#!/usr/bin/env python
-# Corey Brune - Oct 2016
-# Creates an authorization object
-# requirements
-# pip install docopt delphixpy
-
-# The below doc follows the POSIX compliant standards and allows us to use
-# this doc to also define our arguments for the script.
-"""List, create or remove authorizations for a Virtualization Engine
-Usage:
- dx_authorization.py (--create --role --target_type --target --user | --list | --delete --role --target_type --target --user )
- [--engine | --all]
- [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_authorization.py -h | --help | -v | --version
-List, delete and create authentication objects
-
-Examples:
- dx_authorization.py --engine landsharkengine --create --role Data --user dev_user --target_type database --target test_vdb
- dx_authorization.py --engine landsharkengine --create --role Data --user dev_user --target_type group --target Sources
- dx_authorization.py --list
- dx_authorization.py --delete --role Data --user dev_user --target_type database --target test_vdb
-
-Options:
- --create Create an authorization
- --role Role for authorization. Valid Roles are Data,
- Read, Jet Stream User, OWNER, PROVISIONER
- --target Target object for authorization
- --target_type Target type. Valid target types are snapshot,
- group, database
- --user User for the authorization
- --list List all authorizations
- --delete Delete authorization
- --engine Alt Identifier of Delphix engine in dxtools.conf.
- --all Run against all engines.
- --debug Enable debug logging
- --parallel Limit number of jobs to maxjob
- --poll The number of seconds to wait between job polls
- [default: 10]
- --config The path to the dxtools.conf file
- [default: ./dxtools.conf]
- --logdir The path to the logfile you want to use.
- [default: ./dx_authorization.log]
- -h --help Show this screen.
- -v --version Show version.
-"""
-
-VERSION = 'v.0.0.015'
-
-from docopt import docopt
-from os.path import basename
-import sys
-from time import sleep, time
-import traceback
-
-from delphixpy.v1_8_0.exceptions import JobError
-from delphixpy.v1_8_0.exceptions import RequestError
-from delphixpy.v1_8_0.exceptions import HttpError
-from delphixpy.v1_8_0.web import database
-from delphixpy.v1_8_0.web import job
-from delphixpy.v1_8_0.web import role
-from delphixpy.v1_8_0.web import authorization
-from delphixpy.v1_8_0.web import user
-from delphixpy.v1_8_0.web import snapshot
-from delphixpy.v1_8_0.web import group
-from delphixpy.v1_8_0.web.vo import User
-from delphixpy.v1_8_0.web.vo import Authorization
-
-from lib.DlpxException import DlpxException
-from lib.GetSession import GetSession
-from lib.GetReferences import find_obj_by_name
-from lib.DxLogging import logging_est
-from lib.DxLogging import print_info
-from lib.DxLogging import print_debug
-from lib.DxLogging import print_exception
-
-
-def create_authorization(dlpx_obj, role_name, target_type, target_name,
- user_name):
- """
- Function to start, stop, enable or disable a VDB
-
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
- :param role_name: Name of the role
- :param target_type: Supports snapshot, group and database target types
- :param target_name: Name of the target
- :param user_name: User for the authorization
- """
-
- authorization_obj = Authorization()
- print_debug('Searching for {}, {} and {} references.\n'.format(
- role_name, target_name, user_name))
- try:
- authorization_obj.role = find_obj_by_name(dlpx_obj.server_session, role,
- role_name).reference
- authorization_obj.target = find_target_type(dlpx_obj, target_type,
- target_name).reference
- authorization_obj.user = find_obj_by_name(dlpx_obj.server_session, user,
- user_name).reference
- authorization.create(dlpx_obj.server_session, authorization_obj)
- except (RequestError, HttpError, JobError) as e:
- print_exception('An error occurred while creating authorization:\n'
- '{}'.format(e))
- print 'Authorization successfully created for {}.'.format(user_name)
-
-
-def delete_authorization(dlpx_obj, role_name, target_type, target_name,
- user_name):
- """
- Function to delete a given authorization
-
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
- :param role_name: Name of the role
- :type role_name: basestring
- :param target_type: Supports snapshot, group and database target types
- :type target_type basestring
- :param target_name: Name of the target
- :type target_name: basestring
- :param user_name: User for the authorization
- :type user_name: basestring
- """
- target_obj = find_target_type(dlpx_obj, target_type, target_name)
- user_obj = find_obj_by_name(dlpx_obj.server_session, user,
- user_name)
- role_obj = find_obj_by_name(dlpx_obj.server_session, role,
- role_name)
- auth_objs = authorization.get_all(dlpx_obj.server_session)
-
- try:
-
- del_auth_str = '({}, {}, {})'.format(user_obj.reference,
- role_obj.reference,
- target_obj.reference)
- for auth_obj in auth_objs:
- if auth_obj.name == del_auth_str:
- authorization.delete(dlpx_obj.server_session,
- auth_obj.reference)
- except DlpxException as e:
- print_exception('ERROR: Could not delete authorization:\n{}'.format(e))
- print '{} for user {} was deleted successfully'.format(target_name,
- user_name)
-
-
-def find_target_type(dlpx_obj, target_type, target_name):
- """
- Function to find the target authorization
-
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
- :param target_type: Type of target for authorization
- :param target_name: Name of the target
- """
-
- target_obj = None
- try:
- if target_type.lower() == 'group':
- target_obj = find_obj_by_name(dlpx_obj.server_session, group,
- target_name)
- elif target_type.lower() == 'database':
- target_obj = find_obj_by_name(dlpx_obj.server_session, database,
- target_name)
- elif target_type.lower() == 'snapshot':
- target_obj = find_obj_by_name(dlpx_obj.server_session, snapshot,
- target_name)
- except (DlpxException, RequestError, HttpError) as e:
- print_exception('Could not find authorization target type '
- '{}:\n{}'.format(target_type, e))
- return target_obj
-
-
-def list_authorization(dlpx_obj):
- """
- Function to list authorizations for a given engine
-
- :param dlpx_obj: Virtualization Engine session object
- """
- target_obj = None
-
- try:
- auth_objs = authorization.get_all(dlpx_obj.server_session)
- print_info('User, Role, Target, Reference')
- for auth_obj in auth_objs:
- role_obj = role.get(dlpx_obj.server_session, auth_obj.role)
- user_obj = user.get(dlpx_obj.server_session, auth_obj.user)
- if auth_obj.target.startswith('USER'):
- target_obj = user.get(dlpx_obj.server_session, auth_obj.target)
- elif auth_obj.target.startswith('GROUP'):
- target_obj = group.get(dlpx_obj.server_session, auth_obj.target)
- elif auth_obj.target.startswith('DOMAIN'):
- target_obj = User()
- target_obj.name = 'DOMAIN'
- print '{}, {}, {}, {}'.format(user_obj.name, role_obj.name,
- target_obj.name,
- auth_obj.reference)
- except (RequestError, HttpError, JobError, AttributeError) as e:
- print_exception('An error occurred while listing authorizations.:\n'
- '{}\n'.format((e)))
-
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
- E.g.:
- @run_async
- def task1():
- do_something
- @run_async
- def task2():
- do_something_too
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- from threading import Thread
- from functools import wraps
-
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
-
- return async_func
-
-
-@run_async
-def main_workflow(engine, dlpx_obj):
- """
- This function actually runs the jobs.
- Use the @run_async decorator to run this function asynchronously.
- This allows us to run against multiple Delphix Engine simultaneously
-
- engine: Dictionary of engines
- :type engine: dict
- dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
-
- """
-
- try:
- # Setup the connection to the Delphix Engine
- dlpx_obj.serversess(engine['ip_address'], engine['username'],
- engine['password'])
- except DlpxException as e:
- print_exception('ERROR: js_bookmark encountered an error authenticating'
- ' to {} {}:\n{}\n'.format(engine['hostname'],
- arguments['--target'], e))
- thingstodo = ["thingtodo"]
- try:
- with dlpx_obj.job_mode(single_thread):
- while (len(dlpx_obj.jobs) > 0 or len(thingstodo) > 0):
- if len(thingstodo) > 0:
- if arguments['--create']:
- create_authorization(dlpx_obj, arguments['--role'],
- arguments['--target_type'],
- arguments['--target'],
- arguments['--user'])
- elif arguments['--delete']:
- delete_authorization(dlpx_obj, arguments['--role'],
- arguments['--target_type'],
- arguments['--target'],
- arguments['--user'])
- elif arguments['--list']:
- list_authorization(dlpx_obj)
- thingstodo.pop()
- # get all the jobs, then inspect them
- i = 0
- for j in dlpx_obj.jobs.keys():
- job_obj = job.get(dlpx_obj.server_session,
- dlpx_obj.jobs[j])
- print_debug(job_obj)
- print_info('{}: : {}'.format(
- engine['hostname'], job_obj.job_state))
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- # If the job is in a non-running state, remove it
- # from the running jobs list.
- del dlpx_obj.jobs[j]
- elif job_obj.job_state in 'RUNNING':
- # If the job is in a running state, increment the
- # running job count.
- i += 1
- print_info('{}: {:d} jobs running.'.format(
- engine['hostname'], i))
- # If we have running jobs, pause before repeating the
- # checks.
- if len(dlpx_obj.jobs) > 0:
- sleep(float(arguments['--poll']))
- except (DlpxException, RequestError, JobError, HttpError) as e:
- print_exception('\nError in dx_authorization: {}\n{}'.format(
- engine['hostname'], e))
- sys.exit(1)
-
-
-def run_job(dlpx_obj, config_file_path):
- """
- This function runs the main_workflow aynchronously against all the
- servers specified
-
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
- :param config_file_path: string containing path to configuration file.
- :type config_file_path: str
- """
-
- # Create an empty list to store threads we create.
- threads = []
- engine = None
-
- # If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info('Executing against all Delphix Engines in the dxtools.conf')
- try:
- # For each server in the dxtools.conf...
- for delphix_engine in dlpx_obj.dlpx_engines:
- engine = dlpx_obj.dlpx_engines[delphix_engine]
- # Create a new thread and add it to the list.
- threads.append(main_workflow(engine, dlpx_obj))
- except DlpxException as e:
- print_exception('Error encountered in run_job():\n{}'.format(e))
- sys.exit(1)
-
- elif arguments['--all'] is False:
- # Else if the --engine argument was given, test to see if the engine
- # exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dlpx_obj.dlpx_engines[arguments['--engine']]
- print_info('Executing against Delphix Engine: {}\n'.format(
- arguments['--engine']))
- except (DlpxException, RequestError, KeyError):
- raise DlpxException('\nERROR: Delphix Engine {} cannot be '
- 'found in {}. Please check your value and'
- ' try again. Exiting.\n'.format(
- arguments['--engine'], config_file_path))
- else:
- # Else search for a default engine in the dxtools.conf
- for delphix_engine in dlpx_obj.dlpx_engines:
- if dlpx_obj.dlpx_engines[delphix_engine]['default'] == 'true':
- engine = dlpx_obj.dlpx_engines[delphix_engine]
- print_info('Executing against the default Delphix Engine '
- 'in the dxtools.conf: {}'.format(
- dlpx_obj.dlpx_engines[delphix_engine]['hostname']))
- break
-
- if engine is None:
- raise DlpxException('\nERROR: No default engine found. Exiting')
-
- # run the job against the engine
- threads.append(main_workflow(engine, dlpx_obj))
-
- # For each thread in the list...
- for each in threads:
- # join them back together so that we wait for all threads to complete
- # before moving on
- each.join()
-
-
-def time_elapsed(time_start):
- """
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
-
- :param time_start: float containing start time of the script.
- """
- return round((time() - time_start)/60, +1)
-
-
-def main():
- # We want to be able to call on these variables anywhere in the script.
- global single_thread
- global debug
-
- time_start = time()
- single_thread = False
-
- try:
- dx_session_obj = GetSession()
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- config_file_path = arguments['--config']
- # Parse the dxtools.conf and put it into a dictionary
- dx_session_obj.get_config(config_file_path)
-
- # This is the function that will handle processing main_workflow for
- # all the servers.
- run_job(dx_session_obj, config_file_path)
-
- elapsed_minutes = time_elapsed(time_start)
- print_info('script took {:.2f} minutes to get this far.'.format(
- elapsed_minutes))
-
- # Here we handle what we do when the unexpected happens
- except SystemExit as e:
- # This is what we use to handle our sys.exit(#)
- sys.exit(e)
-
- except DlpxException as e:
- # We use this exception handler when an error occurs in a function call.
- print_exception('ERROR: Please check the ERROR message below:\n'
- '{}'.format(e.message))
- sys.exit(2)
-
- except HttpError as e:
- # We use this exception handler when our connection to Delphix fails
- print_exception('ERROR: Connection failed to the Delphix Engine. Please'
- 'check the ERROR message below:\n{}'.format(e.message))
- sys.exit(2)
-
- except JobError as e:
- # We use this exception handler when a job fails in Delphix so that we
- # have actionable data
- print_exception('A job failed in the Delphix Engine:\n{}'.format(e.job))
- elapsed_minutes = time_elapsed(time_start)
- print_exception('{} took {:.2f} minutes to get this far'.format(
- basename(__file__), elapsed_minutes))
- sys.exit(3)
-
- except KeyboardInterrupt:
- # We use this exception handler to gracefully handle ctrl+c exits
- print_debug('You sent a CTRL+C to interrupt the process')
- elapsed_minutes = time_elapsed(time_start)
- print_info('{} took {:.2f} minutes to get this far'.format(
- basename(__file__), elapsed_minutes))
- except:
- # Everything else gets caught here
- print_exception('{}\n{}'.format(sys.exc_info()[0],
- traceback.format_exc()))
- elapsed_minutes = time_elapsed(time_start)
- print_info("{} took {:.2f} minutes to get this far".format(
- basename(__file__), elapsed_minutes))
- sys.exit(1)
-
-
-if __name__ == "__main__":
- # Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
-
- # Feed our arguments to the main function, and off we go!
- main()
\ No newline at end of file
diff --git a/dx_delete_vdb.py b/dx_delete_vdb.py
index ca2d242..37c3ca2 100755
--- a/dx_delete_vdb.py
+++ b/dx_delete_vdb.py
@@ -1,573 +1,236 @@
-#!/usr/bin/env python
-#Adam Bowen - Apr 2016
-#This script deletes a vdb
-#requirements
-#pip install docopt delphixpy
-
-#The below doc follows the POSIX compliant standards and allows us to use
-#this doc to also define our arguments for the script. This thing is brilliant.
-"""Delete a VDB
-
+#!/usr/bin/env python3
+# Adam Bowen - Apr 2016
+# This script refreshes a vdb
+# Updated by Corey Brune Oct 2016
+# requirements
+# pip install --upgrade setuptools pip docopt delphixpy
+
+# The below doc follows the POSIX compliant standards and allows us to use
+# this doc to also define our ARGUMENTS for the script.
+"""Refresh a vdb
Usage:
- dx_delete_db.py (--group [--name ] | --all_dbs )
- [-d | --engine | --all]
- [--usebackup] [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_delete_db.py (--host [--group ] [--object_type ]
- | --object_type [--group ] [--host ] )
- [-d | --engine | --all]
- [--usebackup] [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_delete_db.py -h | --help | -v | --version
-
-Delete a VDB
-
+ dx_delete_vdb.py --vdb
+ [--engine ]
+ [--group_name ][--force][--debug]
+ [--poll ] [--single_thread ]
+ [--config ] [--logdir ]
+ dx_delete_vdb.py -h | --help | -v | --version
+
+Delete a Delphix VDB
Examples:
- dx_delete_db.py --group "Sources" --object_type dsource --usebackup
- dx_delete_db.py --name "Employee Oracle 11G DB"
- dx_delete_db.py --host LINUXSOURCE --parallel 2 --usebackup
- dx_delete_db.py --host LINUXSOURCE --parallel 4 --usebackup --debug -d landsharkengine
-
-
-
+ dx_delete_vdb.py --vdb aseTest
+ dx_delete_vdb.py --vdb aseTest --engine myengine --single_thread False --force
Options:
- -d Identifier of Delphix engine in dxtools.conf.
- --engine Alt Identifier of Delphix engine in dxtools.conf.
- --all Run against all engines.
- --all_dbs Run against all database objects
- --name Name of object in Delphix to execute against.
- --group Name of group in Delphix to execute against.
- --host Name of environment in Delphix to execute against.
- --object_type dsource or vdb.
- --usebackup Snapshot using "Most Recent backup".
- Available for MSSQL and ASE only.
+ --vdb Name of the VDB to delete.
+ --group_name Name of the group to execute against.
+ --single_thread Run as a single thread. Use True if there are
+ multiple engines and the operation needs to run
+ in parallel.
+ [default: False]
+ --engine Identifier for Delphix engine in dxtools.conf.
+ [default: default]
--debug Enable debug logging
--parallel Limit number of jobs to maxjob
--poll The number of seconds to wait between job polls
[default: 10]
--config The path to the dxtools.conf file
- [default: ./dxtools.conf]
- --logdir The path to the logfile you want to use.
- [default: ./dx_snapshot_db.log]
+ [default: ./config/dxtools.conf]
+ --logdir The path to the logfile you want to use.
+ [default: ./logs/dx_delete_vdb.log]
+ --force Force delete
-h --help Show this screen.
-v --version Show version.
-
"""
-VERSION="v.0.0.001"
-
-
-from docopt import docopt
-import logging
-from os.path import basename
-import signal
import sys
import time
-import traceback
-import json
-
-from multiprocessing import Process
-from time import sleep, time
-
-from delphixpy.v1_6_0.delphix_engine import DelphixEngine
-from delphixpy.v1_6_0.exceptions import HttpError, JobError
-from delphixpy.v1_6_0 import job_context
-from delphixpy.v1_6_0.web import database, environment, group, job, source, user
-from delphixpy.v1_6_0.web.vo import ASESpecificBackupSyncParameters, ASENewBackupSyncParameters, ASELatestBackupSyncParameters, MSSqlSyncParameters
-
-
-def find_obj_by_name(engine, server, f_class, obj_name):
- """
- Function to find objects by name and object class, and return object's reference as a string
- You might use this function to find objects like groups.
- """
- print_debug(engine["hostname"] + ": Searching objects in the " + f_class.__name__ + " class\n for one named \"" + obj_name +"\"")
- obj_ref = ''
-
- all_objs = f_class.get_all(server)
- for obj in all_objs:
- if obj.name == obj_name:
- print_debug(engine["hostname"] + ": Found a match " + str(obj.reference))
- return obj
-
-def find_all_databases_by_group_name(engine, server, group_name, exclude_js_container=False):
- """
- Easy way to quickly find databases by group name
- """
-
- #First search groups for the name specified and return its reference
- group_obj = find_obj_by_name(engine, server, group, group_name)
- if group_obj:
- databases=database.get_all(server, group=group_obj.reference, no_js_container_data_source=exclude_js_container)
- return databases
-
-def find_database_by_name_and_group_name(engine, server, group_name, database_name):
-
- databases = find_all_databases_by_group_name(engine, server, group_name)
-
- for each in databases:
- if each.name == database_name:
- print_debug(engine["hostname"] + ": Found a match " + str(each.reference))
- return each
- print_info("Unable to find \"" + database_name + "\" in " + group_name)
-
-def find_source_by_database(engine, server, database_obj):
- #The source tells us if the database is enabled/disables, virtual, vdb/dSource, or is a staging database.
- source_obj = source.get_all(server, database=database_obj.reference)
- #We'll just do a little sanity check here to ensure we only have a 1:1 result.
- if len(source_obj) == 0:
- print_error(engine["hostname"] + ": Did not find a source for " + database_obj.name + ". Exiting")
- sys.exit(1)
- elif len(source_obj) > 1:
- print_error(engine["hostname"] + ": More than one source returned for " + database_obj.name + ". Exiting")
- print_error(source_obj)
- sys.exit(1)
- return source_obj
-
-def get_config(config_file_path):
- """
- This function reads in the dxtools.conf file
- """
- #First test to see that the file is there and we can open it
- try:
- config_file = open(config_file_path).read()
- except:
- print_error("Was unable to open " + config_file_path + ". Please check the path and permissions, then try again.")
- sys.exit(1)
- #Now parse the file contents as json and turn them into a python dictionary, throw an error if it isn't proper json
- try:
- config = json.loads(config_file)
- except:
- print_error("Was unable to read " + config_file_path + " as json. Please check file in a json formatter and try again.")
- sys.exit(1)
- #Create a dictionary of engines (removing the data node from the dxtools.json, for easier parsing)
- delphix_engines = {}
- for each in config['data']:
- delphix_engines[each['hostname']] = each
- print_debug(delphix_engines)
- return delphix_engines
-
-def logging_est(logfile_path):
- """
- Establish Logging
- """
- global debug
- logging.basicConfig(filename=logfile_path,format='%(levelname)s:%(asctime)s:%(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
- print_info("Welcome to " + basename(__file__) + ", version " + VERSION)
- global logger
- debug = arguments['--debug']
- logger = logging.getLogger()
- if debug == True:
- logger.setLevel(10)
- print_info("Debug Logging is enabled.")
-
-def job_mode(server):
- """
- This function tells Delphix how to execute jobs, based on the single_thread variable at the beginning of the file
- """
- #Synchronously (one at a time)
- if single_thread == True:
- job_m = job_context.sync(server)
- print_debug("These jobs will be executed synchronously")
- #Or asynchronously
- else:
- job_m = job_context.async(server)
- print_debug("These jobs will be executed asynchronously")
- return job_m
-
-def job_wait():
- """
- This job stops all work in the thread/process until jobs are completed.
- """
- #Grab all the jos on the server (the last 25, be default)
- all_jobs = job.get_all(server)
- #For each job in the list, check to see if it is running (not ended)
- for jobobj in all_jobs:
- if not (jobobj.job_state in ["CANCELED", "COMPLETED", "FAILED"]):
- print_debug("Waiting for " + jobobj.reference + " (currently: " + jobobj.job_state+ ") to finish running against the container")
- #If so, wait
- job_context.wait(server,jobobj.reference)
-
-def on_exit(sig, func=None):
- """
- This function helps us end cleanly and with exit codes
- """
- print_info("Shutdown Command Received")
- print_info("Shutting down " + basename(__file__))
- sys.exit(0)
-
-def print_debug(print_obj):
- """
- Call this function with a log message to prefix the message with DEBUG
- """
- try:
- if debug == True:
- print "DEBUG: " + str(print_obj)
- logging.debug(str(print_obj))
- except:
- pass
-
-def print_error(print_obj):
- """
- Call this function with a log message to prefix the message with ERROR
- """
- print "ERROR: " + str(print_obj)
- logging.error(str(print_obj))
-
-def print_info(print_obj):
- """
- Call this function with a log message to prefix the message with INFO
- """
- print "INFO: " + str(print_obj)
- logging.info(str(print_obj))
-
-def print_warning(print_obj):
- """
- Call this function with a log message to prefix the message with WARNING
- """
- print "WARNING: " + str(print_obj)
- logging.warning(str(print_obj))
-
-def serversess(f_engine_address, f_engine_username, f_engine_password):
- """
- Function to setup the session with the Delphix Engine
- """
- server_session= DelphixEngine(f_engine_address, f_engine_username, f_engine_password, "DOMAIN")
- return server_session
-
-def set_exit_handler(func):
- """
- This function helps us set the correct exit code
- """
- signal.signal(signal.SIGTERM, func)
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
-
- E.g.:
- @run_async
- def task1():
- do_something
-
- @run_async
- def task2():
- do_something_too
-
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- from threading import Thread
- from functools import wraps
+from os.path import basename
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
+import docopt
+
+from delphixpy.v1_10_2 import exceptions
+from delphixpy.v1_10_2.web import database
+from delphixpy.v1_10_2.web import vo
+from lib import dlpx_exceptions
+from lib import dx_logging
+from lib import get_references
+from lib import get_session
+from lib import run_job
+from lib.run_async import run_async
+
+VERSION = "v.0.3.002"
+
+
+def delete_vdb(dlpx_obj, vdb_name, force_delete):
+ vdb_list = vdb_name.split(":")
+ for vdb in vdb_list:
+ dx_logging.print_info(f"delete_vdb for: {vdb}")
+ container_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, database, vdb
+ )
+ # Check to make sure our container object has a reference
+ source_obj = get_references.find_source_by_db_name(dlpx_obj.server_session, vdb)
+ if container_obj.reference:
+ try:
+ if source_obj.virtual is not True or source_obj.staging is True:
+ raise dlpx_exceptions.DlpxException(
+ f"ERROR: {container_obj.name} is not a virtual object"
+ )
+ else:
+ dx_logging.print_info(
+ f"INFO: Deleting {container_obj.name} on engine {dlpx_obj.server_session.address}"
+ )
+ delete_params = None
+ if force_delete and str(container_obj.reference).startswith(
+ "MSSQL"
+ ):
+ delete_params = vo.DeleteParameters()
+ delete_params.force = True
+ try:
+ dx_logging.print_info(f"triggering delete for: {vdb}")
+ database.delete(
+ dlpx_obj.server_session,
+ container_obj.reference,
+ delete_params,
+ )
+ dx_logging.print_info(f"delete for: {vdb} is running")
+ dlpx_obj.jobs[dlpx_obj.server_session.address].append(
+ dlpx_obj.server_session.last_job
+ )
+ except (
+ dlpx_exceptions.DlpxException,
+ exceptions.RequestError,
+ exceptions.HttpError,
+ ) as err:
+ raise dlpx_exceptions.DlpxException(f"{err}")
+ # This exception is raised if refreshing a vFiles VDB since
+ # AppDataContainer does not have virtual, staging or enabled attributes
+ except AttributeError as err:
+ dx_logging.print_exception(
+ f"ERROR: Deleting {container_obj.name} on engine {dlpx_obj.server_session.address}"
+ )
+ dx_logging.print_exception(f"AttributeError:{err}")
+ except dlpx_exceptions.DlpxException as err:
+ dx_logging.print_exception(f"DlpxException:{err}")
+ except Exception as err:
+ dx_logging.print_exception(f"Exception:\n{err}")
+ dx_logging.print_info(f" Delete operation has been initiated for vdbs ")
- return async_func
@run_async
-def main_workflow(engine):
+def main_workflow(engine, dlpx_obj, single_thread):
"""
- This function is where the main workflow resides.
+ This function is where we create our main workflow.
Use the @run_async decorator to run this function asynchronously.
- This allows us to run against multiple Delphix Engine simultaneously
+ The @run_async decorator allows us to run against multiple Delphix Engine
+ simultaneously
+ :param engine: Dictionary of engines
+ :type engine: dictionary
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param single_thread: True - run single threaded, False - run multi-thread
+ :type single_thread: bool
"""
-
- #Pull out the values from the dictionary for this engine
- engine_address = engine["ip_address"]
- engine_username = engine["username"]
- engine_password = engine["password"]
- #Establish these variables as empty for use later
- databases = []
- environment_obj = None
- source_objs = None
- jobs = {}
-
-
- #Setup the connection to the Delphix Engine
- server = serversess(engine_address, engine_username, engine_password)
-
- #If an environment/server was specified
- if host_name:
- print_debug(engine["hostname"] + ": Getting environment for " + host_name)
- #Get the environment object by the hostname
- environment_obj = find_obj_by_name(engine, server, environment, host_name)
- if environment_obj != None:
- #Get all the sources running on the server
- env_source_objs = source.get_all(server, environment=environment_obj.reference)
- #If the server doesn't have any objects, exit.
- if env_source_objs == None:
- print_error(host_name + "does not have any objects. Exiting")
- sys.exit(1)
- #If we are only filtering by the server, then put those objects in the main list for processing
- if not(arguments['--group'] and database_name):
- source_objs = env_source_objs
- all_dbs = database.get_all(server, no_js_container_data_source=False)
- databases = []
- for source_obj in source_objs:
- if source_obj.staging == False and source_obj.virtual == True:
- database_obj = database.get(server, source_obj.container)
- if database_obj in all_dbs:
- databases.append(database_obj)
- else:
- print_error(engine["hostname"] + ":No environment found for " + host_name + ". Exiting")
- sys.exit(1)
- #If we specified a specific database by name....
- if arguments['--name']:
- #Get the database object from the name
- database_obj = find_database_by_name_and_group_name(engine, server, arguments['--group'], arguments['--name'])
- if database_obj:
- databases.append(database_obj)
- #Else if we specified a group to filter by....
- elif arguments['--group']:
- print_debug(engine["hostname"] + ":Getting databases in group " + arguments['--group'])
- #Get all the database objects in a group.
- databases = find_all_databases_by_group_name(engine, server, arguments['--group'])
- #Else, if we said all vdbs ...
- elif arguments['--all_dbs'] and not arguments['--host'] :
- #Grab all databases
- databases = database.get_all(server, no_js_container_data_source=False)
- elif arguments['--object_type'] and not arguments['--host'] :
- databases = database.get_all(server)
- if not databases or len(databases) == 0:
- print_error("No databases found with the criterion specified")
+ try:
+ # Setup the connection to the Delphix DDP
+ dx_logging.print_info(f"Executing main_workflow")
+ dlpx_obj.dlpx_session(
+ engine["ip_address"],
+ engine["username"],
+ engine["password"],
+ engine["use_https"],
+ )
+ except dlpx_exceptions.DlpxException as err:
+ dx_logging.print_exception(
+ f"ERROR: dx_delete_vdb encountered an error authenticating to "
+ f'{engine["ip_address"]}:{err}'
+ )
+ dx_logging.print_exception(
+ f"Cannot continue operation on " f'{engine["ip_address"]}'
+ )
return
- #reset the running job count before we begin
- i = 0
- with job_mode(server):
- #While there are still running jobs or databases still to process....
- while (len(jobs) > 0 or len(databases) > 0):
- #While there are databases still to process and we are still under
- #the max simultaneous jobs threshold (if specified)
- while len(databases) > 0 and (arguments['--parallel'] == None or i < int(arguments['--parallel'])):
- #Give us the next database in the list, and remove it from the list
- database_obj = databases.pop()
- #Get the source of the database.
- #The source tells us if the database is enabled/disables, virtual, vdb/dSource, or is a staging database.
- source_obj = find_source_by_database(engine, server, database_obj)
- #If we applied the environment/server filter AND group filter, find the intersecting matches
- if environment_obj != None and (arguments['--group']):
- match = False
- for env_source_obj in env_source_objs:
- if source_obj[0].reference in env_source_obj.reference:
- match = True
- break
- if match == False:
- print_error(engine["hostname"] + ": " + database_obj.name + " does not exist on " + host_name + ". Exiting")
- return
- #Snapshot the database
- delete_job = delete_database(engine, server, jobs, source_obj[0], database_obj, arguments['--object_type'])
- #If delete_job has any value, then we know that a job was initiated.
- if delete_job:
- #increment the running job count
- i += 1
- #Check to see if we are running at max parallel processes, and report if so.
- if ( arguments['--parallel'] != None and i >= int(arguments['--parallel'])):
- print_info(engine["hostname"] + ": Max jobs reached (" + str(i) + ")")
- #reset the running jobs counter, as we are about to update the count from the jobs report.
- i = update_jobs_dictionary(engine, server, jobs)
- print_info(engine["hostname"] + ": " + str(i) + " jobs running. " + str(len(databases)) + " jobs waiting to run")
- #If we have running jobs, pause before repeating the checks.
- if len(jobs) > 0:
- sleep(float(arguments['--poll']))
-
-def run_job(engine):
- """
- This function runs the main_workflow aynchronously against all the servers specified
- """
- #Create an empty list to store threads we create.
- threads = []
- #If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info("Executing against all Delphix Engines in the dxtools.conf")
- #For each server in the dxtools.conf...
- for delphix_engine in dxtools_objects:
- engine = dxtools_objects[delphix_engine]
- #Create a new thread and add it to the list.
- threads.append(main_workflow(engine))
- else:
- #Else if the --engine argument was given, test to see if the engine exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dxtools_objects[arguments['--engine']]
- print_info("Executing against Delphix Engine: " + arguments['--engine'])
- except:
- print_error("Delphix Engine \"" + arguments['--engine'] + "\" cannot be found in " + config_file_path)
- print_error("Please check your value and try again. Exiting")
- sys.exit(1)
- #Else if the -d argument was given, test to see if the engine exists in dxtools.conf
- elif arguments['-d']:
- try:
- engine = dxtools_objects[arguments['-d']]
- print_info("Executing against Delphix Engine: " + arguments['-d'])
- except:
- print_error("Delphix Engine \"" + arguments['-d'] + "\" cannot be found in " + config_file_path)
- print_error("Please check your value and try again. Exiting")
- sys.exit(1)
- else:
- #Else search for a default engine in the dxtools.conf
- for delphix_engine in dxtools_objects:
- if dxtools_objects[delphix_engine]['default'] == 'true':
- engine = dxtools_objects[delphix_engine]
- print_info("Executing against the default Delphix Engine in the dxtools.conf: " + dxtools_objects[delphix_engine]['hostname'])
- break
- if engine == None:
- print_error("No default engine found. Exiting")
- sys.exit(1)
- #run the job against the engine
- threads.append(main_workflow(engine))
-
- #For each thread in the list...
- for each in threads:
- #join them back together so that we wait for all threads to complete before moving on
- each.join()
-
-def delete_database(engine, server, jobs, source_obj, container_obj, obj_type=None):
- """
- This function
- FYI - Snapshot is also called sync
- """
- #Sanity check to make sure our source object has a reference
- if source_obj.reference != None :
- #If we specified the --object_type flag, ensure this source is a match. Skip, if not.
- if obj_type != None and ((obj_type.lower() == "vdb" and source_obj.virtual != True ) or (obj_type.lower() == "dsource" and source_obj.virtual != False )):
- print_warning(engine["hostname"] + ": " + container_obj.name + " is not a " + obj_type.lower() + ". Skipping sync")
- #Ensure this source is not a staging database. We can't act upon those.
- elif source_obj.staging == True:
- print_warning(engine["hostname"] + ": " + container_obj.name + " is a staging database. Skipping.")
- #Ensure the source is enabled. We can't snapshot disabled databases.
- else:
- print_info(engine["hostname"] + ": Deleting " + container_obj.name )
- print_debug(engine["hostname"] + ": Type: " + source_obj.type )
- print_debug(engine["hostname"] + ": " +source_obj.type)
- #Delete it
- database.delete(server, container_obj.reference)
- #Add the job into the jobs dictionary so we can track its progress
- jobs[container_obj] = server.last_job
- #return the job object to the calling statement so that we can tell if a job was created or not (will return None, if no job)
- return server.last_job
-
-def time_elapsed():
- """
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
- """
- elapsed_minutes = round((time() - time_start)/60, +1)
- return elapsed_minutes
-
-def update_jobs_dictionary(engine, server, jobs):
- """
- This function checks each job in the dictionary and updates its status or removes it if the job is complete.
- Return the number of jobs still running.
- """
- #Establish the running jobs counter, as we are about to update the count from the jobs report.
- i = 0
- #get all the jobs, then inspect them
- for j in jobs.keys():
- job_obj = job.get(server, jobs[j])
- print_debug(engine["hostname"] + ": " + str(job_obj))
- print_info(engine["hostname"] + ": " + j.name + ": " + job_obj.job_state)
-
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- #If the job is in a non-running state, remove it from the running jobs list.
- del jobs[j]
- else:
- #If the job is in a running state, increment the running job count.
- i += 1
- return i
-
-def main(argv):
- #We want to be able to call on these variables anywhere in the script.
- global single_thread
- global usebackup
- global time_start
- global host_name
- global database_name
- global config_file_path
- global dxtools_objects
-
-
-
try:
- #Declare globals that will be used throughout the script.
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- time_start = time()
- engine = None
- single_thread = False
- usebackup = arguments['--usebackup']
- database_name = arguments['--name']
- host_name = arguments['--host']
- config_file_path = arguments['--config']
- #Parse the dxtools.conf and put it into a dictionary
- dxtools_objects = get_config(config_file_path)
-
- #This is the function that will handle processing main_workflow for all the servers.
- run_job(engine)
-
- elapsed_minutes = time_elapsed()
- print_info("script took " + str(elapsed_minutes) + " minutes to get this far.")
-
+ with dlpx_obj.job_mode(single_thread):
+ delete_vdb(dlpx_obj, ARGUMENTS["--vdb"], ARGUMENTS["--force"])
+ # locking threads
+ run_job.track_running_jobs(engine, dlpx_obj, 5)
+ except (
+ dlpx_exceptions.DlpxException,
+ dlpx_exceptions.DlpxObjectNotFound,
+ exceptions.RequestError,
+ exceptions.JobError,
+ exceptions.HttpError,
+ ) as err:
+ dx_logging.print_exception(
+ f'Error in dx_delete_vdb on Delpihx Engine: * {engine["ip_address"]} * : {err}'
+ )
+
+
+def main():
+ """
+ main function - creates session and runs jobs
+ """
+ time_start = time.time()
+ try:
+ dx_session_obj = get_session.GetSession()
+ dx_logging.logging_est(ARGUMENTS["--logdir"])
+ config_file_path = ARGUMENTS["--config"]
+ single_thread = ARGUMENTS["--single_thread"]
+ engine = ARGUMENTS["--engine"]
+ dx_session_obj.get_config(config_file_path)
+ # This is the function that will handle processing main_workflow for all the servers.
+ t = run_job.run_job_mt(main_workflow, dx_session_obj, engine, single_thread)
+ dx_logging.print_info(
+ f"delete operation(s) are in progress. Process will terminate once all operations are complete."
+ )
+ for each in t:
+ # join them back together so that we wait for all threads to complete
+ each.join()
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_info(
+ f"delete operation took {elapsed_minutes} minutes to complete."
+ )
+ # Here we handle what we do when the unexpected happens
+ except SystemExit as err:
+ # This is what we use to handle our sys.exit(#)
+ sys.exit(err)
+
+ except dlpx_exceptions.DlpxException as err:
+ # We use this exception handler when an error occurs in a function
+ # call.
+ dx_logging.print_exception(
+ f"ERROR: Please check the ERROR message below:\n {err.error}"
+ )
+ sys.exit(2)
- #Here we handle what we do when the unexpected happens
- except SystemExit as e:
- """
- This is what we use to handle our sys.exit(#)
- """
- sys.exit(e)
- except HttpError as e:
- """
- We use this exception handler when our connection to Delphix fails
- """
- print_error("Connection failed to the Delphix Engine")
- print_error( "Please check the ERROR message below")
- print_error(e.message)
+ except exceptions.HttpError as err:
+ # We use this exception handler when our connection to Delphix fails
+ dx_logging.print_exception(
+ f"ERROR: Connection failed to the Delphix DDP. Please check the ERROR message below:\n{err.status}"
+ )
sys.exit(2)
- except JobError as e:
- """
- We use this exception handler when a job fails in Delphix so that we have actionable data
- """
- print_error("A job failed in the Delphix Engine")
- print_error(e.job)
- elapsed_minutes = time_elapsed()
- print_info(basename(__file__) + " took " + str(elapsed_minutes) + " minutes to get this far.")
+
+ except exceptions.JobError as err:
+ # We use this exception handler when a job fails in Delphix so that we
+ # have actionable data
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_exception(
+ f"A job failed in the Delphix Engine:\n{err.job}."
+ f"{basename(__file__)} took {elapsed_minutes} minutes to complete"
+ )
sys.exit(3)
+
except KeyboardInterrupt:
- """
- We use this exception handler to gracefully handle ctrl+c exits
- """
- print_debug("You sent a CTRL+C to interrupt the process")
- elapsed_minutes = time_elapsed()
- print_info(basename(__file__) + " took " + str(elapsed_minutes) + " minutes to get this far.")
- except:
- """
- Everything else gets caught here
- """
- print_error(sys.exc_info()[0])
- print_error(traceback.format_exc())
- elapsed_minutes = time_elapsed()
- print_info(basename(__file__) + " took " + str(elapsed_minutes) + " minutes to get this far.")
- sys.exit(1)
+ # We use this exception handler to gracefully handle ctrl+c exits
+ dx_logging.print_debug("You sent a CTRL+C to interrupt the process")
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_info(
+ f"{basename(__file__)} took {elapsed_minutes} minutes to complete."
+ )
+
if __name__ == "__main__":
- #Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
- #I added this below condition to account for my --name | or AT LEAST ONE OF --group --host --object_type
- #I couldn't quite sort it out with docopt. Maybe I'm just dense today.
- #Anyway, if none of the four options are given, print the __doc__ and exit.
- if not(arguments['--name']) and not(arguments['--group']) and not(arguments['--host']) and not(arguments['--object_type']) and not(arguments['--all_dbs']):
- print(__doc__)
- sys.exit()
- #Feed our arguments to the main function, and off we go!
- print arguments
- main(arguments)
\ No newline at end of file
+ # Grab our ARGUMENTS from the doc at the top of the script
+ ARGUMENTS = docopt.docopt(__doc__, version=basename(__file__) + " " + VERSION)
+ # Feed our ARGUMENTS to the main function, and off we go!
+ main()
diff --git a/dx_environment.py b/dx_environment.py
index c7f3855..7e27a9d 100755
--- a/dx_environment.py
+++ b/dx_environment.py
@@ -1,691 +1,550 @@
-#!/usr/bin/env python
-#Corey Brune 08 2016
-#This script creates an environment
-#requirements
-#pip install docopt delphixpy
-
-#The below doc follows the POSIX compliant standards and allows us to use
-#this doc to also define our arguments for the script.
+#!/usr/bin/env python3
+# Corey Brune 08 2016
+# This script creates an environment in Delphix
+# The below doc follows the POSIX compliant standards and allows us to
+# define our ARGUMENTS for the script.
"""Create Host Environment
Usage:
- dx_environment.py (--type --env_name --host_user \
---ip [--toolkit ] [--ase --ase_user --ase_pw ] \
-|--update_ase_pw --env_name | --update_ase_user --env_name \
-| --delete | --refresh | --list)
-[--logdir ][--debug] [--config ] [--connector_name ]
-[--pw ][--engine ][--all] [--poll ]
- dx_environment.py (--update_host --old_host_address --new_host_address ) [--logdir ][--debug] [--config ]
- dx_environment.py ([--enable]|[--disable]) --env_name [--logdir ][--debug] [--config ]
- dx_environment.py -h | --help | -v | --version
-
-Create a Delphix environment. (current support for standalone environments only)
+ dx_environment.py ( [--list] | [--create] | [--enable] | [--disable] | [--delete] | [--refresh] | [--update_host])
+ [--os_type ]
+ [--host_type ]
+ [--toolkit ]
+ [--env_name ]
+ [--passwd ]
+ [--connector_host_name ]
+ [--ip ]
+ [--old_host_address ]
+ [--new_host_address ]
+ [--single_thread ]
+ [--host_user ]
+ [--logdir ]
+ [--config ]
+ [--engine ]
+ [--poll ]
+ dx_environment.py -h | --help | -v | --version
+
+Create a Delphix environment.
+- current support for standalone environments only
+- does not support password updates.
Examples:
- dx_environment.py --engine landsharkengine --type linux --env_name test1 --host_user delphix --pw delphix --ip 182.1.1.1 --toolkit /var/opt/delphix
- dx_environment.py --type linux --env_name test1 --update_ase_pw newPasswd
- dx_environment.py --type linux --env_name test1 --host_user delphix --pw delphix --ip 182.1.1.1 --toolkit /var/opt/delphix
- dx_environment.py --update_host --host_name 10.0.3.60
- dx_environment.py --type linux --env_name test1 --host_user delphix --pw delphix --ip 182.1.1.1 --toolkit /var/opt/delphix --ase --ase_user sa --ase_pw delphixpw
- dx_environment.py --type windows --env_name SOURCE --host_user delphix.local\\administrator --ip 10.0.1.50 --toolkit foo --config dxtools.conf --pw 'myTempPassword123!' --debug --connector_name 10.0.1.60
- dx_environment.py --enable --env_name SOURCE
- dx_environment.py --disable --env_name SOURCE
dx_environment.py --list
+ dx_environment.py --create --engine mymask --os_type Linux --env_name oratgt \
+ --host_user delphix --passwd xxxx --ip 10.0.1.30 --toolkit /home/delphix
+ dx_environment.py --create --engine mymask --os_type Windows --env_name wintgt \
+ --host_user delphix\dephix_trgt --passwd xxxx --ip 10.0.1.60 --connector_host_name wintgt
+ dx_environment.py --create --os_type Windows --env_name winsrc \
+ --host_user delphix\delphix_src --passwd delphix --ip 10.0.1.50 --connector_host_name wintgt
+ dx_environment.py --enable --engine mymask --env_name oratgt
+ dx_environment.py --disable --engine mymask --env_name oratgt
+ dx_environment.py --refresh --engine mymask --env_name oratgt
+ dx_environment.py --delete --engine mymask --env_name oratgt
+ dx_environment.py --update_host --engine mymask --old_host_address 10.0.1.20 --new_host_address 10.0.1.30
+
+
Options:
- --type The OS type for the environment
- --env_name The name of the Delphix environment
- --ip The IP address of the Delphix environment
- --list List all of the environments for a given engine
- --toolkit Path of the toolkit. Required for Unix/Linux
- --host_user The username on the Delphix environment
- --delete The name of the Delphix environment to delete
- --update_ase_pw The new ASE DB password
- --refresh The name of the Delphix environment to refresh. Specify "all" to refresh all environments
- --pw Password of the user
- --connector_name The name of the Delphix connector to use. Required for Windows source environments
- --update_ase_user Update the ASE DB username
- --ase Flag to enable ASE environments
- --ase_user The ASE DB username
- --ase_pw Password of the ASE DB user
- --all Run against all engines.
- --debug Enable debug logging
- --parallel Limit number of jobs to maxjob
- --engine Identifier of Delphix engine in dxtools.conf.
-
- --poll The number of seconds to wait between job polls
- [default: 10]
- --config The path to the dxtools.conf file
- [default: ./dxtools.conf]
- --logdir The path to the logfile you want to use.
- [default: ./dx_environment.log]
- -h --help Show this screen.
- -v --version Show version.
- --update_host Update the host address for an environment
- --old_host_address The current name of the host, as registered in Delphix. Required for update_host
- --new_host_address The desired name of the host, as registered in Delphix. Required for update_host
- --enable Enable the named environment
- --disable Disable the named environment
+ --os_type The OS type for the environment
+ --env_name The name of the Delphix environment
+ --toolkit Path of the toolkit. Required for Unix/Linux
+ --connector_host_name The name of the Delphix connector Host to use.
+ Required for Windows source environments
+ --ip The IP address of the Delphix environment
+ --host_user The username on the Delphix environment
+ --passwd Password of the user
+ --ase_user The ASE DB username
+ --ase_pw Password of the ASE DB user
+ --update_ase_user Update the ASE DB username
+ --update_ase_pw The new ASE DB password
+ --old_host_address The current name of the host, as registered in
+ Delphix. Required for update
+ --new_host_address The desired name of the host, as registered in
+ Delphix. Required for update
+ --engine Identifier of Delphix engine in dxtools.conf.
+ [default: default]
+ --poll The number of seconds to wait between job polls
+ [default: 10]
+ --config The path to the dxtools.conf file
+ [default: ./config/dxtools.conf]
+ --logdir The path to the logfile you want to use.
+ [default: ./logs/dx_environment.log]
+ -h --help Show this screen.
+ -v --version Show version.
+ --single_thread Run as a single thread? True or False
+ [default: False]
"""
-VERSION="v.0.3.612"
-
-from docopt import docopt
-from os.path import basename
import sys
-import traceback
-from time import sleep, time
-
-from delphixpy.v1_8_0.exceptions import HttpError
-from delphixpy.v1_8_0.exceptions import JobError
-from delphixpy.v1_8_0.exceptions import RequestError
-from delphixpy.v1_8_0.web import environment
-from delphixpy.v1_8_0.web import job
-from delphixpy.v1_8_0.web import host
-from delphixpy.v1_8_0.web.vo import UnixHostEnvironment
-from delphixpy.v1_8_0.web.vo import ASEHostEnvironmentParameters
-from delphixpy.v1_8_0.web.vo import HostEnvironmentCreateParameters
-from delphixpy.v1_8_0.web.vo import WindowsHostEnvironment
-from delphixpy.v1_8_0.web.vo import WindowsHost
-from delphixpy.v1_8_0.web.vo import UnixHost
-
-from lib.DlpxException import DlpxException
-from lib.GetSession import GetSession
-from lib.GetReferences import find_obj_by_name
-from lib.GetReferences import find_obj_name
-from lib.GetReferences import find_all_objects
-from lib.DxLogging import logging_est
-from lib.DxLogging import print_info
-from lib.DxLogging import print_debug
-from lib.DxLogging import print_exception
+import time
+from os.path import basename
+
+import docopt
+
+from delphixpy.v1_10_2 import exceptions
+from delphixpy.v1_10_2.web import environment
+from delphixpy.v1_10_2.web import host
+from delphixpy.v1_10_2.web import vo
+from lib import dlpx_exceptions
+from lib import dx_logging
+from lib import get_references
+from lib import get_session
+from lib import run_job
+from lib.run_async import run_async
+
+VERSION = "v.0.3.616"
def enable_environment(dlpx_obj, env_name):
"""
Enable the given host
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param env_name: Environment name in Delphix
+ :type env_name: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
-
- env_obj = find_obj_by_name(dlpx_obj.server_session,
- environment, env_name)
-
+ env_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, environment, env_name
+ )
try:
- environment.enable(dlpx_obj.server_session,env_obj.reference)
- print('Attempting to enable {}'.format(env_name))
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Enabling the host {} '
- 'encountered an error:\n{}'.format(env_name, e))
- sys.exit(1)
+ environment.enable(dlpx_obj.server_session, env_obj.reference)
+ except (dlpx_exceptions.DlpxException, exceptions.RequestError) as err:
+ dx_logging.print_exception(
+ f"ERROR: Enabling the host {env_name} " f"encountered an error:\n{err}"
+ )
-def disable_environment(dlpx_obj,env_name):
+def disable_environment(dlpx_obj, env_name):
"""
- Enable the given host
+ Enable a Delphix environment
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param env_name: Environment name in Delphix
+ :type env_name: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
- env_obj = find_obj_by_name(dlpx_obj.server_session,
- environment, env_name)
-
+ env_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, environment, env_name
+ )
try:
- environment.disable(dlpx_obj.server_session,env_obj.reference)
- print('Attempting to disable {}'.format(env_name))
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Disabling the host {} '
- 'encountered an error:\n{}'.format(env_name, e))
- sys.exit(1)
+ environment.disable(dlpx_obj.server_session, env_obj.reference)
+ except (dlpx_exceptions.DlpxException, exceptions.RequestError) as err:
+ dx_logging.print_exception(
+ f"ERROR: Disabling the host {env_name} " f"encountered an error:\n{err}"
+ )
def update_host_address(dlpx_obj, old_host_address, new_host_address):
"""
- Update the given host
+ Update the environment
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param old_host_address: Original IP address of environment
+ :type old_host_address: str
+ :param new_host_address: New IP address of the environment
+ :type new_host_address: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
- old_host_obj = find_obj_by_name(dlpx_obj.server_session,
- host, old_host_address)
+ old_host_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, host, old_host_address
+ )
if old_host_obj.type == "WindowsHost":
- host_obj = WindowsHost()
+ host_obj = vo.WindowsHost()
else:
- host_obj = UnixHost()
+ host_obj = vo.UnixHost()
host_obj.address = new_host_address
try:
- host.update(dlpx_obj.server_session, old_host_obj.reference, host_obj)
+ host.update(dlpx_obj.server_session, old_host_obj.reference, host_obj)
- print('Attempting to update {} to {}'.format(old_host_address, new_host_address))
-
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Updating the host {} '
- 'encountered an error:\n{}'.format(env_name, e))
- sys.exit(1)
+ except (dlpx_exceptions.DlpxException, exceptions.RequestError) as err:
+ dx_logging.print_exception(
+ f"ERROR: Updating the host {host_obj.name} " f"encountered an error:\n{err}"
+ )
def list_env(dlpx_obj):
"""
- List all environments for a given engine
+ List all environments for the engine
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
-
all_envs = environment.get_all(dlpx_obj.server_session)
+ if not all_envs:
+ dx_logging.print_info(
+ f"There are no environments on engine:{dlpx_obj.server_session.address}"
+ )
+ return
+ env_host = ""
for env in all_envs:
- env_user = find_obj_name(dlpx_obj.server_session,
- environment.user, env.primary_user)
+ env_user = get_references.find_obj_name(
+ dlpx_obj.server_session, environment.user, env.primary_user
+ )
try:
- env_host = find_obj_name(dlpx_obj.server_session, host, env.host)
+ env_host = get_references.find_obj_name(
+ dlpx_obj.server_session, host, env.host
+ )
except AttributeError:
pass
-
- if env.type == 'WindowsHostEnvironment':
- print('Environment Name: {}, Username: {}, Host: {},'
- 'Enabled: {}, '.format(env.name, env_user, env_host,
- env.enabled))
- elif env.type == 'WindowsCluster' or env.type == 'OracleCluster':
- print('Environment Name: {}, Username: {}' \
- 'Enabled: {}, '.format(env.name, env_user, env.enabled))
+ if env.type == "WindowsHostEnvironment":
+ print(
+ f"Environment Name: {env.name}, Username: {env_user}, "
+ f"Host: {env_host},Enabled: {env.enabled}"
+ )
+ elif env.type == "WindowsCluster" or env.type == "OracleCluster":
+ print(
+ f"Environment Name: {env.name}, Username: {env_user}"
+ f"Enabled: {env.enabled}, "
+ )
else:
- print 'Environment Name: {}, Username: {}, Host: {}, Enabled: {},'\
- ' ASE Environment Params: {}'.format(
- env.name, env_user, env_host, env.enabled,
- env.ase_host_environment_parameters if
- isinstance(env.ase_host_environment_parameters,
- ASEHostEnvironmentParameters) else 'Undefined')
+ print(
+ f"Environment Name: {env.name}, Username: {env_user}, "
+ f"Host: {env_host}, Enabled: {env.enabled}, "
+ f"ASE Environment Params: "
+ f'{env.ase_host_environment_parameters if isinstance(env.ase_host_environment_parameters,vo.ASEHostEnvironmentParameters) else "Undefined"}'
+ )
def delete_env(dlpx_obj, env_name):
"""
Deletes an environment
-
- engine: Dictionary of engines
- env_name: Name of the environment to delete
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param env_name: Name of the environment to delete
+ :type env_name: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
-
- env_obj = find_obj_by_name(dlpx_obj.server_session, environment,
- env_name)
-
+ env_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, environment, env_name
+ )
if env_obj:
environment.delete(dlpx_obj.server_session, env_obj.reference)
- dlpx_obj.jobs[engine_name] = \
- dlpx_obj.server_session.last_job
-
+ dlpx_obj.jobs[
+ dlpx_obj.server_session.address
+ ] = dlpx_obj.server_session.last_job
elif env_obj is None:
- print('Environment was not found in the Engine: {}'.format(env_name))
- sys.exit(1)
+ dlpx_exceptions.DlpxObjectNotFound(f"Environment was not found: {env_name}")
def refresh_env(dlpx_obj, env_name):
"""
Refresh the environment
-
- engine: Dictionary of engines
- env_name: Name of the environment to refresh
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :parm env_name: Name of the environment to refresh
+ :type env_name: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
-
if env_name == "all":
- env_list = find_all_objects(dlpx_obj.server_session, environment)
- for env_obj in env_list:
- try:
- environment.refresh(dlpx_obj.server_session, env_obj.reference)
- dlpx_obj.jobs[engine_name] = \
- dlpx_obj.server_session.last_job
-
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Refreshing the environment {} '
- 'encountered an error:\n{}'.format(env_name, e))
- sys.exit(1)
+ env_list = get_references.find_all_objects(dlpx_obj.server_session, environment)
+ for env_obj in env_list:
+ try:
+ environment.refresh(dlpx_obj.server_session, env_obj.reference)
+ dlpx_obj.jobs[
+ dlpx_obj.server_session.address
+ ] = dlpx_obj.server_session.last_job
+ except (dlpx_exceptions.DlpxException, exceptions.RequestError) as err:
+ dlpx_exceptions.DlpxException(
+ f"Encountered an error while refreshing {env_name}: {err}"
+ )
else:
-
- try:
- env_obj = find_obj_by_name(dlpx_obj.server_session, environment,
- env_name)
-
- environment.refresh(dlpx_obj.server_session, env_obj.reference)
- dlpx_obj.jobs[engine_name] = \
- dlpx_obj.server_session.last_job
-
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Refreshing the environment {} '
- 'encountered an error:\n{}'.format(env_name, e))
- sys.exit(1)
-
-
-def update_ase_username(dlpx_obj):
- """
- Update the ASE database user password
- """
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
-
- env_obj = UnixHostEnvironment()
- env_obj.ase_host_environment_parameters = ASEHostEnvironmentParameters()
- env_obj.ase_host_environment_parameters.db_user = \
- arguments['--update_ase_user']
-
- try:
- environment.update(dlpx_obj.server_session, find_obj_by_name(
- dlpx_obj.server_session, environment, arguments['--env_name'],
- env_obj).reference, env_obj)
-
- except (HttpError, RequestError) as e:
- print_exception('\nERROR: Updating the ASE DB password '
- 'failed:\n{}\n'.format(e))
-
-
-def update_ase_pw(dlpx_obj):
- """
- Update the ASE database user password
- """
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
- env_obj = UnixHostEnvironment()
- env_obj.ase_host_environment_parameters = ASEHostEnvironmentParameters()
- env_obj.ase_host_environment_parameters.credentials = {'type':
- 'PasswordCredential',
- 'password':
- arguments['--update_ase_pw']}
-
- try:
- environment.update(dlpx_obj.server_session, find_obj_by_name(
- dlpx_obj.server_session, environment, arguments['--env_name'],
- env_obj).reference, env_obj)
-
- except (HttpError, RequestError) as e:
- print_exception('\nERROR: Updating the ASE DB password '
- 'failed:\n{}\n'.format(e))
-
-
-def create_linux_env(dlpx_obj, env_name, host_user, ip_addr, toolkit_path,
- pw=None):
-
+ try:
+ env_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, environment, env_name
+ )
+ environment.refresh(dlpx_obj.server_session, env_obj.reference)
+ dlpx_obj.jobs[
+ dlpx_obj.server_session.address
+ ] = dlpx_obj.server_session.last_job
+ except (dlpx_exceptions.DlpxException, exceptions.RequestError) as err:
+ raise dlpx_exceptions.DlpxException(
+ f"Refreshing {env_name} encountered an error:\n{err}"
+ )
+
+
+def create_linux_env(
+ dlpx_obj,
+ env_name,
+ host_user,
+ ip_addr,
+ toolkit_path,
+ passwd=None,
+ ase_user=None,
+ ase_pw=None,
+):
"""
Create a Linux environment.
-
- env_name: The name of the environment
- host_user: The server account used to authenticate
- ip_addr: DNS name or IP address of the environment
- toolkit_path: Path to the toolkit. Note: This directory must be
- writable by the host_user
- pw: Password of the user. Default: None (use SSH keys instead)
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param env_name: The name of the environment
+ :type env_name: str
+ :param host_user: The server account used to authenticate
+ :type host_user: str
+ :param ip_addr: DNS name or IP address of the environment
+ :type ip_addr: str
+ :param toolkit_path: Path to the toolkit. Note: This directory must be
+ writable by the host_user
+ :type toolkit_path: str
+ :param passwd: Password of the user. Default: None (use SSH keys instead)
+ :type passwd: str or bool
+ :param ase_user: username for ASE DB
+ :type ase_user: str
+ :param ase_pw: password for the ASE DB user
+ :type ase_pw: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
- env_params_obj = HostEnvironmentCreateParameters()
-
- if pw is None:
- print_debug('Creating the environment with SSH Keys')
- env_params_obj.primary_user = {'type': 'EnvironmentUser',
- 'name': host_user,
- 'credential': {
- 'type': 'SystemKeyCredential'}}
- else:
- print_debug('Creating the environment with a password')
- env_params_obj.primary_user = {'type': 'EnvironmentUser',
- 'name': host_user,
- 'credential': {
- 'type': 'PasswordCredential',
- 'password': pw }}
-
- env_params_obj.host_parameters = {'type': 'UnixHostCreateParameters',
- 'host': { 'address': ip_addr,
- 'type': 'UnixHost',
- 'name': env_name,
- 'toolkitPath': toolkit_path}}
-
- env_params_obj.host_environment = UnixHostEnvironment()
+ env_params_obj = vo.HostEnvironmentCreateParameters()
+ env_params_obj.host_environment = vo.UnixHostEnvironment()
+ env_params_obj.host_parameters = vo.UnixHostCreateParameters()
+ env_params_obj.host_parameters.host = vo.UnixHost()
env_params_obj.host_environment.name = env_name
-
- if arguments['--ase']:
- env_params_obj.host_environment.ase_host_environment_parameters = \
- ASEHostEnvironmentParameters()
-
- try:
- env_params_obj.host_environment.ase_host_environment_parameters.db_user = \
- arguments['--ase_user']
- env_params_obj.host_environment.ase_host_environment_parameters.credentials = {
- 'type': 'PasswordCredential',
- 'password': arguments['--ase_pw']}
- except KeyError:
- print_exception('The --ase_user and --ase_pw arguments are'
- ' required with the --ase flag.\n')
-
+ env_params_obj.host_parameters.host.address = ip_addr
+ env_params_obj.host_parameters.name = env_name
+ env_params_obj.host_parameters.host.toolkit_path = toolkit_path
+ # setting user credentials
+ env_params_obj.primary_user = vo.EnvironmentUser()
+ env_params_obj.primary_user.name = host_user
+ if passwd is None:
+ env_params_obj.primary_user.credential = vo.SystemKeyCredential()
+ else:
+ env_params_obj.primary_user.credential = vo.PasswordCredential()
+ env_params_obj.primary_user.credential.password = passwd
+ if ase_user:
+ env_params_obj.host_environment.ase_host_environment_parameters = (
+ vo.ASEHostEnvironmentParameters()
+ )
+ env_params_obj.host_environment.ase_host_environment_parameters.db_user = (
+ ase_user
+ )
+ env_params_obj.host_environment.ase_host_environment_parameters.credentials = (
+ vo.PasswordCredential()
+ )
+ env_params_obj.host_environment.ase_host_environment_parameters.credentials.password = (
+ ase_pw
+ )
try:
- environment.create(dlpx_obj.server_session,
- env_params_obj)
- dlpx_obj.jobs[engine_name] = \
- dlpx_obj.server_session.last_job
-
- except (DlpxException, RequestError, HttpError) as e:
- print('\nERROR: Encountered an exception while creating the '
- 'environment:\n{}'.format(e))
- except JobError as e:
- print_exception('JobError while creating environment {}:\n{}'.format(
- e, e.message))
-
-
-def create_windows_env(dlpx_obj, env_name, host_user, ip_addr,
- pw=None, connector_name=None):
-
+ environment.create(dlpx_obj.server_session, env_params_obj)
+ dlpx_obj.jobs[
+ dlpx_obj.server_session.address
+ ] = dlpx_obj.server_session.last_job
+ except (
+ dlpx_exceptions.DlpxException,
+ exceptions.RequestError,
+ exceptions.HttpError,
+ ) as err:
+ raise dlpx_exceptions.DlpxException(
+ f"ERROR: Encountered an exception while creating the "
+ f"environment:\n{err}"
+ )
+ except exceptions.JobError as err:
+ raise dlpx_exceptions.DlpxException(
+ f"JobError while creating environment:\n{err}"
+ ) from err
+
+
+def create_windows_env(
+ dlpx_obj, env_name, host_user, ip_addr, passwd=None, connector_host_name=None
+):
"""
Create a Windows environment.
-
- env_name: The name of the environment
- host_user: The server account used to authenticate
- ip_addr: DNS name or IP address of the environment
- toolkit_path: Path to the toolkit. Note: This directory must be
- writable by the host_user
- pw: Password of the user. Default: None (use SSH keys instead)
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param env_name: The name of the environment
+ :type env_name: str
+ :param host_user: The server account used to authenticate
+ :type host_user: str
+ :param ip_addr: DNS name or IP address of the environment
+ :type ip_addr: str
+ :param passwd: Password of the user. Default: None (use SSH keys instead)
+ :type passwd: str
+ :param connector_name: Name of the Delphix connector
+ :type connector_name: str
"""
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
-
- env_params_obj = HostEnvironmentCreateParameters()
-
- print_debug('Creating the environment with a password')
-
- env_params_obj.primary_user = {'type': 'EnvironmentUser',
- 'name': host_user,
- 'credential': {
- 'type': 'PasswordCredential',
- 'password': pw }}
-
- env_params_obj.host_parameters = {'type': 'WindowsHostCreateParameters',
- 'host': { 'address': ip_addr,
- 'type': 'WindowsHost',
- 'name': env_name,
- 'connectorPort': 9100}}
-
- env_params_obj.host_environment = WindowsHostEnvironment()
+ env_params_obj = vo.HostEnvironmentCreateParameters()
+ env_params_obj.primary_user = vo.EnvironmentUser()
+ env_params_obj.primary_user.name = host_user
+ env_params_obj.primary_user.credential = vo.PasswordCredential()
+ env_params_obj.primary_user.credential.password = passwd
+ env_params_obj.host_parameters = vo.WindowsHostCreateParameters()
+ env_params_obj.host_parameters.host = vo.WindowsHost()
+ env_params_obj.host_parameters.host.connector_port = 9100
+ env_params_obj.host_parameters.host.address = ip_addr
+ env_params_obj.host_environment = vo.WindowsHostEnvironment()
env_params_obj.host_environment.name = env_name
-
- if connector_name:
- env_obj = find_obj_by_name(dlpx_obj.server_session, environment,
- connector_name)
-
- if env_obj:
+ env_obj = None
+ if connector_host_name:
+ env_obj = get_references.find_obj_by_name(
+ dlpx_obj.server_session, environment, connector_host_name
+ )
+ if env_obj:
env_params_obj.host_environment.proxy = env_obj.host
- elif env_obj is None:
- print('Host was not found in the Engine: {}'.format(arguments[--connector_name]))
- sys.exit(1)
-
+ elif connector_host_name is not None and env_obj is None:
+ raise dlpx_exceptions.DlpxObjectNotFound(
+ f"Host was not found in the Engine: {connector_host_name}"
+ )
try:
- environment.create(dlpx_obj.server_session,
- env_params_obj)
- dlpx_obj.jobs[engine_name] = \
- dlpx_obj.server_session.last_job
-
- except (DlpxException, RequestError, HttpError) as e:
- print('\nERROR: Encountered an exception while creating the '
- 'environment:\n{}'.format(e))
-
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
-
- E.g.:
- @run_async
- def task1():
- do_something
-
- @run_async
- def task2():
- do_something_too
-
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- from threading import Thread
- from functools import wraps
-
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
-
- return async_func
+ environment.create(dlpx_obj.server_session, env_params_obj)
+ dlpx_obj.jobs[dlpx_obj.server_session.address].append(
+ dlpx_obj.server_session.last_job
+ )
+ except (
+ dlpx_exceptions.DlpxException,
+ exceptions.RequestError,
+ exceptions.HttpError,
+ ) as err:
+ raise dlpx_exceptions.DlpxException(
+ f"ERROR: Encountered an exception while creating the "
+ f"environment:\n{err}"
+ )
@run_async
-def main_workflow(engine, dlpx_obj):
+def main_workflow(engine, dlpx_obj, single_thread):
"""
This function is where we create our main workflow.
Use the @run_async decorator to run this function asynchronously.
The @run_async decorator allows us to run against multiple Delphix Engine
simultaneously
-
:param engine: Dictionary of engines
:type engine: dictionary
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param single_thread: True - run single threaded, False - run multi-thread
+ :type single_thread: bool
"""
-
try:
- # Setup the connection to the Delphix Engine
- dlpx_obj.serversess(engine['ip_address'], engine['username'],
- engine['password'])
-
- except DlpxException as e:
- print_exception('ERROR: Engine {} encountered an error while'
- '{}:\n{}\n'.format(engine['hostname'],
- arguments['--target'], e))
- sys.exit(1)
-
- thingstodo = ["thingtodo"]
+ # Setup the connection to the Delphix DDP
+ dlpx_obj.dlpx_session(
+ engine["ip_address"], engine["username"], engine["password"]
+ )
+ except dlpx_exceptions.DlpxException as err:
+ dx_logging.print_exception(
+ f"ERROR: dx_environment encountered an error authenticating to "
+ f' {engine["ip_address"]} :\n{err}'
+ )
try:
with dlpx_obj.job_mode(single_thread):
- while len(dlpx_obj.jobs) > 0 or len(thingstodo) > 0:
- if len(thingstodo)> 0:
- if arguments['--type'] == 'linux' or arguments['--type'] == 'windows':
- env_name = arguments['--env_name']
- host_user = arguments['--host_user']
- pw = arguments['--pw']
- ip_addr = arguments['--ip']
- host_name = arguments['--connector_name']
- if arguments['--type'] == 'linux':
- toolkit_path = arguments['--toolkit']
- create_linux_env(dlpx_obj, env_name, host_user,
- ip_addr, toolkit_path, pw)
- else:
- create_windows_env(dlpx_obj, env_name, host_user,
- ip_addr, pw, host_name,)
-
- elif arguments['--delete']:
- delete_env(dlpx_obj, arguments['--delete'])
-
- elif arguments['--refresh']:
- refresh_env(dlpx_obj, arguments['--refresh'])
-
- elif arguments['--update_ase_pw']:
- update_ase_pw(dlpx_obj)
-
- elif arguments['--update_ase_user']:
- update_ase_username(dlpx_obj)
- elif arguments['--list']:
- list_env(dlpx_obj)
- elif arguments['--update_host']:
- update_host_address(dlpx_obj, arguments['--old_host_address'], arguments['--new_host_address'])
- elif arguments['--enable']:
- enable_environment(dlpx_obj, arguments['--env_name'])
- elif arguments['--disable']:
- disable_environment(dlpx_obj, arguments['--env_name'])
-
- thingstodo.pop()
- # get all the jobs, then inspect them
- i = 0
- for j in dlpx_obj.jobs.keys():
- job_obj = job.get(dlpx_obj.server_session, dlpx_obj.jobs[j])
- print_debug(job_obj)
- print_info('{} Environment: {}'.format(
- engine['hostname'], job_obj.job_state))
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- # If the job is in a non-running state, remove it
- # from the running jobs list.
- del dlpx_obj.jobs[j]
- elif job_obj.job_state in 'RUNNING':
- # If the job is in a running state, increment the
- # running job count.
- i += 1
- print_info('{}: {:d} jobs running.'.format(
- engine['hostname'], i))
- # If we have running jobs, pause before repeating the
- # checks.
- if len(dlpx_obj.jobs) > 0:
- sleep(float(arguments['--poll']))
- except (DlpxException, RequestError, JobError, HttpError) as e:
- print_exception('Error while creating the environment {}\n{}'.format(
- arguments['--env_name'], e))
- sys.exit(1)
-
-def run_job(dlpx_obj, config_file_path):
- """
- This function runs the main_workflow aynchronously against all the
- servers specified
+ if ARGUMENTS["--list"]:
+ list_env(dlpx_obj)
+ elif ARGUMENTS["--create"]:
+ env_name = ARGUMENTS["--env_name"]
+ host_user = ARGUMENTS["--host_user"]
+ passwd = ARGUMENTS["--passwd"]
+ ip_addr = ARGUMENTS["--ip"]
+ type = ARGUMENTS["--os_type"]
+ toolkit_path = ARGUMENTS["--toolkit"]
+ if type is None:
+ raise dlpx_exceptions.DlpxException(
+ "--os_type parameter is required for environment creation"
+ )
+
+ type = type.lower()
+ if type == "windows":
+ connector_host_name = ARGUMENTS["--connector_host_name"]
+ create_windows_env(
+ dlpx_obj,
+ env_name,
+ host_user,
+ ip_addr,
+ passwd,
+ connector_host_name,
+ )
+ elif type == "linux":
+ if toolkit_path is None:
+ raise dlpx_exceptions.DlpxException(
+ "--toolkit parameter is required for environment "
+ "creation"
+ )
+ create_linux_env(
+ dlpx_obj, env_name, host_user, ip_addr, toolkit_path, passwd
+ )
+ elif ARGUMENTS["--enable"]:
+ enable_environment(dlpx_obj, ARGUMENTS["--env_name"])
+ elif ARGUMENTS["--disable"]:
+ disable_environment(dlpx_obj, ARGUMENTS["--env_name"])
+ elif ARGUMENTS["--delete"]:
+ delete_env(dlpx_obj, ARGUMENTS["--env_name"])
+ elif ARGUMENTS["--refresh"]:
+ refresh_env(dlpx_obj, ARGUMENTS["--env_name"])
+ elif ARGUMENTS["--update_host"]:
+ update_host_address(
+ dlpx_obj,
+ ARGUMENTS["--old_host_address"],
+ ARGUMENTS["--new_host_address"],
+ )
+ run_job.track_running_jobs(engine, dlpx_obj, 5)
+ except (
+ dlpx_exceptions.DlpxException,
+ exceptions.RequestError,
+ exceptions.JobError,
+ exceptions.HttpError,
+ ) as err:
+ dx_logging.print_exception(
+ f"Error in dx_environment for engine:"
+ f'{engine["ip_address"]}: Error Message: {err}'
+ )
- dlpx_obj: Virtualization Engine session object
- config_file_path: filename of the configuration file for virtualization
- engines
- """
-
- #Create an empty list to store threads we create.
- threads = []
- engine = None
-
- #If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info("Executing against all Delphix Engines in the dxtools.conf")
- try:
- #For each server in the dxtools.conf...
- for delphix_engine in dlpx_obj.dlpx_engines:
- engine = dlpx_obj.dlpx_engines[delphix_engine]
- #Create a new thread and add it to the list.
- threads.append(main_workflow(engine, dlpx_obj))
-
- except DlpxException as e:
- print 'Error encountered in run_job():\n{}'.format(e)
- sys.exit(1)
-
- elif arguments['--all'] is False:
- #Else if the --engine argument was given, test to see if the engine
- # exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dlpx_obj.dlpx_engines[arguments['--engine']]
- print_info('Executing against Delphix Engine: {}\n'.format(
- arguments['--engine']))
- except (DlpxException, RequestError, KeyError) as e:
- print_exception('\nERROR: Delphix Engine {} cannot be '
- 'found in {}. Please check your value '
- 'and try again. Exiting.\n'.format(
- arguments['--engine'], config_file_path))
- else:
- #Else search for a default engine in the dxtools.conf
- for delphix_engine in dlpx_obj.dlpx_engines:
- if dlpx_obj.dlpx_engines[delphix_engine]['default'] == \
- 'true':
- engine = dlpx_obj.dlpx_engines[delphix_engine]
- print_info('Executing against the default Delphix Engine '
- 'in the dxtools.conf: {}'.format(
- dlpx_obj.dlpx_engines[delphix_engine]['hostname']))
- break
- if engine is None:
- raise DlpxException("\nERROR: No default engine found. Exiting")
-
- #run the job against the engine
- threads.append(main_workflow(engine, dlpx_obj))
- #For each thread in the list...
- for each in threads:
- #join them back together so that we wait for all threads to complete
- # before moving on
- each.join()
-
-
-def time_elapsed(time_start):
+def main():
"""
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
-
- :param time_start: start time of the script.
- :type time_start: float
+ main function - creates session and runs jobs
"""
- return round((time() - time_start)/60, +1)
-
-
-def main():
- # We want to be able to call on these variables anywhere in the script.
- global single_thread
- global debug
-
- time_start = time()
- single_thread = False
-
+ time_start = time.time()
try:
- dx_session_obj = GetSession()
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- config_file_path = arguments['--config']
- # Parse the dxtools.conf and put it into a dictionary
+ dx_session_obj = get_session.GetSession()
+ dx_logging.logging_est(ARGUMENTS["--logdir"])
+ config_file_path = ARGUMENTS["--config"]
+ single_thread = ARGUMENTS["--single_thread"]
+ engine = ARGUMENTS["--engine"]
dx_session_obj.get_config(config_file_path)
-
- # This is the function that will handle processing main_workflow for
- # all the servers.
- run_job(dx_session_obj, config_file_path)
-
- elapsed_minutes = time_elapsed(time_start)
- print_info('script took {:.2f} minutes to get this far.'.format(
- elapsed_minutes))
-
+ for each in run_job.run_job_mt(
+ main_workflow, dx_session_obj, engine, single_thread
+ ):
+ each.join()
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_info(
+ f"de_environment took {elapsed_minutes} minutes to " f"complete."
+ )
# Here we handle what we do when the unexpected happens
- except SystemExit as e:
+ except SystemExit as err:
# This is what we use to handle our sys.exit(#)
- sys.exit(e)
-
- except DlpxException as e:
- # We use this exception handler when an error occurs in a function call.
- print_exception('ERROR: Please check the ERROR message below:\n'
- '{}'.format(e.message))
+ sys.exit(err)
+
+ except dlpx_exceptions.DlpxException as err:
+ # We use this exception handler when an error occurs in a function
+ # call.
+ dx_logging.print_exception(
+ f"ERROR: Please check the ERROR message " f"below:\n {err.error}"
+ )
sys.exit(2)
- except HttpError as e:
+ except exceptions.HttpError as err:
# We use this exception handler when our connection to Delphix fails
- print_exception('ERROR: Connection failed to the Delphix Engine. Please'
- 'check the ERROR message below:\n{}'.format(e.message))
+ dx_logging.print_exception(
+ f"ERROR: Connection failed to the Delphix DDP. Please check "
+ f"the ERROR message below:\n{err.status}"
+ )
sys.exit(2)
- except JobError as e:
+ except exceptions.JobError as err:
# We use this exception handler when a job fails in Delphix so that we
# have actionable data
- print_exception('A job failed in the Delphix Engine:\n{}'.format(e.job))
- elapsed_minutes = time_elapsed(time_start)
- print_exception('{} took {:.2f} minutes to get this far'.format(
- basename(__file__), elapsed_minutes))
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_exception(
+ f"A job failed in the Delphix Engine:\n{err.job}."
+ f"{basename(__file__)} took {elapsed_minutes} minutes to "
+ f"complete"
+ )
sys.exit(3)
except KeyboardInterrupt:
# We use this exception handler to gracefully handle ctrl+c exits
- print_debug('You sent a CTRL+C to interrupt the process')
- elapsed_minutes = time_elapsed(time_start)
- print_info('{} took {:.2f} minutes to get this far'.format(
- basename(__file__), elapsed_minutes))
- except:
- # Everything else gets caught here
- print_exception('{}\n{}'.format(sys.exc_info()[0],
- traceback.format_exc()))
- elapsed_minutes = time_elapsed(time_start)
- print_info("{} took {:.2f} minutes to get this far".format(
- basename(__file__), elapsed_minutes))
- sys.exit(1)
-
+ dx_logging.print_debug("You sent a CTRL+C to interrupt the process")
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_info(
+ f"{basename(__file__)} took {elapsed_minutes} " f"minutes to complete."
+ )
if __name__ == "__main__":
- #Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
- #Feed our arguments to the main function, and off we go!
+ # Grab our ARGUMENTS from the doc at the top of the script
+ ARGUMENTS = docopt.docopt(__doc__, version=basename(__file__) + " " + VERSION)
+ # Feed our ARGUMENTS to the main function, and off we go!
main()
diff --git a/dx_groups.py b/dx_groups.py
deleted file mode 100755
index 7bb79c6..0000000
--- a/dx_groups.py
+++ /dev/null
@@ -1,363 +0,0 @@
-#!/usr/bin/env python
-# Adam Bowen - Aug 2017
-#Description:
-# This script will allow you to easily manage groups in Delphix
-#
-#Requirements
-#pip install docopt delphixpy
-
-#The below doc follows the POSIX compliant standards and allows us to use
-#this doc to also define our arguments for the script.
-"""Description
-Usage:
- dx_groups.py (--group_name [--add | --delete])
- [--engine | --all]
- [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_groups.py (--list)
- [--engine | --all]
- [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_groups.py -h | --help | -v | --version
-Description
-
-Examples:
- dx_groups.py --debug --config delphixpy-examples/dxtools_1.conf --group_name Test --add
- dx_groups.py --config delphixpy-examples/dxtools_1.conf --group_name Test --delete
- dx_groups.py --list
-
-Options:
- --group_name The name of the group
- --add Add the identified group
- --delete Delete the identified group
- --engine Alt Identifier of Delphix engine in dxtools.conf.
- --all Run against all engines.
- --debug Enable debug logging
- --parallel Limit number of jobs to maxjob
- --poll The number of seconds to wait between job polls
- [default: 10]
- --config The path to the dxtools.conf file
- [default: ./dxtools.conf]
- --logdir The path to the logfile you want to use.
- [default: ./dx_skel.log]
- -h --help Show this screen.
- -v --version Show version.
-"""
-
-VERSION = 'v.0.0.002'
-
-import sys
-from os.path import basename
-from time import sleep, time
-from docopt import docopt
-
-from delphixpy.v1_8_0.exceptions import HttpError
-from delphixpy.v1_8_0.exceptions import JobError
-from delphixpy.v1_8_0.exceptions import RequestError
-from delphixpy.v1_8_0.web import job
-from delphixpy.v1_8_0.web import group
-from delphixpy.v1_8_0.web.vo import Group
-
-from lib.DlpxException import DlpxException
-from lib.DxLogging import logging_est
-from lib.DxLogging import print_debug
-from lib.DxLogging import print_info
-from lib.DxLogging import print_exception
-from lib.GetReferences import find_obj_by_name
-from lib.GetReferences import find_all_objects
-from lib.GetSession import GetSession
-
-def add_group(group_name):
- """
- This function adds the group
- """
- group_obj = Group()
- group_obj.name = group_name
-
-
- try:
- group.create(dx_session_obj.server_session,group_obj)
- print('Attempting to create {}'.format(group_name))
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Creating the group {} '
- 'encountered an error:\n{}'.format(group_name, e))
- sys.exit(1)
-
-def delete_group(group_name):
- """
- This function adds the group
- """
- group_obj = find_obj_by_name(dx_session_obj.server_session,
- group, group_name)
-
-
- try:
- group.delete(dx_session_obj.server_session,group_obj.reference)
- print('Attempting to delete {}'.format(group_name))
- except (DlpxException, RequestError) as e:
- print_exception('\nERROR: Deleting the group {} '
- 'encountered an error:\n{}'.format(group_name, e))
- sys.exit(1)
-
-def list_groups():
- """
- This function lists all groups
- """
- group_list = find_all_objects(dx_session_obj.server_session, group)
-
- for group_obj in group_list:
- print('Group: {}'.format(group_obj.name))
-
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
- E.g.:
- @run_async
- def task1():
- do_something
- @run_async
- def task2():
- do_something_too
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- from threading import Thread
- from functools import wraps
-
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
-
- return async_func
-
-
-@run_async
-def main_workflow(engine):
- """
- This function actually runs the jobs.
- Use the @run_async decorator to run this function asynchronously.
- This allows us to run against multiple Delphix Engine simultaneously
-
- engine: Dictionary of engines
- """
- try:
- #Setup the connection to the Delphix Engine
- dx_session_obj.serversess(engine['ip_address'], engine['username'],
- engine['password'])
-
- except DlpxException as e:
- print_exception('\nERROR: Engine {} encountered an error while'
- '{}:\n{}\n'.format(engine['hostname'],
- arguments['--target'], e))
- sys.exit(1)
-
- thingstodo = ["thingtodo"]
- try:
- with dx_session_obj.job_mode(single_thread):
- while (len(dx_session_obj.jobs) > 0 or len(thingstodo)> 0):
- if len(thingstodo) > 0:
- if arguments['--add'] :
- add_group(arguments['--group_name'])
- elif arguments['--delete']:
- delete_group(arguments['--group_name'])
- elif arguments['--list']:
- list_groups()
- thingstodo.pop()
- # get all the jobs, then inspect them
- i = 0
- for j in dx_session_obj.jobs.keys():
- job_obj = job.get(dx_session_obj.server_session,
- dx_session_obj.jobs[j])
- print_debug(job_obj)
- print_info('{}: Group: {}'.format(
- engine['hostname'], job_obj.job_state))
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- # If the job is in a non-running state, remove it
- # from the
- # running jobs list.
- del dx_session_obj.jobs[j]
- elif job_obj.job_state in 'RUNNING':
- # If the job is in a running state, increment the
- # running job count.
- i += 1
- print_info('{}: {:d} jobs running.'.format(
- engine['hostname'], i))
- # If we have running jobs, pause before repeating the
- # checks.
- if len(dx_session_obj.jobs) > 0:
- sleep(float(arguments['--poll']))
-
- except (HttpError, RequestError, JobError, DlpxException) as e:
- print_exception('ERROR: Could not complete group '
- 'operation: {}'.format(e))
-
-
-def run_job():
- """
- This function runs the main_workflow aynchronously against all the servers
- specified
- """
- #Create an empty list to store threads we create.
- threads = []
- engine = None
-
- #If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info("Executing against all Delphix Engines in the dxtools.conf")
-
- try:
- #For each server in the dxtools.conf...
- for delphix_engine in dx_session_obj.dlpx_engines:
- engine = dx_session_obj[delphix_engine]
- #Create a new thread and add it to the list.
- threads.append(main_workflow(engine))
-
- except DlpxException as e:
- print 'Error encountered in run_job():\n{}'.format(e)
- sys.exit(1)
-
- elif arguments['--all'] is False:
- #Else if the --engine argument was given, test to see if the engine
- # exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dx_session_obj.dlpx_engines[arguments['--engine']]
- print_info('Executing against Delphix Engine: {}\n'.format(
- (arguments['--engine'])))
-
- except (DlpxException, RequestError, KeyError) as e:
- raise DlpxException('\nERROR: Delphix Engine {} cannot be '
- 'found in {}. Please check your value '
- 'and try again. Exiting.\n'.format(
- arguments['--engine'], config_file_path))
-
- else:
- #Else search for a default engine in the dxtools.conf
- for delphix_engine in dx_session_obj.dlpx_engines:
- if dx_session_obj.dlpx_engines[delphix_engine]['default'] == \
- 'true':
-
- engine = dx_session_obj.dlpx_engines[delphix_engine]
- print_info('Executing against the default Delphix Engine '
- 'in the dxtools.conf: {}'.format(
- dx_session_obj.dlpx_engines[delphix_engine]['hostname']))
-
- break
-
- if engine == None:
- raise DlpxException("\nERROR: No default engine found. Exiting")
-
- #run the job against the engine
- threads.append(main_workflow(engine))
-
- #For each thread in the list...
- for each in threads:
- #join them back together so that we wait for all threads to complete
- # before moving on
- each.join()
-
-
-def time_elapsed():
- """
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
- """
- #elapsed_minutes = round((time() - time_start)/60, +1)
- #return elapsed_minutes
- return round((time() - time_start)/60, +1)
-
-
-def main(arguments):
- #We want to be able to call on these variables anywhere in the script.
- global single_thread
- global usebackup
- global time_start
- global config_file_path
- global dx_session_obj
- global debug
-
- if arguments['--debug']:
- debug = True
-
- try:
- dx_session_obj = GetSession()
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- time_start = time()
- single_thread = False
- config_file_path = arguments['--config']
- #Parse the dxtools.conf and put it into a dictionary
- dx_session_obj.get_config(config_file_path)
-
- #This is the function that will handle processing main_workflow for
- # all the servers.
- run_job()
-
- elapsed_minutes = time_elapsed()
- print_info('script took {:.2f} minutes to get this far.'.format(
- elapsed_minutes))
-
- #Here we handle what we do when the unexpected happens
- except DlpxException as e:
- print_exception('script encountered an error while processing the'
- 'config file:\n{}'.format(e))
-
- except SystemExit as e:
- """
- This is what we use to handle our sys.exit(#)
- """
- sys.exit(e)
-
- except HttpError as e:
- """
- We use this exception handler when our connection to Delphix fails
- """
- print_exception('Connection failed to the Delphix Engine'
- 'Please check the ERROR message:\n{}'.format(e))
- sys.exit(1)
-
- except JobError as e:
- """
- We use this exception handler when a job fails in Delphix so that
- we have actionable data
- """
- elapsed_minutes = time_elapsed()
- print_exception('A job failed in the Delphix Engine')
- print_info('{} took {:.2f} minutes to get this far\n{}'.format(
- basename(__file__), elapsed_minutes, e))
- sys.exit(3)
-
- except KeyboardInterrupt:
- """
- We use this exception handler to gracefully handle ctrl+c exits
- """
- print_debug("You sent a CTRL+C to interrupt the process")
- elapsed_minutes = time_elapsed()
- print_info('{} took {:.2f} minutes to get this far\n'.format(
- basename(__file__), elapsed_minutes))
-
- except:
- """
- Everything else gets caught here
- """
- print_exception(sys.exc_info()[0])
- elapsed_minutes = time_elapsed()
- print_info('{} took {:.2f} minutes to get this far\n'.format(
- basename(__file__), elapsed_minutes))
- sys.exit(1)
-
-if __name__ == "__main__":
- #Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
- #Feed our arguments to the main function, and off we go!
- main(arguments)
diff --git a/dx_jetstream_container.py b/dx_jetstream_container.py
deleted file mode 100755
index 0ba25db..0000000
--- a/dx_jetstream_container.py
+++ /dev/null
@@ -1,589 +0,0 @@
-#!/usr/bin/env python
-#Adam Bowen - Jun 2016
-#dx_jetstream_container.py
-#Use this file as a starter for your python scripts, if you like
-#requirements
-#pip install docopt delphixpy
-
-#The below doc follows the POSIX compliant standards and allows us to use
-#this doc to also define our arguments for the script. This thing is brilliant.
-"""Perform routine operations on Jetstream containers
-
-Usage:
- dx_jetstream_container.py --template (--container | --all_containers )
- --operation [-d | --engine | --all]
- [--bookmark_name ] [--bookmark_tags ] [--bookmark_shared ]
- [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_jetstream_container.py -h | --help | -v | --version
-
-Perform routine operations on a Jetstream Container
-
-Examples:
- dx_jetstream_container.py --operation refresh --template "Masked SugarCRM Application" --container "Sugar Automated Testing Container"
- dx_jetstream_container.py --operation reset --template "Masked SugarCRM Application" --all_containers
- dx_jetstream_container.py --template "Masked SugarCRM Application" --container "Sugar Automated Testing Container" --operation bookmark --bookmark_name "Testing" --bookmark_tags "one,two,three" --bookmark_shared true
-
-Options:
- -d Identifier of Delphix engine in dxtools.conf.
- --engine Alt Identifier of Delphix engine in dxtools.conf.
- --all Run against all engines.
- --all_containers Run against all jetstream containers
- --template Name of Jetstream template to execute against.
- --container Name of Jetstream container to execute against.
- --operation Name of the operation to execute
- Can be one of:
- start, stop, recover, refresh, reset, bookmark
- --bookmark_name Name of the bookmark to create
- (only valid with "--operation bookmark")
- --bookmark_tags Comma-delimited list to tag the bookmark
- (only valid with "--operation bookmark")
- --bookmark_shared Share bookmark: true/false
- [default: false]
- --host Name of environment in Delphix to execute against.
- --debug Enable debug logging
- --parallel Limit number of jobs to maxjob
- --poll The number of seconds to wait between job polls
- [default: 10]
- --config The path to the dxtools.conf file
- [default: ./dxtools.conf]
- --logdir The path to the logfile you want to use.
- [default: ./dx_jetstream_container_refresh.log]
- -h --help Show this screen.
- -v --version Show version.
-
-"""
-
-VERSION="v.0.0.005"
-
-
-from docopt import docopt
-import logging
-from os.path import basename
-import signal
-import sys
-import time
-import traceback
-import json
-import threading
-
-from multiprocessing import Process
-from time import sleep, time
-
-from delphixpy.v1_6_0.delphix_engine import DelphixEngine
-from delphixpy.v1_6_0.exceptions import HttpError, JobError
-from delphixpy.v1_6_0 import job_context
-from delphixpy.v1_6_0.web import jetstream, job
-from delphixpy.v1_6_0.web.vo import JSBookmark, JSBookmarkCreateParameters, JSTimelinePointLatestTimeInput
-#from delphixpy.v1_6_0.web.vo import
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
-
- E.g.:
- @run_async
- def task1():
- do_something
-
- @run_async
- def task2():
- do_something_too
-
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- #from threading import Thread
- from functools import wraps
-
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = threading.Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
-
- return async_func
-
-@run_async
-def container_bookmark(engine, server, container_obj, bookmark_name, bookmark_shared, tags):
- '''This function bookmarks the current branch on the container'''
- #But first, let's make sure it is in a CONSISTENT state
- container_recover(engine, server, container_obj)
- #Next let's make sure it is started
- container_start(engine, server, container_obj)
- #Prepare the bookmark creation parameters
- bookmark_create_params = JSBookmarkCreateParameters()
- bookmark_create_params.bookmark = JSBookmark()
- bookmark_create_params.bookmark.name = bookmark_name
- bookmark_create_params.bookmark.branch = container_obj.active_branch
- bookmark_create_params.bookmark.shared = bookmark_shared
- bookmark_create_params.bookmark.tags = tags
- bookmark_create_params.timeline_point_parameters = JSTimelinePointLatestTimeInput()
- bookmark_create_params.timeline_point_parameters.source_data_layout = container_obj.reference
-
- jetstream.bookmark.create(server, bookmark_create_params)
-
-def container_recover(engine, server, container_obj):
- '''This function recovers a container that is in an "INCONSISTENT" state'''
- if container_obj.state == "INCONSISTENT":
- #if not recover it
- job_obj = jetstream.container.recover(server, container_obj.reference)
- #wait for the recovery action to finish
- job_context.wait(server,job_obj.reference)
- #get the updated object with the new state
- container_obj = jetstream.container.get(server, container_obj.reference)
- return container_obj
-
-@run_async
-def container_recover_async(engine, server, container_obj):
- '''This function recovers all specified containers asynchronously'''
- container_recover(engine, server, container_obj)
-
-@run_async
-def container_refresh(engine, server, container_obj):
- '''This function refreshes a container'''
- #But first, let's make sure it is in a CONSISTENT state
- container_recover(engine, server, container_obj)
- #Next let's make sure it is started
- container_start(engine, server, container_obj)
- #Now let's refresh it.
- refresh_job = jetstream.container.refresh(server, container_obj.reference)
-
-@run_async
-def container_reset(engine, server, container_obj):
- '''This function resets a container'''
- #But first, let's make sure it is in a CONSISTENT state
- container_recover(engine, server, container_obj)
- #Next let's make sure it is started
- container_start(engine, server, container_obj)
- #Now let's refresh it.
- reset_job = jetstream.container.reset(server, container_obj.reference)
-
-def container_start(engine, server, container_obj):
- '''This function starts/enables a container that is in an "OFFLINE" state'''
- if container_obj.state == "OFFLINE":
- #if not, enable it
- jetstream.container.enable(server, container_obj.reference)
-
-@run_async
-def container_start_async(engine, server, container_obj):
- '''This function starts all specified containers asynchronously'''
- container_start(engine, server, container_obj)
-
-def container_stop(engine, server, container_obj):
- '''This function starts/enables a container that is in an "OFFLINE" state'''
- if container_obj.state == "ONLINE":
- #if not, enable it
- jetstream.container.disable(server, container_obj.reference)
-
-@run_async
-def container_stop_async(engine, server, container_obj):
- '''This function starts all specified containers asynchronously'''
- container_stop(engine, server, container_obj)
-
-def find_container_by_name_and_template_name(engine, server, container_name, template_name):
- template_obj = find_obj_by_name(engine, server, jetstream.template, template_name)
-
- containers = jetstream.container.get_all(server, template=template_obj.reference)
-
- for each in containers:
- if each.name == container_name:
- print_debug(engine["hostname"] + ": Found a match " + str(each.reference))
- return each
- print_info("Unable to find \"" + container_name + "\" in " + template_name)
-
-def find_all_containers_by_template_name(engine, server, template_name):
- template_obj = find_obj_by_name(engine, server, jetstream.template, template_name)
-
- containers = jetstream.container.get_all(server, template=template_obj.reference)
- if containers:
- for each in containers:
- print_debug(engine["hostname"] + ": Found a match " + str(each.reference))
- return containers
- print_info("Unable to find \"" + container_name + "\" in " + template_name)
-
-def find_obj_by_name(engine, server, f_class, obj_name):
- """
- Function to find objects by name and object class, and return object's reference as a string
- You might use this function to find objects like groups.
- """
- print_debug(engine["hostname"] + ": Searching objects in the " + f_class.__name__ + " class\n for one named \"" + obj_name +"\"")
- obj_ref = ''
-
- all_objs = f_class.get_all(server)
- for obj in all_objs:
- if obj.name == obj_name:
- print_debug(engine["hostname"] + ": Found a match " + str(obj.reference))
- return obj
-
-def get_config(config_file_path):
- """
- This function reads in the dxtools.conf file
- """
- #First test to see that the file is there and we can open it
- try:
- config_file = open(config_file_path).read()
- except:
- print_error("Was unable to open " + config_file_path + ". Please check the path and permissions, then try again.")
- sys.exit(1)
- #Now parse the file contents as json and turn them into a python dictionary, throw an error if it isn't proper json
- try:
- config = json.loads(config_file)
- except:
- print_error("Was unable to read " + config_file_path + " as json. Please check file in a json formatter and try again.")
- sys.exit(1)
- #Create a dictionary of engines (removing the data node from the dxtools.json, for easier parsing)
- delphix_engines = {}
- for each in config['data']:
- delphix_engines[each['hostname']] = each
- print_debug(delphix_engines)
- return delphix_engines
-
-def logging_est(logfile_path):
- """
- Establish Logging
- """
- global debug
- logging.basicConfig(filename=logfile_path,format='%(levelname)s:%(asctime)s:%(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
- print_info("Welcome to " + basename(__file__) + ", version " + VERSION)
- global logger
- debug = arguments['--debug']
- logger = logging.getLogger()
- if debug == True:
- logger.setLevel(10)
- print_info("Debug Logging is enabled.")
-
-def job_mode(server):
- """
- This function tells Delphix how to execute jobs, based on the single_thread variable at the beginning of the file
- """
- #Synchronously (one at a time)
- if single_thread == True:
- job_m = job_context.sync(server)
- print_debug("These jobs will be executed synchronously")
- #Or asynchronously
- else:
- job_m = job_context.async(server)
- print_debug("These jobs will be executed asynchronously")
- return job_m
-
-def job_wait(server):
- """
- This job stops all work in the thread/process until jobs are completed.
- """
- #Grab all the jos on the server (the last 25, be default)
- all_jobs = job.get_all(server)
- #For each job in the list, check to see if it is running (not ended)
- for jobobj in all_jobs:
- if not (jobobj.job_state in ["CANCELED", "COMPLETED", "FAILED"]):
- print_debug("Waiting for " + jobobj.reference + " (currently: " + jobobj.job_state+ ") to finish running against the container")
- #If so, wait
- job_context.wait(server,jobobj.reference)
-
-def on_exit(sig, func=None):
- """
- This function helps us end cleanly and with exit codes
- """
- print_info("Shutdown Command Received")
- print_info("Shutting down " + basename(__file__))
- sys.exit(0)
-
-def print_debug(print_obj):
- """
- Call this function with a log message to prefix the message with DEBUG
- """
- try:
- if debug == True:
- print "DEBUG: " + str(print_obj)
- logging.debug(str(print_obj))
- except:
- pass
-
-def print_error(print_obj):
- """
- Call this function with a log message to prefix the message with ERROR
- """
- print "ERROR: " + str(print_obj)
- logging.error(str(print_obj))
-
-def print_info(print_obj):
- """
- Call this function with a log message to prefix the message with INFO
- """
- print "INFO: " + str(print_obj)
- logging.info(str(print_obj))
-
-def print_warning(print_obj):
- """
- Call this function with a log message to prefix the message with WARNING
- """
- print "WARNING: " + str(print_obj)
- logging.warning(str(print_obj))
-
-def serversess(f_engine_address, f_engine_username, f_engine_password):
- """
- Function to setup the session with the Delphix Engine
- """
- server_session= DelphixEngine(f_engine_address, f_engine_username, f_engine_password, "DOMAIN")
- return server_session
-
-def set_exit_handler(func):
- """
- This function helps us set the correct exit code
- """
- signal.signal(signal.SIGTERM, func)
-
-@run_async
-def main_workflow(engine):
- """
- This function is where the main workflow resides.
- Use the @run_async decorator to run this function asynchronously.
- This allows us to run against multiple Delphix Engine simultaneously
- """
-
- #Pull out the values from the dictionary for this engine
- engine_address = engine["ip_address"]
- engine_username = engine["username"]
- engine_password = engine["password"]
- #Establish these variables as empty for use later
- containers = []
- jobs = {}
-
-
- #Setup the connection to the Delphix Engine
- server = serversess(engine_address, engine_username, engine_password)
-
- #If we specified a specific database by name....
- if arguments['--container']:
- #Get the container object from the name
- container_obj = find_container_by_name_and_template_name(engine, server, arguments['--container'], arguments['--template'])
- if container_obj:
- containers.append(container_obj)
- #Else, if we said all containers ...
- elif arguments['--all_containers']:
- #Grab all containers in the template
- containers = find_all_containers_by_template_name(engine, server, arguments['--template'])
- if not containers or len(containers) == 0:
- print_error("No containers found with the criterion specified")
- return
- #reset the running job count before we begin
- i = 0
- container_threads = []
- #While there are still running jobs or containers still to process....
- while (i > 0 or len(containers) > 0):
- #While there are containers still to process and we are still under
- #the max simultaneous jobs threshold (if specified)
- while len(containers) > 0 and (arguments['--parallel'] == None or i < int(arguments['--parallel'])):
- #Give us the next database in the list, and remove it from the list
- container_obj = containers.pop()
- #what do we want to do?
- if arguments['--operation'] == "refresh":
- #refresh the container
- container_threads.append(container_refresh(engine, server, container_obj))
- elif arguments['--operation'] == "reset":
- container_threads.append(container_reset(engine, server, container_obj))
- elif arguments['--operation'] == "start":
- container_threads.append(container_start_async(engine, server, container_obj))
- elif arguments['--operation'] == "stop":
- container_threads.append(container_stop_async(engine, server, container_obj))
- elif arguments['--operation'] == "recover":
- container_threads.append(container_recover_async(engine, server, container_obj))
- elif arguments['--operation'] == "bookmark":
- if arguments['--bookmark_tags']:
- tags = arguments['--bookmark_tags'].split(',')
- else:
- tags = []
- if arguments['--bookmark_shared']:
- if str(arguments['--bookmark_shared']).lower() == "true":
- bookmark_shared = True
- elif str(arguments['--bookmark_shared']).lower() == "false":
- bookmark_shared = False
- else:
- print_error("Invalid argument \"" + str(arguments['--bookmark_shared']).lower() + "\" for --bookmark_shared")
- print_error("--bookmark_shared only takes a value of true/false.")
- print_error("Exiting")
- sys.exit(1)
- else:
- bookmark_shared=False
- container_threads.append(container_bookmark(engine, server, container_obj, arguments['--bookmark_name'], bookmark_shared, tags))
- #For each thread in the list...
- i = len(container_threads)
- #Check to see if we are running at max parallel processes, and report if so.
- if ( arguments['--parallel'] != None and i >= int(arguments['--parallel'])):
- print_info(engine["hostname"] + ": Max jobs reached (" + str(i) + ")")
- #reset the running jobs counter, as we are about to update the count from the jobs report.
- i=0
- for t in container_threads:
- if t.isAlive():
- i+=1
- print_info(engine["hostname"] + ": " + str(i) + " jobs running. " + str(len(containers)) + " jobs waiting to run")
- #If we have running jobs, pause before repeating the checks.
- if i > 0:
- sleep(float(arguments['--poll']))
- print "made it out"
- #For each thread in the list...
- for each in container_threads:
- #join them back together so that we wait for all threads to complete before moving on
- each.join()
-
-def run_job(engine):
- """
- This function runs the main_workflow aynchronously against all the servers specified
- """
- #Create an empty list to store threads we create.
- threads = []
- #If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info("Executing against all Delphix Engines in the dxtools.conf")
- #For each server in the dxtools.conf...
- for delphix_engine in dxtools_objects:
- engine = dxtools_objects[delphix_engine]
- #Create a new thread and add it to the list.
- threads.append(main_workflow(engine))
- else:
- #Else if the --engine argument was given, test to see if the engine exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dxtools_objects[arguments['--engine']]
- print_info("Executing against Delphix Engine: " + arguments['--engine'])
- except:
- print_error("Delphix Engine \"" + arguments['--engine'] + "\" cannot be found in " + config_file_path)
- print_error("Please check your value and try again. Exiting")
- sys.exit(1)
- #Else if the -d argument was given, test to see if the engine exists in dxtools.conf
- elif arguments['-d']:
- try:
- engine = dxtools_objects[arguments['-d']]
- print_info("Executing against Delphix Engine: " + arguments['-d'])
- except:
- print_error("Delphix Engine \"" + arguments['-d'] + "\" cannot be found in " + config_file_path)
- print_error("Please check your value and try again. Exiting")
- sys.exit(1)
- else:
- #Else search for a default engine in the dxtools.conf
- for delphix_engine in dxtools_objects:
- if dxtools_objects[delphix_engine]['default'] == 'true':
- engine = dxtools_objects[delphix_engine]
- print_info("Executing against the default Delphix Engine in the dxtools.conf: " + dxtools_objects[delphix_engine]['hostname'])
- break
- if engine == None:
- print_error("No default engine found. Exiting")
- sys.exit(1)
- #run the job against the engine
- threads.append(main_workflow(engine))
-
- #For each thread in the list...
- for each in threads:
- #join them back together so that we wait for all threads to complete before moving on
- each.join()
-
-def time_elapsed():
- """
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
- """
- elapsed_minutes = round((time() - time_start)/60, +1)
- return elapsed_minutes
-
-def update_jobs_dictionary(engine, server, jobs):
- """
- This function checks each job in the dictionary and updates its status or removes it if the job is complete.
- Return the number of jobs still running.
- """
- #Establish the running jobs counter, as we are about to update the count from the jobs report.
- i = 0
- #get all the jobs, then inspect them
- for j in jobs.keys():
- job_obj = job.get(server, jobs[j])
- print_debug(engine["hostname"] + ": " + str(job_obj))
- print_info(engine["hostname"] + ": " + j.name + ": " + job_obj.job_state)
-
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- #If the job is in a non-running state, remove it from the running jobs list.
- del jobs[j]
- else:
- #If the job is in a running state, increment the running job count.
- i += 1
- return i
-
-def main(argv):
- #We want to be able to call on these variables anywhere in the script.
- global single_thread
- global usebackup
- global time_start
- global config_file_path
- global dxtools_objects
-
- try:
- #Declare globals that will be used throughout the script.
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- time_start = time()
- engine = None
- single_thread = False
-
- config_file_path = arguments['--config']
- #Parse the dxtools.conf and put it into a dictionary
- dxtools_objects = get_config(config_file_path)
-
- #This is the function that will handle processing main_workflow for all the servers.
- run_job(engine)
-
- elapsed_minutes = time_elapsed()
- print_info("script took " + str(elapsed_minutes) + " minutes to get this far.")
-
-
- #Here we handle what we do when the unexpected happens
- except SystemExit as e:
- """
- This is what we use to handle our sys.exit(#)
- """
- sys.exit(e)
- except HttpError as e:
- """
- We use this exception handler when our connection to Delphix fails
- """
- print_error("Connection failed to the Delphix Engine")
- print_error( "Please check the ERROR message below")
- print_error(e.message)
- sys.exit(2)
- except JobError as e:
- """
- We use this exception handler when a job fails in Delphix so that we have actionable data
- """
- print_error("A job failed in the Delphix Engine")
- print_error(e.job)
- elapsed_minutes = time_elapsed()
- print_info(basename(__file__) + " took " + str(elapsed_minutes) + " minutes to get this far.")
- sys.exit(3)
- except KeyboardInterrupt:
- """
- We use this exception handler to gracefully handle ctrl+c exits
- """
- print_debug("You sent a CTRL+C to interrupt the process")
- elapsed_minutes = time_elapsed()
- print_info(basename(__file__) + " took " + str(elapsed_minutes) + " minutes to get this far.")
- except:
- """
- Everything else gets caught here
- """
- print_error(sys.exc_info()[0])
- print_error(traceback.format_exc())
- elapsed_minutes = time_elapsed()
- print_info(basename(__file__) + " took " + str(elapsed_minutes) + " minutes to get this far.")
- sys.exit(1)
-
-if __name__ == "__main__":
- #Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
-
- #Feed our arguments to the main function, and off we go!
- print arguments
- main(arguments)
\ No newline at end of file
diff --git a/dx_jobs.py b/dx_jobs.py
deleted file mode 100755
index 069853b..0000000
--- a/dx_jobs.py
+++ /dev/null
@@ -1,367 +0,0 @@
-#!/usr/bin/env python
-# Corey Brune - Oct 2016
-#Description:
-# List jobs on a given engine
-#
-#Requirements
-#pip install docopt delphixpy
-
-#The below doc follows the POSIX compliant standards and allows us to use
-#this doc to also define our arguments for the script.
-"""List jobs on an engine
-Usage:
- dx_jobs.py (--list [--state ][--title ])
- [--engine | --all]
- [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_jobs.py -h | --help | -v | --version
-
-List jobs on an engine
-
-Examples:
- dx_jobs.py --list --state failed
- dx_jobs.py --list --title snapsync
- dx_jobs.py --list --state failed --title snapsync
-
-
-Options:
- --list List all jobs on an engine.
- --title Filter job by title name. Note: The search is case insensitive.
- --state Filter jobs by state: RUNNING, SUSPENDED, CANCELED, COMPLETED, FAILED
- --engine Alt Identifier of Delphix engine in dxtools.conf.
- --all Run against all engines.
- --debug Enable debug logging
- --parallel Limit number of jobs to maxjob
- --poll The number of seconds to wait between job polls
- [default: 10]
- --config The path to the dxtools.conf file
- [default: ./dxtools.conf]
- --logdir The path to the logfile you want to use.
- [default: ./dx_operations_vdb.log]
- -h --help Show this screen.
- -v --version Show version.
-"""
-
-VERSION = 'v.0.0.002'
-
-import sys
-import re
-from os.path import basename
-from time import sleep, time
-from docopt import docopt
-
-from delphixpy.v1_8_0.exceptions import HttpError
-from delphixpy.v1_8_0.exceptions import JobError
-from delphixpy.v1_8_0.exceptions import RequestError
-from delphixpy.v1_8_0.web import job
-
-from lib.DlpxException import DlpxException
-from lib.DxLogging import logging_est
-from lib.DxLogging import print_debug
-from lib.DxLogging import print_info
-from lib.DxLogging import print_exception
-from lib.GetSession import GetSession
-
-
-def list_jobs():
-
- if arguments['--state']:
- if re.match('RUNNING|SUSPENDED|CANCELED|COMPLETED|FAILED',
- arguments['--state'].upper()):
- pass
- else:
- print_info('The state should be one of these options:\n'
- 'RUNNING, SUSPENDED, CANCELED, COMPLETED, FAILED')
- sys.exit(1)
-
- for job_info in job.get_all(dx_session_obj.server_session,
- job_state=arguments['--state'].upper()):
-
- if arguments['--title']:
- if re.search(arguments['--title'], job_info.title,
- re.IGNORECASE):
- print('Action={}, Job State={}, Parent Action State={},'
- 'Percent Complete={}, Reference={}, Target={},'
- 'Target Name={}, Title={}, User={}\n'.format(
- job_info.action_type, job_info.job_state,
- job_info.parent_action_state,
- job_info.percent_complete, job_info.reference,
- job_info.target, job_info.target_name,
- job_info.title, job_info.user))
- else:
- print('Action=%s, Job State=%s, Parent Action State=%s,'
- 'Percent Complete=%s, Reference=%s, Target=%s,'
- 'Target Name=%s, Title=%s, User=%s\n' %
- (job_info.action_type, job_info.job_state,
- job_info.parent_action_state,
- job_info.percent_complete, job_info.reference,
- job_info.target, job_info.target_name,
- job_info.title, job_info.user))
- else:
- for job_info in job.get_all(dx_session_obj.server_session):
-
- if arguments['--title']:
- if re.search(arguments['--title'], job_info.title,
- re.IGNORECASE):
- print('Action=%s, Job State=%s, Parent Action State=%s,'
- 'Percent Complete=%s, Reference=%s, Target=%s,'
- 'Target Name=%s, Title=%s, User=%s\n' %
- (job_info.action_type, job_info.job_state,
- job_info.parent_action_state, job_info.percent_complete,
- job_info.reference, job_info.target, job_info.target_name,
- job_info.title, job_info.user))
- else:
- print('Action=%s, Job State=%s, Parent Action State=%s,'
- 'Percent Complete=%s, Reference=%s, Target=%s,'
- 'Target Name=%s, Title=%s, User=%s\n' %
- (job_info.action_type, job_info.job_state,
- job_info.parent_action_state, job_info.percent_complete,
- job_info.reference, job_info.target,
- job_info.target_name, job_info.title, job_info.user))
-
-
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
- E.g.:
- @run_async
- def task1():
- do_something
- @run_async
- def task2():
- do_something_too
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- from threading import Thread
- from functools import wraps
-
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
-
- return async_func
-
-
-@run_async
-def main_workflow(engine):
- """
- This function actually runs the jobs.
- Use the @run_async decorator to run this function asynchronously.
- This allows us to run against multiple Delphix Engine simultaneously
-
- engine: Dictionary of engines
- """
- jobs = {}
-
- try:
- #Setup the connection to the Delphix Engine
- dx_session_obj.serversess(engine['ip_address'], engine['username'],
- engine['password'])
-
- except DlpxException as e:
- print_exception('\nERROR: Engine {} encountered an error while'
- '{}:\n{}\n'.format(engine['hostname'],
- arguments['--target'], e))
- sys.exit(1)
-
- thingstodo = ["thingtodo"]
- with dx_session_obj.job_mode(single_thread):
- while len(dx_session_obj.jobs) > 0 or len(thingstodo) > 0:
- if len(thingstodo) > 0:
-
- if arguments['--list']:
- list_jobs()
- thingstodo.pop()
-
- # get all the jobs, then inspect them
- i = 0
- for j in dx_session_obj.jobs.keys():
- job_obj = job.get(dx_session_obj.server_session,
- dx_session_obj.jobs[j])
- print_debug(job_obj)
- print_info('{}: Operations: {}'.format(engine['hostname'],
- job_obj.job_state))
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- # If the job is in a non-running state, remove it from the
- # running jobs list.
- del dx_session_obj.jobs[j]
- elif job_obj.job_state in 'RUNNING':
- # If the job is in a running state, increment the running
- # job count.
- i += 1
-
- print_info('{}: {:d} jobs running.'.format(
- engine['hostname'], i))
-
- # If we have running jobs, pause before repeating the checks.
- if len(dx_session_obj.jobs) > 0:
- sleep(float(arguments['--poll']))
-
-
-def run_job():
- """
- This function runs the main_workflow aynchronously against all the servers
- specified
- """
- #Create an empty list to store threads we create.
- threads = []
-
- #If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info("Executing against all Delphix Engines in the dxtools.conf")
-
- try:
- #For each server in the dxtools.conf...
- for delphix_engine in dx_session_obj.dlpx_engines:
- engine = dx_session_obj[delphix_engine]
- #Create a new thread and add it to the list.
- threads.append(main_workflow(engine))
-
- except DlpxException as e:
- print 'Error encountered in run_job():\n{}'.format(e)
- sys.exit(1)
-
- elif arguments['--all'] is False:
- #Else if the --engine argument was given, test to see if the engine
- # exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dx_session_obj.dlpx_engines[arguments['--engine']]
- print_info('Executing against Delphix Engine: %s\n' %
- (arguments['--engine']))
-
- except (DlpxException, RequestError, KeyError) as e:
- raise DlpxException('\nERROR: Delphix Engine %s cannot be ' 'found in %s. Please check your value '
- 'and try again. Exiting.\n' % (
- arguments['--engine'], config_file_path))
-
-
-
- else:
- #Else search for a default engine in the dxtools.conf
- for delphix_engine in dx_session_obj.dlpx_engines:
- if dx_session_obj.dlpx_engines[delphix_engine]['default'] == \
- 'true':
-
- engine = dx_session_obj.dlpx_engines[delphix_engine]
- print_info('Executing against the default Delphix Engine '
- 'in the dxtools.conf: %s' % (
- dx_session_obj.dlpx_engines[delphix_engine]['hostname']))
-
- break
-
- if engine == None:
- raise DlpxException("\nERROR: No default engine found. Exiting")
-
- #run the job against the engine
- threads.append(main_workflow(engine))
-
- #For each thread in the list...
- for each in threads:
- #join them back together so that we wait for all threads to complete
- # before moving on
- each.join()
-
-
-def time_elapsed():
- """
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
- """
- elapsed_minutes = round((time() - time_start)/60, +1)
- return elapsed_minutes
-
-
-def main(argv):
- #We want to be able to call on these variables anywhere in the script.
- global single_thread
- global usebackup
- global time_start
- global config_file_path
- global database_name
- global dx_session_obj
- global debug
-
- if arguments['--debug']:
- debug = True
-
- try:
- dx_session_obj = GetSession()
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- time_start = time()
- engine = None
- single_thread = False
- config_file_path = arguments['--config']
- #Parse the dxtools.conf and put it into a dictionary
- dx_session_obj.get_config(config_file_path)
-
- #This is the function that will handle processing main_workflow for
- # all the servers.
- run_job()
-
- elapsed_minutes = time_elapsed()
- print_info("script took " + str(elapsed_minutes) +
- " minutes to get this far.")
-
- #Here we handle what we do when the unexpected happens
- except SystemExit as e:
- """
- This is what we use to handle our sys.exit(#)
- """
- sys.exit(e)
-
- except HttpError as e:
- """
- We use this exception handler when our connection to Delphix fails
- """
- print_exception('Connection failed to the Delphix Engine'
- 'Please check the ERROR message below')
- sys.exit(1)
-
- except JobError as e:
- """
- We use this exception handler when a job fails in Delphix so that
- we have actionable data
- """
- elapsed_minutes = time_elapsed()
- print_exception('A job failed in the Delphix Engine')
- print_info('%s took %s minutes to get this far\n' %
- (basename(__file__), str(elapsed_minutes)))
- sys.exit(3)
-
- except KeyboardInterrupt:
- """
- We use this exception handler to gracefully handle ctrl+c exits
- """
- print_debug("You sent a CTRL+C to interrupt the process")
- elapsed_minutes = time_elapsed()
- print_info('%s took %s minutes to get this far\n' %
- (basename(__file__), str(elapsed_minutes)))
-
- except:
- """
- Everything else gets caught here
- """
- print_exception(sys.exc_info()[0])
- elapsed_minutes = time_elapsed()
- print_info('%s took %s minutes to get this far\n' %
- (basename(__file__), str(elapsed_minutes)))
- sys.exit(1)
-
-if __name__ == "__main__":
- #Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
- #Feed our arguments to the main function, and off we go!
- main(arguments)
diff --git a/dx_operations.py b/dx_operations.py
index 9827d78..0d0f81b 100755
--- a/dx_operations.py
+++ b/dx_operations.py
@@ -1,17 +1,18 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Corey Brune - Oct 2016
# This script starts or stops a VDB
# requirements
# pip install docopt delphixpy
# The below doc follows the POSIX compliant standards and allows us to use
-# this doc to also define our arguments for the script.
+# this doc to also define our ARGUMENTS for the script.
"""List all VDBs or Start, stop, enable, disable a VDB
Usage:
- dx_operations_vdb.py (--vdb [--stop | --start | --enable | --disable] | --list | --all_dbs )
- [-d | --engine | --all]
- [--force] [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
+ dx_operations_vdb.py (--vdb [--stop | --start | --enable | \
+ --disable] | --list | --all_dbs )
+ [--engine ]
+ [--force --parallel --poll --single_thread ]
+ [--config ] [--logdir ]
dx_operations_vdb.py -h | --help | -v | --version
List all VDBs, start, stop, enable, disable a VDB
@@ -30,11 +31,12 @@
--list List all databases from an engine
--enable Enable the VDB
--disable Disable the VDB
- -d Identifier of Delphix engine in dxtools.conf.
- --engine Alt Identifier of Delphix engine in dxtools.conf.
- --all Run against all engines.
+ --engine Identifier of Delphix engine in dxtools.conf.
+ [default: default]
+ --single_thread Run as a single thread. False if running multiple
+ threads.
+ [default: True]
--force Do not clean up target in VDB disable operations
- --debug Enable debug logging
--parallel Limit number of jobs to maxjob
--poll The number of seconds to wait between job polls
[default: 10]
@@ -45,40 +47,30 @@
-h --help Show this screen.
-v --version Show version.
"""
-
-VERSION = 'v.0.3.018'
-
import sys
+import time
from os.path import basename
-from time import sleep, time
-import traceback
-from docopt import docopt
-from delphixpy.v1_8_0.exceptions import HttpError
-from delphixpy.v1_8_0.exceptions import JobError
-from delphixpy.v1_8_0.exceptions import RequestError
-from delphixpy.v1_8_0.web import database
-from delphixpy.v1_8_0.web import job
-from delphixpy.v1_8_0.web import source
-from delphixpy.v1_8_0.web.capacity import consumer
-from delphixpy.v1_8_0.web.vo import SourceDisableParameters
-from delphixpy.v1_8_0.web.source import source
+import docopt
+
+from delphixpy.v1_10_2 import exceptions
+from delphixpy.v1_10_2.web import database
+from delphixpy.v1_10_2.web import source
+from delphixpy.v1_10_2.web.capacity import consumer
+from delphixpy.v1_10_2.web.vo import SourceDisableParameters
+from lib import dlpx_exceptions
+from lib import dx_logging
+from lib import get_references
+from lib import get_session
+from lib import run_job
+from lib.run_async import run_async
-from lib.DlpxException import DlpxException
-from lib.DxLogging import logging_est
-from lib.DxLogging import print_debug
-from lib.DxLogging import print_info
-from lib.DxLogging import print_exception
-from lib.GetReferences import find_obj_by_name
-from lib.GetReferences import find_all_objects
-from lib.GetReferences import find_obj_list
-from lib.GetSession import GetSession
+VERSION = "v.0.3.004"
def dx_obj_operation(dlpx_obj, vdb_name, operation):
"""
Function to start, stop, enable or disable a VDB
-
:param dlpx_obj: Virtualization Engine session object
:type dlpx_obj: lib.GetSession.GetSession
:param vdb_name: Name of the object to stop/start/enable/disable
@@ -86,354 +78,234 @@ def dx_obj_operation(dlpx_obj, vdb_name, operation):
:param operation: enable or disable dSources and VDBs
:type operation: str
"""
-
- print_debug('Searching for {} reference.\n'.format(vdb_name))
- engine_name = dlpx_obj.dlpx_engines.keys()[0]
- vdb_obj = find_obj_by_name(dlpx_obj.server_session, source, vdb_name)
+ engine_name = list(dlpx_obj.dlpx_ddps)[0]
+ vdb_obj = get_references.find_obj_by_name(dlpx_obj.server_session, source, vdb_name)
try:
if vdb_obj:
- if operation == 'start':
+ if operation == "start":
source.start(dlpx_obj.server_session, vdb_obj.reference)
- elif operation == 'stop':
+ elif operation == "stop":
source.stop(dlpx_obj.server_session, vdb_obj.reference)
- elif operation == 'enable':
+ elif operation == "enable":
source.enable(dlpx_obj.server_session, vdb_obj.reference)
- elif operation == 'disable':
- source.disable(dlpx_obj.server_session,
- vdb_obj.reference)
- elif operation == 'force_disable':
+ elif operation == "disable":
+ source.disable(dlpx_obj.server_session, vdb_obj.reference)
+ elif operation == "force_disable":
disable_params = SourceDisableParameters()
disable_params.attempt_cleanup = False
- source.disable(dlpx_obj.server_session,
- vdb_obj.reference,
- disable_params)
+ source.disable(
+ dlpx_obj.server_session, vdb_obj.reference, disable_params
+ )
dlpx_obj.jobs[engine_name] = dlpx_obj.server_session.last_job
- except (RequestError, HttpError, JobError, AttributeError), e:
- print_exception('An error occurred while performing {} on {}:\n'
- '{}'.format(operation, vdb_name, e))
- print '{} was successfully performed on {}.'.format(operation, vdb_name)
+ except (exceptions.RequestError, exceptions.JobError, AttributeError) as err:
+ raise dlpx_exceptions.DlpxException(
+ f"An error occurred while performing {operation} on {vdb_obj}:\n" f"{err}"
+ )
+ print(f"{operation} was successfully performed on {vdb_name}.")
def all_databases(dlpx_obj, operation):
"""
Enable or disable all dSources and VDBs on an engine
-
:param dlpx_obj: Virtualization Engine session object
:type dlpx_obj: lib.GetSession.GetSession
:param operation: enable or disable dSources and VDBs
:type operation: str
"""
-
for db in database.get_all(dlpx_obj.server_session):
try:
dx_obj_operation(dlpx_obj, db.name, operation)
- except (RequestError, HttpError, JobError):
+ except (exceptions.RequestError, exceptions.HttpError):
pass
- print '{} {}\n'.format(operation, db.name)
- sleep(2)
+ time.sleep(1)
def list_databases(dlpx_obj):
"""
Function to list all databases and stats for an engine
-
:param dlpx_obj: Virtualization Engine session object
:type dlpx_obj: lib.GetSession.GetSession
"""
-
- source_stats_lst = find_all_objects(dlpx_obj.server_session, source)
- is_dSource = None
+ all_source_objs = source.get_all(dlpx_obj.server_session)
+ all_consumer_objs = consumer.get_all(dlpx_obj.server_session)
+ db_size = None
+ active_space = None
+ sync_space = None
+ log_space = None
try:
- for db_stats in find_all_objects(dlpx_obj.server_session,
- consumer):
- source_stats = find_obj_list(source_stats_lst, db_stats.name)
+ for db_stats in all_consumer_objs:
+ source_stats = get_references.find_obj_list(all_source_objs, db_stats.name)
if source_stats is not None:
- if source_stats.virtual is False:
- db_size = source_stats.runtime.database_size/1024/1024/1024
- print('name: {}, provision container: dSource, disk usage: '
- '{:.2f}GB, Size of Snapshots: {:.2f}GB, '
- 'dSource Size: {:.2f}GB, Log Size: {:.2f}MB,'
- 'Enabled: {}, Status: {}'.format(str(db_stats.name),
- db_stats.breakdown.active_space/1024/1024/1024,
- db_stats.breakdown.sync_space/1024/1024/1024,
- source_stats.runtime.database_size/1024/1024/1024,
- db_stats.breakdown.log_space/1024/1024,
- source_stats.runtime.enabled,
- source_stats.runtime.status))
- elif source_stats.virtual is True:
- print('name: {}, provision container: {}, disk usage: '
- '{:.2f}GB, Size of Snapshots: {:.2f}GB, '
- 'Log Size: {:.2f}MB, Enabled: {}, '
- 'Status: {}'.format(str(db_stats.name),
- db_stats.parent,
- db_stats.breakdown.active_space/1024/1024/1024,
- db_stats.breakdown.sync_space/1024/1024/1024,
- db_stats.breakdown.log_space/1024/1024,
- source_stats.runtime.enabled,
- source_stats.runtime.status))
+ active_space = db_stats.breakdown.active_space / 1024 / 1024 / 1024
+ sync_space = db_stats.breakdown.sync_space / 1024 / 1024 / 1024
+ log_space = db_stats.breakdown.log_space / 1024 / 1024
+ db_size = source_stats.runtime.database_size / 1024 / 1024 / 1024
+ if source_stats.virtual is False:
+ print(
+ f"name: {db_stats.name}, provision container:"
+ f" {db_stats.parent}, disk usage: {db_size:.2f}GB,"
+ f"Size of Snapshots: {active_space:.2f}GB, "
+ f"dSource Size: {sync_space:.2f}GB, "
+ f"Log Size: {log_space:.2f}MB,"
+ f"Enabled: {source_stats.runtime.enabled},"
+ f"Status: {source_stats.runtime.status}"
+ )
+ elif source_stats.virtual is True:
+ print(
+ f"name: {db_stats.name}, provision container: "
+ f"{db_stats.parent}, disk usage: "
+ f"{active_space:.2f}GB, Size of Snapshots: "
+ f"{sync_space:.2f}GB"
+ f"Log Size: {log_space:.2f}MB, Enabled: "
+ f"{source_stats.runtime.enabled}, "
+ f"Status: {source_stats.runtime.status}"
+ )
elif source_stats is None:
- print('name: {},provision container: {},database disk '
- 'usage: {:.2f} GB,Size of Snapshots: {:.2f} GB,'
- 'Could not find source information. This could be a '
- 'result of an unlinked object'.format(
- str(db_stats.name), str(db_stats.parent),
- db_stats.breakdown.active_space / 1024 / 1024 / 1024,
- db_stats.breakdown.sync_space / 1024 / 1024 / 1024))
- except (RequestError, JobError, AttributeError, DlpxException) as err:
- print 'An error occurred while listing databases: {}'.format(err)
-
-
-def run_async(func):
- """
- http://code.activestate.com/recipes/576684-simple-threading-decorator/
- run_async(func)
- function decorator, intended to make "func" run in a separate
- thread (asynchronously).
- Returns the created Thread object
- E.g.:
- @run_async
- def task1():
- do_something
- @run_async
- def task2():
- do_something_too
- t1 = task1()
- t2 = task2()
- ...
- t1.join()
- t2.join()
- """
- from threading import Thread
- from functools import wraps
-
- @wraps(func)
- def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
- func_hl.start()
- return func_hl
-
- return async_func
+ print(
+ f"name: {db_stats.name},provision container: "
+ f"{db_stats.parent}, database disk usage: "
+ f"{db_size:.2f}GB,"
+ f"Size of Snapshots: {active_space:.2f}GB,"
+ "Could not find source information. This could be a "
+ "result of an unlinked object"
+ )
+ except (
+ exceptions.RequestError,
+ AttributeError,
+ dlpx_exceptions.DlpxException,
+ ) as err:
+ print(f"An error occurred while listing databases: {err}")
@run_async
-def main_workflow(engine, dlpx_obj):
+def main_workflow(engine, dlpx_obj, single_thread):
"""
This function is where we create our main workflow.
Use the @run_async decorator to run this function asynchronously.
The @run_async decorator allows us to run against multiple Delphix Engine
simultaneously
-
:param engine: Dictionary of engines
:type engine: dictionary
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
+ :param dlpx_obj: DDP session object
+ :type dlpx_obj: lib.GetSession.GetSession object
+ :param single_thread: True - run single threaded, False - run multi-thread
+ :type single_thread: bool
"""
-
try:
- # Setup the connection to the Delphix Engine
- dlpx_obj.serversess(engine['ip_address'], engine['username'],
- engine['password'])
-
- except DlpxException as e:
- print_exception('ERROR: Engine {} encountered an error while'
- '{}:\n{}\n'.format(engine['hostname'],
- arguments['--target'], e))
- sys.exit(1)
-
- thingstodo = ["thingtodo"]
+ # Setup the connection to the Delphix DDP
+ dlpx_obj.dlpx_session(
+ engine["ip_address"],
+ engine["username"],
+ engine["password"],
+ engine["use_https"],
+ )
+ except dlpx_exceptions.DlpxException as err:
+ dx_logging.print_exception(
+ f"ERROR: {basename(__file__)} encountered an error authenticating"
+ f' to {engine["hostname"]} {ARGUMENTS["--target"]}:\n{err}'
+ )
+ thingstodo = ["thingstodo"]
try:
with dlpx_obj.job_mode(single_thread):
- while len(dlpx_obj.jobs) > 0 or len(thingstodo) > 0:
- if len(thingstodo) > 0:
- if arguments['--start']:
- dx_obj_operation(dlpx_obj, arguments['--vdb'], 'start')
- elif arguments['--stop']:
- dx_obj_operation(dlpx_obj, arguments['--vdb'], 'stop')
- elif arguments['--enable']:
- dx_obj_operation(dlpx_obj, arguments['--vdb'], 'enable')
- elif arguments['--disable']:
- if arguments['--force']:
+ while dlpx_obj.jobs or thingstodo:
+ if thingstodo:
+ if ARGUMENTS["--start"]:
+ dx_obj_operation(dlpx_obj, ARGUMENTS["--vdb"], "start")
+ elif ARGUMENTS["--stop"]:
+ dx_obj_operation(dlpx_obj, ARGUMENTS["--vdb"], "stop")
+ elif ARGUMENTS["--enable"]:
+ dx_obj_operation(dlpx_obj, ARGUMENTS["--vdb"], "enable")
+ elif ARGUMENTS["--disable"]:
+ if ARGUMENTS["--force"]:
dx_obj_operation(
- dlpx_obj, arguments['--vdb'], 'force_disable')
+ dlpx_obj, ARGUMENTS["--vdb"], "force_disable"
+ )
else:
- dx_obj_operation(
- dlpx_obj, arguments['--vdb'], 'disable')
- elif arguments['--list']:
+ dx_obj_operation(dlpx_obj, ARGUMENTS["--vdb"], "disable")
+ elif ARGUMENTS["--list"]:
list_databases(dlpx_obj)
- elif arguments['--all_dbs']:
- all_databases(dlpx_obj, arguments['--all_dbs'])
+ elif ARGUMENTS["--all_dbs"]:
+ all_databases(dlpx_obj, ARGUMENTS["--all_dbs"])
thingstodo.pop()
- # get all the jobs, then inspect them
- i = 0
- for j in dlpx_obj.jobs.keys():
- job_obj = job.get(dlpx_obj.server_session, dlpx_obj.jobs[j])
- print_debug(job_obj)
- print_info('{}: Running JS Bookmark: {}'.format(
- engine['hostname'], job_obj.job_state))
- if job_obj.job_state in ["CANCELED", "COMPLETED", "FAILED"]:
- # If the job is in a non-running state, remove it
- # from the running jobs list.
- del dlpx_obj.jobs[j]
- elif job_obj.job_state in 'RUNNING':
- # If the job is in a running state, increment the
- # running job count.
- i += 1
- print_info('{}: {:d} jobs running.'.format(
- engine['hostname'], i))
- # If we have running jobs, pause before repeating the
- # checks.
- if len(dlpx_obj.jobs) > 0:
- sleep(float(arguments['--poll']))
- except (DlpxException, RequestError, JobError, HttpError) as e:
- print_exception('Error in js_bookmark: {}\n{}'.format(
- engine['hostname'], e))
- sys.exit(1)
-
-
-def time_elapsed(time_start):
- """
- This function calculates the time elapsed since the beginning of the script.
- Call this anywhere you want to note the progress in terms of time
-
- :param time_start: start time of the script.
- :type time_start: float
- """
- return round((time() - time_start)/60, +1)
+ run_job.find_job_state(engine, dlpx_obj)
+ except (
+ dlpx_exceptions.DlpxException,
+ exceptions.RequestError,
+ exceptions.JobError,
+ exceptions.HttpError,
+ ) as err:
+ dx_logging.print_exception(
+ f'Error in {basename(__file__)}: {engine["ip_address"]}\n{err}'
+ )
-def run_job(dlpx_obj, config_file_path):
+def main():
"""
- This function runs the main_workflow aynchronously against all the
- servers specified
-
- :param dlpx_obj: Virtualization Engine session object
- :type dlpx_obj: lib.GetSession.GetSession
- :param config_file_path: string containing path to configuration file.
- :type config_file_path: str
+ main function - creates session and runs jobs
"""
-
- # Create an empty list to store threads we create.
- threads = []
- engine = None
-
- # If the --all argument was given, run against every engine in dxtools.conf
- if arguments['--all']:
- print_info('Executing against all Delphix Engines in the dxtools.conf')
- try:
- # For each server in the dxtools.conf...
- for delphix_engine in dlpx_obj.dlpx_engines:
- engine = dlpx_obj.dlpx_engines[delphix_engine]
- # Create a new thread and add it to the list.
- threads.append(main_workflow(engine, dlpx_obj))
- except DlpxException as e:
- print_exception('Error encountered in run_job():\n{}'.format(e))
- sys.exit(1)
-
- elif arguments['--all'] is False:
- # Else if the --engine argument was given, test to see if the engine
- # exists in dxtools.conf
- if arguments['--engine']:
- try:
- engine = dlpx_obj.dlpx_engines[arguments['--engine']]
- print_info('Executing against Delphix Engine: {}\n'.format(
- arguments['--engine']))
- except (DlpxException, RequestError, KeyError):
- raise DlpxException('\nERROR: Delphix Engine {} cannot be '
- 'found in {}. Please check your value and'
- ' try again. Exiting.\n'.format(
- arguments['--engine'], config_file_path))
- else:
- # Else search for a default engine in the dxtools.conf
- for delphix_engine in dlpx_obj.dlpx_engines:
- if dlpx_obj.dlpx_engines[delphix_engine]['default'] == 'true':
- engine = dlpx_obj.dlpx_engines[delphix_engine]
- print_info('Executing against the default Delphix Engine '
- 'in the dxtools.conf: {}'.format(
- dlpx_obj.dlpx_engines[delphix_engine]['hostname']))
- break
-
- if engine is None:
- raise DlpxException('\nERROR: No default engine found. Exiting')
-
- # run the job against the engine
- threads.append(main_workflow(engine, dlpx_obj))
-
- # For each thread in the list...
- for each in threads:
- # join them back together so that we wait for all threads to complete
- # before moving on
- each.join()
-
-
-def main():
- # We want to be able to call on these variables anywhere in the script.
- global single_thread
- global debug
-
- time_start = time()
- single_thread = False
-
+ time_start = time.time()
try:
- dx_session_obj = GetSession()
- logging_est(arguments['--logdir'])
- print_debug(arguments)
- config_file_path = arguments['--config']
- # Parse the dxtools.conf and put it into a dictionary
+ dx_session_obj = get_session.GetSession()
+ dx_logging.logging_est(ARGUMENTS["--logdir"])
+ config_file_path = ARGUMENTS["--config"]
+ single_thread = ARGUMENTS["--single_thread"]
+ engine = ARGUMENTS["--engine"]
dx_session_obj.get_config(config_file_path)
-
# This is the function that will handle processing main_workflow for
# all the servers.
- run_job(dx_session_obj, config_file_path)
-
- elapsed_minutes = time_elapsed(time_start)
- print_info('script took {:.2f} minutes to get this far.'.format(
- elapsed_minutes))
-
+ for each in run_job.run_job(
+ main_workflow, dx_session_obj, engine, single_thread
+ ):
+ # join them back together so that we wait for all threads to
+ # complete
+ each.join()
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_info(
+ f"script took {elapsed_minutes} minutes to " f"get this far."
+ )
# Here we handle what we do when the unexpected happens
- except SystemExit as e:
+ except SystemExit as err:
# This is what we use to handle our sys.exit(#)
- sys.exit(e)
-
- except DlpxException as e:
- # We use this exception handler when an error occurs in a function call.
- print_exception('ERROR: Please check the ERROR message below:\n'
- '{}'.format(e.message))
+ sys.exit(err)
+
+ except dlpx_exceptions.DlpxException as err:
+ # We use this exception handler when an error occurs in a function
+ # call.
+ dx_logging.print_exception(
+ f"ERROR: Please check the ERROR message " f"below:\n {err.error}"
+ )
sys.exit(2)
- except HttpError as e:
+ except exceptions.HttpError as err:
# We use this exception handler when our connection to Delphix fails
- print_exception('ERROR: Connection failed to the Delphix Engine. Please'
- 'check the ERROR message below:\n{}'.format(e.message))
+ dx_logging.print_exception(
+ f"ERROR: Connection failed to the Delphix DDP. Please check "
+ f"the ERROR message below:\n{err.status}"
+ )
sys.exit(2)
- except JobError as e:
+ except exceptions.JobError as err:
# We use this exception handler when a job fails in Delphix so that we
# have actionable data
- print_exception('A job failed in the Delphix Engine:\n{}'.format(e.job))
- elapsed_minutes = time_elapsed(time_start)
- print_exception('{} took {:.2f} minutes to get this far'.format(
- basename(__file__), elapsed_minutes))
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_exception(
+ f"A job failed in the Delphix Engine:\n{err.job}."
+ f"{basename(__file__)} took {elapsed_minutes} minutes to get "
+ f"this far"
+ )
sys.exit(3)
except KeyboardInterrupt:
# We use this exception handler to gracefully handle ctrl+c exits
- print_debug('You sent a CTRL+C to interrupt the process')
- elapsed_minutes = time_elapsed(time_start)
- print_info('{} took {:.2f} minutes to get this far'.format(
- basename(__file__), elapsed_minutes))
- except:
- # Everything else gets caught here
- print_exception('{}\n{}'.format(sys.exc_info()[0],
- traceback.format_exc()))
- elapsed_minutes = time_elapsed(time_start)
- print_info("{} took {:.2f} minutes to get this far".format(
- basename(__file__), elapsed_minutes))
- sys.exit(1)
+ dx_logging.print_debug("You sent a CTRL+C to interrupt the process")
+ elapsed_minutes = run_job.time_elapsed(time_start)
+ dx_logging.print_info(
+ f"{basename(__file__)} took {elapsed_minutes} " f"minutes to get this far."
+ )
if __name__ == "__main__":
- # Grab our arguments from the doc at the top of the script
- arguments = docopt(__doc__, version=basename(__file__) + " " + VERSION)
-
- # Feed our arguments to the main function, and off we go!
+ # Grab our ARGUMENTS from the doc at the top of the script
+ ARGUMENTS = docopt.docopt(__doc__, version=basename(__file__) + " " + VERSION)
+ # Feed our ARGUMENTS to the main function, and off we go!
main()
diff --git a/dx_provision_dsource.py b/dx_provision_dsource.py
index e3bb304..f510851 100755
--- a/dx_provision_dsource.py
+++ b/dx_provision_dsource.py
@@ -1,628 +1,309 @@
-#!/usr/bin/env python
-# Corey Brune - Feb 2017
-#Description:
-# Create and sync a dSource
-#
-#Requirements
-#pip install docopt delphixpy
+#!/usr/bin/env python3
+# Requirements
+# pip install docopt delphixpy
+
+# The below doc follows the POSIX compliant standards and allows us to use
+# this doc to also define our ARGUMENTS for the script.
-#The below doc follows the POSIX compliant standards and allows us to use
-#this doc to also define our arguments for the script.
"""Create and sync a dSource
Usage:
- dx_provision_dsource.py (--type )
- dx_provision_dsource.py --type --dsource_name --ip_addr --db_name --env_name --db_install_path --dx_group --db_passwd --db_user [--port_num ][--num_connections ][--link_now ][--files_per_set ][--rman_channels ]
- [--engine | --all]
- [--debug] [--parallel ] [--poll ]
- [--config ] [--logdir ]
- dx_provision_dsource.py --type --dsource_name --ase_user --ase_passwd --backup_path