Created
February 11, 2020 17:34
-
-
Save trepidity/5abd7bf545feafb511fbeed4cc7a91f1 to your computer and use it in GitHub Desktop.
A script to install NetIQ Access Manager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
import boto3 | |
import botocore | |
import os | |
import shutil | |
import tarfile | |
import subprocess | |
import sys | |
import argparse | |
import io | |
import hashlib | |
import re | |
import zipfile | |
try: | |
input = raw_input | |
except NameError: | |
pass | |
parser = argparse.ArgumentParser(description='A tool to download and run net-iq installers') | |
parser.add_argument('--download-dir', default="/tmp/nam-downloader", | |
help='where to download the installer to') | |
parser.add_argument('--aws-access-key-id', default=None) | |
parser.add_argument('--aws-secret-access-key', default=None) | |
parser.add_argument('--dry-run', default=False, action="store_const", const=True, | |
help="download and extract the tarfile, but don't run the script") | |
parser.add_argument('--list-versions', default=False, action="store_const", const=True, | |
help="list the versions available but don't download") | |
parser.add_argument('--version', default="interactive", | |
help="which version to install, 'interactive' for a prompt") | |
parser.add_argument('--bucket-name', default='access-manager-installation-media' ) | |
parser.add_argument('--no-sign-request', default=False, action="store_const", const=True, | |
help="don't sign with AWS credentials, allows access to anonymous buckets") | |
parser.add_argument('--ignore-sha', default=False, action="store_const", const=True) | |
parser.add_argument('type', metavar="TYPE", choices=['idp','lag','admin', 'patch'], | |
help="type to attempt: 'idp', 'lag', 'admin', or 'patch'") | |
parser.add_argument('--install', default=False, action="store_const", const=True, | |
help="install the new tool, don't upgrade existing version") | |
parser.add_argument('--upgrade', default=False, action="store_const", const=True, | |
help="upgrade the tool") | |
parser.add_argument('--dont-detect-installed', default=False, action="store_const", const=True, | |
help="don't use rpm to detect if the tool is already installed") | |
args = parser.parse_args() | |
install_upgrade_prefix = "" | |
install_suffix = "install.sh" | |
upgrade_suffix = "upgrade.sh" | |
if args.type == 'idp' or args.type == 'admin': | |
keyword = "ManagerService" | |
install_upgrade_prefix = "" | |
elif args.type == 'lag': | |
keyword = "GatewayService" | |
install_upgrade_prefix = "ag_" | |
install_filename = install_upgrade_prefix + install_suffix | |
upgrade_filename = install_upgrade_prefix + upgrade_suffix | |
rpm_names = { | |
'lag': 'novell-apache-gateway', | |
'idp': 'novell-nidp-server', | |
'admin': 'novell-amservice', | |
} | |
boto_config = None | |
if args.no_sign_request: | |
boto_config = botocore.config.Config(signature_version=botocore.UNSIGNED) | |
s3 = boto3.client( | |
's3', | |
config=boto_config, | |
aws_access_key_id=args.aws_access_key_id, | |
aws_secret_access_key=args.aws_secret_access_key, | |
) | |
patch_match = re.compile("^patch/(.*)\.zip$") | |
def list_options(client): | |
if args.type == "patch": | |
return [patch_match.match(entry["Key"]).group(1) | |
for entry in client.list_objects(Bucket=args.bucket_name, Prefix="patch")["Contents"] | |
if entry["Key"].endswith(".zip")] | |
else: | |
return [option | |
for option in (o["Prefix"].strip("/") for o in | |
client.list_objects(Bucket=args.bucket_name, Delimiter="/")["CommonPrefixes"]) | |
if option != "patch"] | |
def download(client, file, sub_dir): | |
if os.path.exists(os.path.join(args.download_dir, sub_dir)): | |
shutil.rmtree(os.path.join(args.download_dir, sub_dir)) | |
if not os.path.exists(os.path.join(args.download_dir)): | |
os.mkdir(os.path.join(args.download_dir)) | |
working_dir = os.path.join(args.download_dir, sub_dir) | |
os.mkdir(working_dir) | |
tar_path = os.path.join(args.download_dir, file) | |
sha_file = file + ".sha" | |
sha_expected = None | |
try: | |
sha_io = io.BytesIO() | |
client.download_fileobj(args.bucket_name, sha_file, sha_io) | |
sha_expected = sha_io.getvalue().strip() | |
except botocore.exceptions.ClientError: | |
pass | |
with open(tar_path, 'wb') as data: | |
client.download_fileobj(args.bucket_name, file, data) | |
sha = hashlib.sha256() | |
with open(tar_path, 'rb') as f: | |
while True: | |
data = f.read(1024 << 3) | |
if not data: | |
break | |
sha.update(data) | |
if not args.ignore_sha and sha_expected is not None: | |
sha_true = sha.hexdigest() | |
if sha_expected != sha_true: | |
print("Invalid SHA (add --ignore-sha to bypass)") | |
print("Expecting: {}".format(sha_expected)) | |
print("Computed: {}".format(sha_true)) | |
sys.exit() | |
return tar_path, working_dir | |
def install_or_upgrade_filename(): | |
if args.install: | |
return install_filename | |
if args.upgrade: | |
return upgrade_filename | |
if args.dont_detect_installed: | |
if "u" == input("install or upgrade? (I/u)").lower(): | |
return upgrade_filename | |
else: | |
return install_filename | |
rpm_query = subprocess.Popen(['rpm', '-q', rpm_names[args.type]], stdout=subprocess.PIPE) | |
stdout, stderr = rpm_query.communicate() | |
if stdout.strip() != "": | |
return upgrade_filename | |
else: | |
return install_filename | |
def choose_option(client, choice): | |
prefix = choice+"/" | |
try: | |
files = [entry["Key"] | |
for entry in client.list_objects(Bucket=args.bucket_name, Prefix=prefix)["Contents"] | |
if keyword in entry["Key"]] | |
except KeyError: | |
files = [] | |
if len(files) < 1: | |
print("missing NetIQ install files in bucket") | |
sys.exit() | |
files = [f for f in files if not f.endswith(".sha")] | |
if len(files) > 1: | |
print("too many files in dir:") | |
for file in files: | |
print(" ", file) | |
sys.exit() | |
file = files[0] | |
tar_path, working_dir = download(client, file, choice) | |
with tarfile.open(tar_path) as tar: | |
os.chdir(working_dir) | |
print("cd {}".format(working_dir)) | |
tar.extractall() | |
filename = install_or_upgrade_filename() | |
for tarinfo in tar: | |
if tarinfo.isreg() and tarinfo.name.split("/")[-1] == filename: | |
cmd = ["sudo", "bash", tarinfo.name] | |
print(" ".join(cmd)) | |
if not args.dry_run: | |
subprocess.call(cmd) | |
def do_patch(client, choice): | |
zip_path, working_dir = download(client, "patch/{}.zip".format(choice), "patch") | |
with zipfile.ZipFile(zip_path) as zip: | |
os.chdir(working_dir) | |
print("cd {}".format(working_dir)) | |
zip.extractall() | |
cmd = ["sudo", "bash", "{}/installPatch.sh".format(choice)] | |
print(" ".join(cmd)) | |
if not args.dry_run: | |
subprocess.call(cmd) | |
if args.list_versions: | |
for option in list_options(s3): | |
print(option) | |
else: | |
if args.version == "interactive": | |
for option in list_options(s3): | |
print(option) | |
args.version = input("Enter a version: ") | |
if args.type == "patch": | |
do_patch(s3, args.version) | |
else: | |
choose_option(s3, args.version) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment