Providers/nxOMSAutomationWorker/automationworker/3.x/scripts/register.py (102 lines of code) (raw):

#!/usr/bin/env python3 # ==================================== # Copyright (c) Microsoft Corporation. All rights reserved. # ==================================== """Script for registration against AzureAutomation agent service.""" import datetime as datetime import hashlib import base64 import json import hmac import socket import argparse import requests import requests.packages.urllib3 from requests.packages.urllib3.exceptions import InsecureRequestWarning from OpenSSL import crypto class AgentService: def __init__(self, endpoint, account_key, cert_path, cert_key_path, worker_group_name, machine_id): self.protocol_version = "2.0" self.endpoint = endpoint self.account_key = account_key self.cert_path = cert_path self.cert_key_path = cert_key_path self.worker_group_name = worker_group_name self.machine_id = machine_id.lower() requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # disable ssl warnings requests.packages.urllib3.disable_warnings() # disable insecure platform warning @staticmethod def encode_base64_sha256(key, msg): message = bytes(msg, encoding='utf-8') secret = bytes(key, encoding='utf-8') signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest()) return signature.decode() def compute_hmac(self, date, key, payload): sha256_hash = hashlib.sha256() sha256_hash.update(json.dumps(payload).encode()) encoded_payload = base64.b64encode(sha256_hash.digest()) str_to_sign = encoded_payload.decode() + "\n" + date # Based on AgentService contract signature = self.encode_base64_sha256(key, str_to_sign) return signature def register_worker(self): cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(self.cert_path).read()) cert_thumbprint = cert.digest("sha1").decode().replace(":", "") date = datetime.datetime.utcnow().isoformat() + "0-00:00" payload = {'RunbookWorkerGroup': self.worker_group_name, "MachineName": socket.gethostname(), "IpAddress": socket.gethostbyname(socket.gethostname()), "Thumbprint": cert_thumbprint, "Issuer": str(cert.get_issuer()), "Subject": str(cert.get_subject())} signature = self.compute_hmac(date, self.account_key, payload) header = {'Authorization': 'Shared ' + signature, 'ProtocolVersion': self.protocol_version, 'x-ms-date': date, "Content-Type": "application/json"} url = "{0}/HybridV2(MachineId='{1}')".format(self.endpoint, self.machine_id) req = requests.put(url, cert=(self.cert_path, self.cert_key_path), verify=False, headers=header, data=json.dumps(payload)) if req.status_code is not 200: print ("Agentservice : Failed to register worker. Status [{0}], Reason [{1}]".format(req.status_code, req.reason)) return print ("Agentservice : Registration complete, status [" + str(req.status_code) + "]") print ("Machine name : " + str(socket.gethostname())) print ("Machine id : " + str(self.machine_id)) print ("Worker group name : " + str(self.worker_group_name)) print ("Certificate thumbprint : " + str(cert_thumbprint)) def deregister_worker(self): cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(self.cert_path).read()) cert_thumbprint = cert.digest("sha1").decode().replace(":", "") date = datetime.datetime.utcnow().isoformat() + "0-00:00" payload = {"Thumbprint": cert_thumbprint, "Issuer": str(cert.get_issuer()), "Subject": str(cert.get_subject())} signature = self.compute_hmac(date, self.account_key, payload) header = {'Authorization': 'Shared ' + signature, 'ProtocolVersion': self.protocol_version, 'x-ms-date': date, "Content-Type": "application/json"} url = "{0}/Hybrid(MachineId='{1}')".format(self.endpoint, self.machine_id) req = requests.delete(url, cert=(self.cert_path, self.cert_key_path), verify=False, headers=header, data=json.dumps(payload)) if req.status_code is not 200: print ("Agent service : Failed to de-register worker. Status [{0}], Reason [{1}]".format(req.status_code, req.reason)) return print ("Agent service : De-registration complete, status [" + str(req.status_code) + "]") def main(): parser = argparse.ArgumentParser() parser.add_argument('-url', help='Registration url', required=True) parser.add_argument('-accountkey', help='Automation account key', required=True) parser.add_argument('-workergroupname', help='worker group name', required=True) parser.add_argument('-cert', help='Certificate file path', required=True) parser.add_argument('-key', help='Private key file path', required=True) parser.add_argument('-machineid', help='Machine id', required=True) group = parser.add_mutually_exclusive_group(required=True) group.add_argument('--register', action='store_true', help='Register the worker') group.add_argument('--deregister', action='store_true', help='De-register the worker') args = parser.parse_args() agent = AgentService(args.url, args.accountkey, args.cert, args.key, args.workergroupname, args.machineid) if args.register: agent.register_worker() elif args.deregister: agent.deregister_worker() if __name__ == "__main__": main()