Skip to content

Instantly share code, notes, and snippets.

@trepidity
Created February 11, 2020 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trepidity/5abd7bf545feafb511fbeed4cc7a91f1 to your computer and use it in GitHub Desktop.
Save trepidity/5abd7bf545feafb511fbeed4cc7a91f1 to your computer and use it in GitHub Desktop.
A script to install NetIQ Access Manager
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