def __call__(self, *args, **kwargs): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: req = api.tm.ltm.nodes.node.load( name=node.name, partition=node.partition ) req.delete()
def delete_app(self, app_name, policy_name, partition='Common'): pool_name = "%s_pool" % (app_name) monitor_name = "%s_monitor" % (app_name) monitor_path = "/%s/%s" % (partition, monitor_name) with TransactionContextManager(self.tx) as api: api._meta_data['icr_session'].session.headers[ 'X-F5-REST-Coordination-Id'] = api._meta_data[ 'icr_session'].session.headers[ 'X-F5-REST-Coordination-Id'].__str__() policy = api.tm.ltm.policys.policy.load(name=policy_name, partition=partition) my_rule = policy.rules_s.rules.load(name=app_name) my_rule.delete() print "Deleted policy rule %s" % (app_name) pool_path = "/%s/%s" % (partition, pool_name) pool = api.tm.ltm.pools.pool.load(partition=partition, name=pool_name) pool.delete() print "Deleted pool %s" % pool_path monitor = api.tm.ltm.monitor.https.http.load(name=monitor_name, partition=partition) monitor.delete() print "Deleted monitor %s" % (monitor_path)
def update_crypto(self, name, cert, key, chain, cert_chain_name): """updated certificate and key :param name: domain name :type name: string :param cert: certificate filename :type cert: string :param key: key filename :type key: string :param chain: chain filename :type chain: string :param cert_chain_name: chain name :type cert_chain_name: string :raises BigIpCertStorageError: something went wrong accessing the file to the BIG-IP """ # Because they exist, we will modify them in a transaction try: tx = self.mgmt.tm.transactions.transaction with TransactionContextManager(tx) as api: self._update_crypto_key(api, key, name) self._update_crypto_cert(api, cert, name) self._update_crypto_cert(api, chain, cert_chain_name) except Exception as e: raise BigIpCertStorageError(self.active_device, e)
def delete_virtual_address_from_device(self): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: address = api.tm.ltm.virtual_address_s.virtual_address.load( name=self.params['address'], partition=self.params['partition']) address.delete()
def update_virtual_address_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: address = api.tm.ltm.virtual_address_s.virtual_address.load( name=self.params['address'], partition=self.params['partition']) address.modify(**params)
def update_snat_pool_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: r = api.tm.ltm.snatpools.snatpool.load( name=self.params['name'], partition=self.params['partition'] ) r.modify(**params)
def delete_snat_pool_from_device(self): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: pool = api.tm.ltm.snatpools.snatpool.load( name=self.params['name'], partition=self.params['partition'] ) pool.delete()
def create_on_device(self): params = self.want.api_params() tx = self.client.api.tm.transactions.transaction with TransactionContextManager(tx) as api: params = dict(name=self.want.name, partition=self.want.partition, **params) resource = api.tm.ltm.policys.policy.create(**params) self._upsert_policy_rules_on_device(resource) return True
def delete_user_from_device(self): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: if self.is_version_less_than_13(): user = api.tm.auth.users.user.load( name=self.params['username_credential']) user.delete() else: user = api.tm.auth.users.user.load( name=self.params['username_credential'], partition=self.params['partition']) user.delete()
def update_user_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: if self.is_version_less_than_13(): r = api.tm.auth.users.user.load( name=self.params['username_credential']) r.modify(**params) else: r = api.tm.auth.users.user.load( name=self.params['username_credential'], partition=self.params['partition']) r.modify(**params)
def update_on_device(self): params = self.changes.api_params() # Using a transaction because the rule ordering cannot be changed # by just patching the policy endpoint. You instead need to patch # each of the rule endpoints. tx = self.client.api.tm.transactions.transaction with TransactionContextManager(tx) as api: resource = api.tm.ltm.policys.policy.load( name=self.want.name, partition=self.want.partition) if params: resource.modify(**params) self._upsert_policy_rules_on_device(resource)
def provision_dedicated_on_device(self): params = self.want.api_params() tx = self.client.api.tm.transactions.transaction collection = self.client.api.tm.sys.provision.get_collection() resources = [x['name'] for x in collection if x['name'] != self.want.module] with TransactionContextManager(tx) as api: provision = api.tm.sys.provision for resource in resources: resource = getattr(provision, resource) resource = resource.load() resource.update(level='none') resource = getattr(provision, self.want.module) resource = resource.load() resource.update(**params)
def ensure_hostname_is_present(self): self.changed_params['hostname'] = self.params['hostname'] if self.params['check_mode']: return True tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: r = api.tm.sys.global_settings.load() r.update(hostname=self.params['hostname']) if self.hostname_exists(): return True else: raise F5ModuleError("Failed to set the hostname")
def delete(self): changed = False check_mode = self.params['check_mode'] delete_cert = self.cert_exists() delete_key = self.key_exists() if not delete_cert and not delete_key: return changed if check_mode: params = dict() params['cert_name'] = name params['key_name'] = name params['partition'] = partition self.cparams = params return True tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: if delete_cert: # Delete the certificate c = api.tm.sys.file.ssl_certs.ssl_cert.load( name=self.params['name'], partition=self.params['partition'] ) c.delete() changed = True if delete_key: # Delete the certificate key k = self.api.tm.sys.file.ssl_keys.ssl_key.load( name=self.params['name'], partition=self.params['partition'] ) k.delete() changed = True return changed
def update_sys_global_settings_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: r = api.tm.sys.global_settings.load() r.update(**params)
def create_app(self, app_name, pool_members, policy_name, partition='Common'): pool_name = "%s_pool" % (app_name) monitor_name = "%s_monitor" % (app_name) send_str = "GET /env/VCAP_APPLICATION HTTP/1.1\\r\\nhost: %s\\r\\nconnection:close\\r\\n\\r\\n" % ( app_name) recv_str = app_name monitor_path = "/%s/%s" % (partition, monitor_name) with TransactionContextManager(self.tx) as api: api._meta_data['icr_session'].session.headers[ 'X-F5-REST-Coordination-Id'] = api._meta_data[ 'icr_session'].session.headers[ 'X-F5-REST-Coordination-Id'].__str__() # sys.exit(0) monitor = api.tm.ltm.monitor.https.http.create(name=monitor_name, partition=partition, interval=10, timeout=31, send=send_str, recv=recv_str) pool_path = "/%s/%s" % (partition, pool_name) pool = api.tm.ltm.pools.pool.create(partition=partition, name=pool_name, minActiveMembers=1, monitor=monitor_name) print "Created pool %s" % pool_path member_list = pool_members.split(',') member_list.reverse() priority_group = 0 for member in member_list: pool._meta_data['uri'] = pool._meta_data['uri'].split( "/transaction/")[0] + "/ltm/pool/~%s~%s/" % (partition, pool_name) pool_member = pool.members_s.members.create( partition=partition, name=member, priorityGroup=priority_group) priority_group += 10 print " Added member %s" % member policy = api.tm.ltm.policys.policy.load(name=policy_name, partition=partition) rules = policy.rules_s.get_collection() my_rule = policy.rules_s.rules.create(name=app_name) payload = { u'caseInsensitive': True, u'equals': True, u'external': True, u'fullPath': u'0', u'host': True, u'httpHost': True, u'index': 0, u'name': u'0', u'present': True, u'remote': True, u'request': True, u'values': [app_name] } my_rule._meta_data[ 'uri'] = policy._meta_data['uri'] + 'rules/' + app_name + '/' my_rule.conditions_s.conditions.create(**payload) payload = { "vlanId": 0, "forward": True, "code": 0, "fullPath": "0", "name": "0", "pool": pool_name, "request": True, "select": True, "status": 0 } my_rule.actions_s.actions.create(**payload) print "Created policy rule %s" % (app_name)
def f5_cert_deployer(b_mg, b_vs_name, b_vs_ip, b_part, b_vlan, b_http_prof, b_ssl_prof, b_vs_port, *args): domain = args[0][2] key = args[0][3] cert = args[0][4] chain = args[0][5] # Upload files b_mg.shared.file_transfer.uploads.upload_file(key) b_mg.shared.file_transfer.uploads.upload_file(cert) b_mg.shared.file_transfer.uploads.upload_file(chain) # Check to see if these already exist key_status = b_mg.tm.sys.file.ssl_keys.ssl_key.exists(name=domain + ".key") cert_status = b_mg.tm.sys.file.ssl_certs.ssl_cert.exists(name=domain + ".crt") chain_status = b_mg.tm.sys.file.ssl_certs.ssl_cert.exists( name='le-chain.crt') if key_status and cert_status and chain_status: # Because they exist, we will modify them in a transaction tx = b_mg.tm.transactions.transaction with TransactionContextManager(tx) as api: modkey = api.tm.sys.file.ssl_keys.ssl_key.load(name=domain + ".key") modkey.sourcePath = 'file:/var/config/rest/downloads/%s' % ( os.path.basename(key)) modkey.update() modcert = api.tm.sys.file.ssl_certs.ssl_cert.load(name=domain + ".crt") modcert.sourcePath = 'file:/var/config/rest/downloads/%s' % ( os.path.basename(cert)) modcert.update() modchain = api.tm.sys.file.ssl_certs.ssl_cert.load( name='le-chain.crt') modchain.sourcePath = 'file:/var/config/rest/downloads/%s' % ( os.path.basename(chain)) modchain.update() else: newkey = b_mg.tm.sys.file.ssl_keys.ssl_key.create( name=domain + ".key", sourcePath='file:/var/config/rest/downloads/%s' % (os.path.basename(key))) newcert = b_mg.tm.sys.file.ssl_certs.ssl_cert.create( name=domain + ".crt", sourcePath='file:/var/config/rest/downloads/%s' % (os.path.basename(cert))) newchain = b_mg.tm.sys.file.ssl_certs.ssl_cert.create( name='le-chain.crt', sourcePath='file:/var/config/rest/downloads/%s' % (os.path.basename(chain))) certKeyChain = { 'certKeyChain': [{ 'name': domain, 'defaultsFrom': '/Common/lorx_client_ssl', 'cert': "/" + b_part + "/" + domain + ".crt", 'key': "/" + b_part + "/" + domain + ".key", 'chain': "/" + b_part + "/le-chain.crt" }] } if not (b_mg.tm.ltm.virtuals.virtual.exists(name=b_vs_name, partition=b_part)): b_mg.tm.ltm.virtuals.virtual.create( name=b_vs_name, partition=b_part, destination=b_vs_ip + ':' + b_vs_port, sourceAddressTranslation={'type': "automap"}, mask='255.255.255.255', vlans=[b_vlan], profiles=[{ 'name': b_http_prof }]) if not (b_mg.tm.ltm.profile.client_ssls.client_ssl.exists( name=b_ssl_prof, partition=b_part)): b_mg.tm.ltm.profile.client_ssls.client_ssl.create(name=b_ssl_prof, partition=b_part) vs = b_mg.tm.ltm.virtuals.virtual.load(name=b_vs_name, partition=b_part) ssl_prof = b_mg.tm.ltm.profile.client_ssls.client_ssl.load( name=b_ssl_prof, partition=b_part) ssl_prof.modify(**certKeyChain) prof = vs.profiles_s.profiles.create(name=ssl_prof, partition=b_part) else: vs = b_mg.tm.ltm.virtuals.virtual.load(name=b_vs_name, partition=b_part) prof = vs.profiles_s.profiles.create(name=b_ssl_prof, partition=b_part) with TransactionContextManager(s1) as api1: print("attach ssl prof") ssl_prof = api1.tm.ltm.profile.client_ssls.client_ssl.load( name=b_ssl_prof, partition=b_part) ssl_prof.modify(**certKeyChain) prof = vs.profiles_s.profiles.create(name=b_ssl_prof, partition=b_part) else: if not (b_mg.tm.ltm.profile.client_ssls.client_ssl.exists( name=b_ssl_prof, partition=b_part)): ssl_prof = b_mg.tm.ltm.profile.client_ssls.client_ssl.create( name=b_ssl_prof, partition=b_part) ssl_prof.modify(**certKeyChain) vs = b_mg.tm.ltm.virtuals.virtual.load(name=b_vs_name, partition=b_part) prof = vs.profiles_s.profiles.create(name=b_ssl_prof, partition=b_part) else: try: #for virt in b_mg.tm.ltm.virtuals.get_collection(): vs = b_mg.tm.ltm.virtuals.virtual.load(name=b_vs_name, partition=b_part) ssl_profs = vs.profiles_s.get_collection() for i in range(len(ssl_profs)): profs_list = [] profs_list = profs_list.append(ssl_profs[i].name) print(ssl_profs[i].name) # print(str(ssl_profs[i].name)) if (str(ssl_profs[i].name) == b_ssl_prof): print(str(ssl_profs[i].name)) ssl_profs.modify(**certKeyChain) break else: if vs.profiles_s.profiles.exists(name=b_ssl_prof, partition=b_part): break else: s1 = b_mg.tm.transactions.transaction with TransactionContextManager(s1) as api1: print("else run") ssl_prof = api1.tm.ltm.profile.client_ssls.client_ssl.load( name=b_ssl_prof, partition=b_part) ssl_prof.modify(**certKeyChain) vs = api1.tm.ltm.virtuals.virtual.load( name=b_vs_name, partition=b_part) prof = vs.profiles_s.profiles.create( name=b_ssl_prof, partition=b_part) except Exception as err: print(err)
def present(self): params = dict() current = self.read() # Temporary locations to hold the changed params update = dict( dns=None, forwarders=None, cache=None ) nameservers = self.params['name_servers'] search_domains = self.params['search'] ip_version = self.params['ip_version'] forwarders = self.params['forwarders'] cache = self.params['cache'] check_mode = self.params['check_mode'] if nameservers: if 'name_servers' in current: if nameservers != current['name_servers']: params['nameServers'] = nameservers else: params['nameServers'] = nameservers if search_domains: if 'search' in current: if search_domains != current['search']: params['search'] = search_domains else: params['search'] = search_domains if ip_version: if 'ip_version' in current: if ip_version != int(current['ip_version']): if ip_version == 6: params['include'] = 'options inet6' elif ip_version == 4: params['include'] = '' else: if ip_version == 6: params['include'] = 'options inet6' elif ip_version == 4: params['include'] = '' if params: self.cparams.update(camel_dict_to_snake_dict(params)) if 'include' in params: del self.cparams['include'] if params['include'] == '': self.cparams['ip_version'] = 4 else: self.cparams['ip_version'] = 6 update['dns'] = params.copy() params = dict() if forwarders: if 'forwarders' in current: if forwarders != current['forwarders']: params['forwarders'] = forwarders else: params['forwarders'] = forwarders if params: self.cparams.update(camel_dict_to_snake_dict(params)) update['forwarders'] = ' '.join(params['forwarders']) params = dict() if cache: if 'cache' in current: if cache != current['cache']: params['cache'] = cache if params: self.cparams.update(camel_dict_to_snake_dict(params)) update['cache'] = params['cache'] params = dict() if self.cparams: changed = True if check_mode: return changed else: return False tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: cache = api.tm.sys.dbs.db.load(name='dns.cache') proxy = api.tm.sys.dbs.db.load(name='dns.proxy.__iter__') dns = api.tm.sys.dns.load() # Empty values can be supplied, but you cannot supply the # None value, so we check for that specifically if update['cache'] is not None: cache.update(value=update['cache']) if update['forwarders'] is not None: proxy.update(value=update['forwarders']) if update['dns'] is not None: dns.update(**update['dns']) return changed
def update_iapp_template_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: r = api.tm.sys.application.templates.template.load( name=self.params['name'], partition=self.params['partition']) r.actions.modify(**params)
def new_vs_build2(active_ltm, vs_dnsname, vs_dest, vs_port, vs_desc, vs_env, vs_tcpprofile, vs_persistence, vs_redirect, vs_type, vs_httpprofile, vs_sslclient, vs_sslserver, vs_irule, vs_snatpool, vs_policy, vs_poolname): admpass = getpass.getpass('LTM', 'admin') mr = ManagementRoot(str(active_ltm), 'admin', admpass) # Check if Standard naming is used useGlobalNaming = loadStdNames.useStdNaming() logger.info("new_vs_build2()- Use Standard Global naming : " + useGlobalNaming ) idx = 1 strReturn = {str(idx) : 'VS Creation Report'} idx += 1 logger.info(str(active_ltm) + " VS DNS:" + str(vs_dnsname) + " VS DEST:" + str(vs_dest) + " VS PORT:" + str(vs_port) + " VS DESC:" + str(vs_desc) + " VS Env.:" + str(vs_env) + " VS TCP Prf:" + str(vs_tcpprofile) + " VS Persist:" + str(vs_persistence) + " VS Redirect:" + str(vs_redirect) + " VS Type:" + str(vs_type) + " VS HTTP Prf:" + str(vs_httpprofile) + " VS Clientssl:" + str(vs_sslclient) + " VS Serverssl:" + str(vs_sslserver) + " VS iRule: " + str(vs_irule) + " VS SNATPOOL: " + str(vs_snatpool) + " VS Policy: " + str(vs_policy) + " VS Pool Name: " + str(vs_poolname) ) logger.info("Before VS Build - Env Name: " + str(vs_env) + " DNS name: " + str(vs_dnsname) + " Port: " + str(vs_port)) if useGlobalNaming == '1': std_vsname = loadStdNames.get_std_name(active_ltm, 'LOCAL', 'VIRTUAL_SERVER', '', vs_dnsname) else: std_vsname = str(vs_dnsname) #std_vsname = build_std_names.build_std_vs_name(str(vs_env), str(vs_dnsname), str(vs_port)) #std_poolname = build_std_names.build_std_pool_name(str(vs_env), str(vs_dnsname), str(vs_port)) logger.info("VS Creation process has been initiated. VS Name: " + std_vsname) try: fieldNames = {"name":std_vsname, "description":vs_desc, "ip":vs_dest, "port":vs_port, "ipProtocol":"tcp", "pool":vs_poolname, \ "protocolProfileClient":vs_tcpprofile, "httpProfile":vs_httpprofile, "oneConnectProfile":"none", "sslProfileClient":vs_sslclient, \ "sslProfileServer":vs_sslserver, "rules":vs_irule, "sourceAddressTranslation":vs_snatpool, "persistence":vs_persistence, "policies":vs_policy} logger.info("Protocol Profile: " + fieldNames["protocolProfileClient"] + " HTTP Profie: " + fieldNames["httpProfile"] + \ " SSL Client Profile: " + fieldNames["sslProfileClient"] + " SSL Server Profile: " + fieldNames["sslProfileServer"] + \ " iRule: " + fieldNames["rules"] + " Persistence: " + fieldNames["persistence"] + " Policy: " + fieldNames["policies"]) myvirtual = mr.tm.ltm.virtuals.virtual.create(name=fieldNames["name"], description=fieldNames["description"], \ destination="%s:%s" % (fieldNames["ip"], fieldNames["port"]), ipProtocol=fieldNames["ipProtocol"], \ pool=fieldNames["pool"]) # Create the profiles. When a virtual server is created which has a TCP # base protocol then it is automatically assigned the base "tcp" profile. # This profile cannot be removed without assigning some other TCP profile. # To do this you have to wrap the deletion of the "tcp" profile and the # creation of the of the other TCP profile in a transaction. tx = mr.tm.transactions.transaction with TransactionContextManager(tx) as api: profiles = myvirtual.profiles_s if fieldNames["protocolProfileClient"] != "none": p1 = profiles.profiles.load(partition="Common",name="tcp") p1.delete() myvirtual.profiles_s.profiles.create(partition="Common", name=fieldNames["protocolProfileClient"]) if fieldNames["httpProfile"] != "none": myvirtual.profiles_s.profiles.create(partition="Common", name=fieldNames["httpProfile"]) if fieldNames["oneConnectProfile"] != "none": myvirtual.profiles_s.profiles.create(partition="Common", name=fieldNames["oneConnectProfile"]) if fieldNames["sslProfileClient"] != "none": myvirtual.profiles_s.profiles.create(partition="Common", name=fieldNames["sslProfileClient"]) if fieldNames["sslProfileServer"] != "none": myvirtual.profiles_s.profiles.create(partition="Common", name=fieldNames["sslProfileServer"]) strReturn[str(idx)] = 'Protocol/HTTP/OneConnect/Client and Server SSL Profile has been updated' idx += 1 # Update the virtual server with the iRules. The iRules have to be a list. if fieldNames["rules"] != 'none': rules = [] for rule in fieldNames["rules"].split(): rules.append(rule) myvirtual.rules = rules myvirtual.update() # Update the virtual server with the Snatpool. The Snatpool have to be a dictionary. # When you add snatpool to a Virtual Server during Virtual Server creation, BIG-IP takes 'snatpool'. # However when you need to update snatpool with a specific virtual server, you should use 'sourceAddressTranslation' with dictionary format. if fieldNames["sourceAddressTranslation"] != 'none': vssnatpool = {'pool':'', 'type':'snat'} vssnatpool['pool'] = '/Common/' + fieldNames["sourceAddressTranslation"] myvirtual.sourceAddressTranslation = vssnatpool myvirtual.update() # Update the virtual server with the persistence profile. The iRules # have to be a list. But we will never have more than one. if fieldNames["persistence"] != 'none': persistence = [] for persistenceProfile in fieldNames["persistence"].split(): persistence.append(persistenceProfile) myvirtual.persist = persistence myvirtual.update() # Update the virtual server with the policy. policies = myvirtual.policies_s if fieldNames["policies"] != 'none': myvirtual.policies_s.policies.create(partition="Common", name=fieldNames["policies"]) strReturn[str(idx)] = 'iRule/Persistence/SnatPool/Policy Profile has been updated' idx += 1 strReturn[str(idx)] = 'Requested Virtual Server (' + std_vsname + ') has been succssfully created' idx += 1 except Exception as e: logger.info("Exception during Virtual Server creation-update") strReturn[str(idx)] = "Exception fired!: " + str(e) idx += 1 logger.info("Virtual Server creation-update exception fired: " + str(e)) return json.dumps(strReturn) return json.dumps(strReturn)
mr.shared.file_transfer.uploads.upload_file(key) mr.shared.file_transfer.uploads.upload_file(cert) mr.shared.file_transfer.uploads.upload_file(chain) # Check to see if these already exist key_status = mr.tm.sys.file.ssl_keys.ssl_key.exists( name='{0}.key'.format(domain)) cert_status = mr.tm.sys.file.ssl_certs.ssl_cert.exists( name='{0}.crt'.format(domain)) chain_status = mr.tm.sys.file.ssl_certs.ssl_cert.exists(name='le-chain.crt') if key_status and cert_status and chain_status: # Because they exist, we will modify them in a transaction tx = mr.tm.transactions.transaction with TransactionContextManager(tx) as api: modkey = api.tm.sys.file.ssl_keys.ssl_key.load( name='{0}.key'.format(domain)) modkey.sourcePath = 'file:/var/config/rest/downloads/{0}'.format( os.path.basename(key)) modkey.update() modcert = api.tm.sys.file.ssl_certs.ssl_cert.load( name='{0}.crt'.format(domain)) modcert.sourcePath = 'file:/var/config/rest/downloads/{0}'.format( os.path.basename(cert)) modcert.update() modchain = api.tm.sys.file.ssl_certs.ssl_cert.load(name='le-chain.crt') modchain.sourcePath = 'file:/var/config/rest/downloads/{0}'.format( os.path.basename(chain))
def create_virtual_address_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: api.tm.ltm.virtual_address_s.virtual_address.create(**params)
def create_user_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: api.tm.auth.users.user.create(**params)
def present(self): current = self.read() changed = False do_key = False do_cert = False chash = None khash = None check_mode = self.params['check_mode'] name = self.params['name'] partition = self.params['partition'] cert_content = self.params['cert_content'] key_content = self.params['key_content'] passphrase = self.params['passphrase'] # Technically you dont need to provide us with anything in the form # of content for your cert, but that's kind of illogical, so we just # return saying you didn't "do" anything if you left the cert and keys # empty. if not cert_content and not key_content: return False if key_content is not None: if 'key_checksum' in current: khash = self.get_hash(key_content) if khash not in current['key_checksum']: do_key = "update" else: do_key = "create" if cert_content is not None: if 'cert_checksum' in current: chash = self.get_hash(cert_content) if chash not in current['cert_checksum']: do_cert = "update" else: do_cert = "create" if do_cert or do_key: changed = True params = dict() params['cert_name'] = name params['key_name'] = name params['partition'] = partition if khash: params['key_checksum'] = khash if chash: params['cert_checksum'] = chash self.cparams = params if check_mode: return changed if not do_cert and not do_key: return False tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: if do_cert: # Upload the content of a certificate as a StringIO object cstring = StringIO.StringIO(cert_content) filename = "%s.crt" % (name) filepath = os.path.join(self.dlpath, filename) api.shared.file_transfer.uploads.upload_stringio( cstring, filename ) if do_cert == "update": # Install the certificate params = { 'name': name, 'partition': partition } cert = api.tm.sys.file.ssl_certs.ssl_cert.load(**params) # This works because, while the source path is the same, # calling update causes the file to be re-read cert.update() changed = True elif do_cert == "create": # Install the certificate params = { 'sourcePath': "file://" + filepath, 'name': name, 'partition': partition } api.tm.sys.file.ssl_certs.ssl_cert.create(**params) changed = True if do_key: # Upload the content of a certificate key as a StringIO object kstring = StringIO.StringIO(key_content) filename = "%s.key" % (name) filepath = os.path.join(self.dlpath, filename) api.shared.file_transfer.uploads.upload_stringio( kstring, filename ) if do_key == "update": # Install the key params = { 'name': name, 'partition': partition } key = api.tm.sys.file.ssl_keys.ssl_key.load(**params) params = dict() if passphrase: params['passphrase'] = passphrase else: params['passphrase'] = None key.update(**params) changed = True elif do_key == "create": # Install the key params = { 'sourcePath': "file://" + filepath, 'name': name, 'partition': partition } if passphrase: params['passphrase'] = self.params['passphrase'] else: params['passphrase'] = None api.tm.sys.file.ssl_keys.ssl_key.create(**params) changed = True return changed
def create_iapp_template_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: api.tm.sys.application.templates.template.create(**params)
def chg_vs_ajax(active_ltm, vs_name, vs_dest, vs_port, vs_desc, vs_tcpprofile, vs_persistence, vs_type, vs_httpprofile, vs_sslclient, vs_sslserver, vs_irule, vs_snatpool, vs_policy, vs_poolname): logger.info("chg_vs_ajax Head") admpass = getpass.getpass('LTM', 'admin') mr = ManagementRoot(str(active_ltm), 'admin', admpass) idx = 1 strReturn = {str(idx): 'VS Modification Report'} idx += 1 logger.info("Logger - Before VS Modification" + str(active_ltm) + " VS DNS:" + str(vs_name) + " VS DEST:" + str(vs_dest) + " VS PORT:" + str(vs_port) + " VS DESC:" + str(vs_desc) + " VS TCP Prf:" + str(vs_tcpprofile) + " VS Persist:" + str(vs_persistence) + " VS Type:" + str(vs_type) + " VS HTTP Prf:" + str(vs_httpprofile) + " VS Clientssl:" + str(vs_sslclient) + " VS Serverssl:" + str(vs_sslserver) + " VS iRule: " + str(vs_irule) + " VS SNATPOOL: " + str(vs_snatpool) + " VS Policy: " + str(vs_policy) + " VS Pool Name: " + str(vs_poolname)) logger.info("VS Modification process has been initiated.") try: # fieldNames = VS properties collected from CHAN-IQ GUI fieldNames = {"name":vs_name, "description":vs_desc, "ip":vs_dest, "port":vs_port, "ipProtocol":"tcp", "pool":vs_poolname, \ "protocolProfileClient":vs_tcpprofile, "httpProfile":vs_httpprofile, "oneConnectProfile":"none", "sslProfileClient":vs_sslclient, \ "sslProfileServer":vs_sslserver, "rules":vs_irule, "sourceAddressTranslation":vs_snatpool, "persistence":vs_persistence, "policies":vs_policy} logger.info("Protocol Profile: " + fieldNames["protocolProfileClient"] + " HTTP Profie: " + fieldNames["httpProfile"] + \ " SSL Client Profile: " + fieldNames["sslProfileClient"] + " SSL Server Profile: " + fieldNames["sslProfileServer"] + \ " iRule: " + fieldNames["rules"] + " Persistence: " + fieldNames["persistence"] + " Policy: " + fieldNames["policies"]) loaded_vs = mr.tm.ltm.virtuals.virtual.load(name=fieldNames["name"], partition="Common") # Get profile names from the loaded virtual server of a target BIG-IP device loaded_prf_names = {'name':'','description':'', 'ip':'', 'port':'', 'ipProtocol':'tcp','pool':'none', 'protocolProfileClient':'tcp', 'httpProfile':'none', \ 'oneConnectProfile':'none', 'sslProfileClient':'none', 'sslProfileServer':'none', 'rules':'none', 'sourceAddressTranslation':'none', \ 'persistence':'none', 'policies':'none'} get_vsconfig(mr, fieldNames['name'], 'Common', loaded_prf_names) if not Dicts_Not_Equal(loaded_prf_names, fieldNames): logger.info("Two dictionaries are SAME - No change is needed") strReturn = {str(idx): 'No change is needed'} idx += 1 return json.dumps(strReturn) # Print loaded vs config logger.info( "====== Printing BIG-IP loaded configuration names after return ======" ) for k, v in loaded_prf_names.items(): logger.info('Key: ' + k + ' Value: ' + v) logger.info( "====== Printing GUI configuration names after return ======") for k, v in fieldNames.items(): logger.info('Key: ' + k + ' Value: ' + v) # Create the profiles. When a virtual server is created which has a TCP # base protocol then it is automatically assigned the base 'tcp' profile. # This profile cannot be removed without assigning some other TCP profile. # To do this you have to wrap the deletion of the 'tcp' profile and the # creation of the of the other TCP profile in a transaction. tx = mr.tm.transactions.transaction # Note - DO NOT PROCESS FURTHER IF THERE IS NOTHING TO COMMIT. Otherwise TransationContextManager will fire an error like below: # 404 Unexpected Error: Not Found for uri: https://192.168.144.11:443/mgmt/tm/transaction/1574570920607126/ # Text: u'{"code":404,"message":"there is no command to commit in the transaction.","errorStack":[],"apiError":1}' # TransactionContextManager validate_only option - Default: False. If true, just validate(test) the changes in the context # TransactionContextManager(tx, validate_only=True) # Note(01132020) - Virtual Server properties modification # For Virtual Server property modification, you MUST use modify(**patch), which calls "patch" and modify the one exactly you want to change. # DO NOT USE update(). It would casue an error like " The source (::) and destination (4.5.6.7) addresses for virtual server # (/Common/STDALONE-HOME_VS_vs_01132020) must be be the same type (IPv4 or IPv6)." # modContent: Include modified properties of a Virtual Server modContent = {} # isPrfModified: Flag to use if any of Profiles has been modified. If so, all profiles must be modified simultaneous even there is no change. isPrfModified = 0 with TransactionContextManager(tx) as api: logger.info('#####################################') # Update Basic VS properties if loaded_prf_names['description'] != fieldNames['description']: logger.info("Description has been updated. Current: " + loaded_prf_names['description'] + " New: " + fieldNames['description']) loaded_vs.description = fieldNames['description'] #loaded_vs.update() modContent = {'description': fieldNames['description']} #loaded_vs.modify(**modContent) loaded_vs.source = '0.0.0.0/0' #loaded_vs.destination = '%s:%s' % (fieldNames['ip'], fieldNames['port']) if loaded_prf_names['ip'] != fieldNames['ip'] or loaded_prf_names[ 'port'] != fieldNames['port']: loaded_vs.destination = '%s:%s' % (fieldNames['ip'], fieldNames['port']) logger.info("IP or Port has been updated. Current IP: " + loaded_prf_names['ip'] + " New IP: " + fieldNames['ip'] + " Current Port: " + loaded_prf_names['port'] + " New Port: " + fieldNames['port']) modContent['destination'] = '/Common/%s:%s' % ( fieldNames['ip'], fieldNames['port']) if loaded_prf_names['pool'] != fieldNames['pool']: if fieldNames['pool'] == 'none': loaded_vs.pool = fieldNames['pool'] else: loaded_vs.pool = '/Common/%s' % fieldNames['pool'] #mod3Content = { 'pool':'/Common/%s' % fieldNames['pool'] } modContent['pool'] = '/Common/%s' % fieldNames['pool'] logger.info("Pool has been updated. Current: " + loaded_prf_names['pool'] + " New: " + fieldNames['pool']) #prfRefItems: List variable contains all of Profiles Items such as tcp, http, ssl client, ssl server profiles prfRefItems = [] # ALL profiles under 'profilesReference' should be updated at the same time. So if there is at least 1 profile modified, all profiles must # be modified at the same time. Except loaded_prf_names=='none' and fieldNames=='none', all other cases are considered MODIFIED ''' if ((loaded_prf_names['httpProfile'] != fieldNames['httpProfile'] and loaded_prf_names['httpProfile'] != 'none' and fieldNames['httpProfile'] != 'none') or (loaded_prf_names['protocolProfileClient'] != fieldNames['protocolProfileClient'] and loaded_prf_names['protocolProfileClient'] != 'none' and fieldNames['protocolProfileClient'] != 'none') or (loaded_prf_names['sslProfileClient'] != fieldNames['sslProfileClient'] and loaded_prf_names['sslProfileClient'] != 'none' and fieldNames['sslProfileClient'] != 'none' ) or (loaded_prf_names['sslProfileServer'] != fieldNames['sslProfileServer'] and loaded_prf_names['sslProfileServer'] != 'none' and fieldNames['sslProfileServer'] != 'none' ) or (loaded_prf_names['rules'] != fieldNames['rules'] and loaded_prf_names['rules'] != 'none' and fieldNames['rules'] != 'none') or (loaded_prf_names['policies'] != fieldNames['policies'] and loaded_prf_names['policies'] != 'none' and fieldNames['policies'] != 'none') ): ''' if ((loaded_prf_names['httpProfile'] != 'none' and fieldNames['httpProfile'] != 'none') or (loaded_prf_names['protocolProfileClient'] != 'none' and fieldNames['protocolProfileClient'] != 'none') or (loaded_prf_names['sslProfileClient'] != 'none' and fieldNames['sslProfileClient'] != 'none') or (loaded_prf_names['sslProfileServer'] != 'none' and fieldNames['sslProfileServer'] != 'none') or (loaded_prf_names['rules'] != 'none' and fieldNames['rules'] != 'none') or (loaded_prf_names['policies'] != 'none' and fieldNames['policies'] != 'none')): isPrfModified = 1 # Update http profile if isPrfModified == 1: if loaded_prf_names['httpProfile'] != fieldNames['httpProfile']: if loaded_prf_names['httpProfile'] != 'none' and fieldNames[ 'httpProfile'] == 'none': loaded_httpprf = loaded_vs.profiles_s.profiles.load( partition='Common', name=loaded_prf_names['httpProfile']) loaded_httpprf.delete() elif loaded_prf_names[ 'httpProfile'] == 'none' and fieldNames[ 'httpProfile'] != 'none': prfRefItems.append({ 'name': fieldNames['httpProfile'], 'context': 'all' }) elif loaded_prf_names[ 'httpProfile'] != 'none' and fieldNames[ 'httpProfile'] != 'none': prfRefItems.append({ 'name': fieldNames['httpProfile'], 'context': 'all' }) else: if loaded_prf_names['httpProfile'] != 'none' and fieldNames[ 'httpProfile'] != 'none': prfRefItems.append({ 'name': fieldNames['httpProfile'], 'context': 'all' }) logger.info("HTTP Profile has been updated. Current: " + loaded_prf_names['httpProfile'] + " New: " + fieldNames['httpProfile']) ''' if loaded_prf_names['httpProfile'] != fieldNames['httpProfile'] or isPrfModified == 1: # Update VS profile - Delete and then add # Case1 - Remove Http profile (HTTP Profile X to None) if loaded_prf_names['httpProfile'] != 'none' and fieldNames['httpProfile'] == 'none': loaded_httpprf = loaded_vs.profiles_s.profiles.load(partition='Common', name=loaded_prf_names['httpProfile']) loaded_httpprf.delete() # Case2 - Add new HTTP profile (None to HTTP Profile X) elif loaded_prf_names['httpProfile'] == 'none' and fieldNames['httpProfile'] != 'none': # Newly assigned HTTP profile is not none. Use modify() to simply update HTTP profile #profilesRef = { 'items':[{'name':fieldNames['httpProfile'], 'context':'all'}] } prfRefItems.append({'name':fieldNames['httpProfile'], 'context':'all'}) # Case3 - Change existing HTTP Profile to a new HTTP Profile elif loaded_prf_names['httpProfile'] != fieldNames['httpProfile'] and loaded_prf_names['httpProfile'] != 'none' and fieldNames['httpProfile'] != 'none': prfRefItems.append({'name':fieldNames['httpProfile'], 'context':'all'}) else: pass ''' # Update tcp client profile - At this point, tcp server profiel update is not provided. if loaded_prf_names['protocolProfileClient'] != fieldNames[ 'protocolProfileClient'] or isPrfModified == 1: # Update TCP profile - Delete and then add logger.info("Loaded TCP Prf name: " + loaded_prf_names['protocolProfileClient'] + " Your choice: " + fieldNames['protocolProfileClient']) loaded_tcpprf = loaded_vs.profiles_s.profiles.load( partition='Common', name=loaded_prf_names['protocolProfileClient']) loaded_tcpprf.delete() prfRefItems.append({ 'name': fieldNames['protocolProfileClient'], 'context': 'all' }) logger.info("TCP Profile has been updated. Current: " + loaded_prf_names['protocolProfileClient'] + " New: " + fieldNames['protocolProfileClient']) # Update ssl client profile if loaded_prf_names['sslProfileClient'] != fieldNames[ 'sslProfileClient'] or isPrfModified == 1: logger.info("Loaded clientssl Prf name: " + loaded_prf_names['sslProfileClient'] + " Your choice: " + fieldNames['sslProfileClient']) # Update Client SSL profile - Delete and then add if loaded_prf_names[ 'sslProfileClient'] != 'none' and fieldNames[ 'sslProfileClient'] == 'none': loaded_sslcliprf = loaded_vs.profiles_s.profiles.load( partition='Common', name=loaded_prf_names['sslProfileClient']) loaded_sslcliprf.delete() else: # Newly assigned HTTP profile is not none. Use modify() to simply update HTTP profile #profilesRef3 = { 'items':[{'name':fieldNames['sslProfileClient'], 'context':'clientside'}] } #params3 = {'profilesReference':profilesRef3} #loaded_vs.modify(**params3) prfRefItems.append({ 'name': fieldNames['sslProfileClient'], 'context': 'clientside' }) logger.info("SSL Client Profile has been updated. Current: " + loaded_prf_names['sslProfileClient'] + " New: " + fieldNames['sslProfileClient']) # Update ssl server profile if loaded_prf_names['sslProfileServer'] != fieldNames[ 'sslProfileServer'] or isPrfModified == 1: logger.info("Loaded serverssl Prf name: " + loaded_prf_names['sslProfileServer'] + " Your choice: " + fieldNames['sslProfileServer']) # Update Server SSL profile - Delete and then add if loaded_prf_names[ 'sslProfileServer'] != 'none' and fieldNames[ 'sslProfileServer'] == 'none': loaded_sslsrvprf = loaded_vs.profiles_s.profiles.load( partition='Common', name=loaded_prf_names['sslProfileServer']) loaded_sslsrvprf.delete() else: # Newly assigned HTTP profile is not none. Use modify() to simply update HTTP profile #profilesRef4 = { 'items':[{'name':fieldNames['sslProfileServer'], 'context':'serverside'}] } #params4 = {'profilesReference':profilesRef4} #loaded_vs.modify(**params4) prfRefItems.append({ 'name': fieldNames['sslProfileServer'], 'context': 'serverside' }) logger.info("SSL Server Profile has been updated. Current: " + loaded_prf_names['sslProfileServer'] + " New: " + fieldNames['sslProfileServer']) # Update Persistence profile psstItems = [] if loaded_prf_names['persistence'] != fieldNames['persistence']: # Update Persistence profile - Prep persistence setting and then update if loaded_prf_names['persistence'] != 'none' and fieldNames[ 'persistence'] == 'none': psstItems = [] elif loaded_prf_names['persistence'] == 'none' and fieldNames[ 'persistence'] != 'none': psstItems.append({ 'name': fieldNames['persistence'], 'partition': 'Common' }) else: psstItems.append({ 'name': fieldNames['persistence'], 'partition': 'Common' }) modContent['persist'] = psstItems logger.info("Persistence has been updated. Current: " + loaded_prf_names['persistence'] + " New: " + fieldNames['persistence']) # Update iRule # Ref with a value: u'rules': [u'/Common/REDIRECT'] # Ref without a value: 'rules': [] iRuleItmes = [] if isPrfModified == 1: if loaded_prf_names['rules'] != fieldNames['rules']: if loaded_prf_names['rules'] != 'none' and fieldNames[ 'rules'] == 'none': iRuleItmes = [] elif loaded_prf_names['rules'] == 'none' and fieldNames[ 'rules'] != 'none': iRuleItmes.append('/Common/%s' % fieldNames['rules']) elif loaded_prf_names['rules'] != 'none' and fieldNames[ 'rules'] != 'none': iRuleItmes.append('/Common/%s' % fieldNames['rules']) else: if loaded_prf_names['rules'] != 'none' and fieldNames[ 'rules'] != 'none': iRuleItmes.append('/Common/%s' % fieldNames['rules']) modContent['rules'] = iRuleItmes logger.info("iRule has been updated. Current: " + loaded_prf_names['rules'] + " New: " + fieldNames['rules']) ''' if loaded_prf_names['rules'] != fieldNames['rules'] or isPrfModified == 1: # Update Persistence profile - Prep persistence setting and then update if loaded_prf_names['rules'] != 'none' and fieldNames['rules'] == 'none': iRuleItmes = [] #elif loaded_prf_names['rules'] == 'none' and fieldNames['rules'] == 'none': elif loaded_prf_names['rules'] == fieldNames['rules']: iRuleItems = [] elif loaded_prf_names['rules'] == 'none' and fieldNames['rules'] != 'none': iRuleItmes.append('/Common/%s' % fieldNames['rules']) else: iRuleItmes.append('/Common/%s' % fieldNames['rules']) modContent['rules'] = iRuleItmes ''' # Update Policy profile polRefItems = [] if isPrfModified == 1: if loaded_prf_names['policies'] != fieldNames['policies']: if loaded_prf_names['policies'] != 'none' and fieldNames[ 'policies'] == 'none': polRefItems = [] elif loaded_prf_names['policies'] == 'none' and fieldNames[ 'policies'] != 'none': polRefItems.append({ 'name': fieldNames['policies'], 'partition': 'Common' }) elif loaded_prf_names['policies'] != 'none' and fieldNames[ 'policies'] != 'none': polRefItems.append({ 'name': fieldNames['policies'], 'partition': 'Common' }) else: if loaded_prf_names['policies'] != 'none' and fieldNames[ 'policies'] != 'none': polRefItems.append({ 'name': fieldNames['policies'], 'partition': 'Common' }) logger.info("Policy has been updated. Current: " + loaded_prf_names['policies'] + " New: " + fieldNames['policies']) ''' if loaded_prf_names['policies'] != fieldNames['policies'] or isPrfModified == 1: if loaded_prf_names['policies'] != 'none' and fieldNames['policies'] == 'none': polRefItems = [] elif loaded_prf_names['policies'] == fieldNames['policies']: polRefItems = [] elif loaded_prf_names['policies'] == 'none' and fieldNames['policies'] != 'none': polRefItems.append({'name':fieldNames['policies'], 'partition':'Common'}) else: # Newly assigned HTTP profile is not none. Use modify() to simply update HTTP profile #profilesRef = { 'items':[{'name':fieldNames['httpProfile'], 'context':'all'}] } polRefItems.append({'name':fieldNames['policies'], 'partition':'Common'}) ''' # Update SNAT Pool # Ref with no value: u'sourceAddressTranslation': {u'type': u'none'} # Ref with value:sourceAddressTranslation': {u'pool': u'/Common/snap_p_1.2.3.5', # u'poolReference': {u'link': u'https://localhost/mgmt/tm/ltm/snatpool/~Common~snap_p_1.2.3.5?ver=12.1.2'}, # u'type': u'snat'} snatItems = {} if loaded_prf_names['sourceAddressTranslation'] != fieldNames[ 'sourceAddressTranslation'] or isPrfModified == 1: # Update SNAT Pool if loaded_prf_names[ 'sourceAddressTranslation'] != 'none' and fieldNames[ 'sourceAddressTranslation'] == 'none': snatItems = {} elif loaded_prf_names[ 'sourceAddressTranslation'] == fieldNames[ 'sourceAddressTranslation']: snatItems = {} elif loaded_prf_names[ 'sourceAddressTranslation'] == 'none' and fieldNames[ 'sourceAddressTranslation'] != 'none': snatItems = { 'pool': '/Common/%s' % fieldNames['sourceAddressTranslation'], 'type': 'snat' } else: snatItems = { 'pool': '/Common/%s' % fieldNames['sourceAddressTranslation'], 'type': 'snat' } logger.info("SNAT Pool has been updated. Current: " + loaded_prf_names['sourceAddressTranslation'] + " New: " + fieldNames['sourceAddressTranslation']) modContent['sourceAddressTranslation'] = snatItems prfRef = {} polRef = {} prfRef['items'] = prfRefItems polRef['items'] = polRefItems modContent['profilesReference'] = prfRef modContent['policiesReference'] = polRef logger.info("Content to be modified: {0}".format(modContent)) loaded_vs.modify(**modContent) except Exception as e: logger.info("Error during updating virtual server properties") logger.info("Error Details: " + str(e)) logger.info(traceback.format_exc()) strReturn = { str(idx): 'Error during updating virtual server properties Error Detail: ' + str(e) } idx += 1 return json.dumps(strReturn) mr.tm.sys.config.exec_cmd('save') logger.info("Virtual Server has been updated successfully") strReturn = {str(idx): 'Virtual Server has been updated successfully'} idx += 1 return json.dumps(strReturn)
def create_snat_pool_on_device(self, params): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: api.tm.ltm.snatpools.snatpool.create(**params)
def delete_iapp_template_from_device(self): tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: tpl = api.tm.sys.application.templates.template.load( name=self.params['name'], partition=self.params['partition']) tpl.delete()
def absent(self): params = dict() current = self.read() # Temporary locations to hold the changed params update = dict( dns=None, forwarders=None ) nameservers = self.params['name_servers'] search_domains = self.params['search'] forwarders = self.params['forwarders'] check_mode = self.params['check_mode'] if forwarders and 'forwarders' in current: set_current = set(current['forwarders']) set_new = set(forwarders) forwarders = set_current - set_new if forwarders != set_current: forwarders = list(forwarders) params['forwarders'] = ' '.join(forwarders) if params: changed = True self.cparams.update(camel_dict_to_snake_dict(params)) update['forwarders'] = params['forwarders'] params = dict() if nameservers and 'name_servers' in current: set_current = set(current['name_servers']) set_new = set(nameservers) nameservers = set_current - set_new if nameservers != set_current: params['nameServers'] = list(nameservers) if search_domains and 'search' in current: set_current = set(current['search']) set_new = set(search_domains) search_domains = set_current - set_new if search_domains != set_current: params['search'] = list(search_domains) if params: changed = True self.cparams.update(camel_dict_to_snake_dict(params)) update['dns'] = params.copy() params = dict() if not self.cparams: return False if check_mode: return changed tx = self.api.tm.transactions.transaction with TransactionContextManager(tx) as api: proxy = api.tm.sys.dbs.db.load(name='dns.proxy.__iter__') dns = api.tm.sys.dns.load() if update['forwarders'] is not None: proxy.update(value=update['forwarders']) if update['dns'] is not None: dns.update(**update['dns']) return changed
def deploy_cert(args): domain = args[0] key = args[1] cert = args[2] chain = args[4] ffivemr = ManagementRoot(f5_host, f5_user, f5_password) # Upload files ffivemr.shared.file_transfer.uploads.upload_file(key) ffivemr.shared.file_transfer.uploads.upload_file(cert) ffivemr.shared.file_transfer.uploads.upload_file(chain) # Check to see if these already exist key_status = ffivemr.tm.sys.file.ssl_keys.ssl_key.exists( name='{0}.key'.format(domain)) cert_status = ffivemr.tm.sys.file.ssl_certs.ssl_cert.exists( name='{0}.crt'.format(domain)) chain_status = ffivemr.tm.sys.file.ssl_certs.ssl_cert.exists( name='le-chain.crt') if key_status and cert_status and chain_status: # Because they exist, we will modify them in a transaction tx = ffivemr.tm.transactions.transaction with TransactionContextManager(tx) as txapi: modkey = txapi.tm.sys.file.ssl_keys.ssl_key.load( name='{0}.key'.format(domain)) modkey.sourcePath = 'file:/var/config/rest/downloads/{0}'.format( os.path.basename(key)) modkey.update() modcert = txapi.tm.sys.file.ssl_certs.ssl_cert.load( name='{0}.crt'.format(domain)) modcert.sourcePath = 'file:/var/config/rest/downloads/{0}'.format( os.path.basename(cert)) modcert.update() modchain = txapi.tm.sys.file.ssl_certs.ssl_cert.load( name='le-chain.crt') modchain.sourcePath = 'file:/var/config/rest/downloads/{0}'.format( os.path.basename(chain)) modchain.update() logger.info( " + (hook) Existing Certificate/Key updated in transaction.") else: newkey = ffivemr.tm.sys.file.ssl_keys.ssl_key.create( name='{0}.key'.format(domain), sourcePath='file:/var/config/rest/downloads/{0}'.format( os.path.basename(key))) newcert = ffivemr.tm.sys.file.ssl_certs.ssl_cert.create( name='{0}.crt'.format(domain), sourcePath='file:/var/config/rest/downloads/{0}'.format( os.path.basename(cert))) if not chain_status: logger.info(" + (hook) No LE-Chain found - deploying now") newchain = ffivemr.tm.sys.file.ssl_certs.ssl_cert.create( name='le-chain.crt', sourcePath='file:/var/config/rest/downloads/{0}'.format( os.path.basename(chain))) logger.info(" + (hook) New Certificate/Key created.") # Create SSL Profile if necessary if not ffivemr.tm.ltm.profile.client_ssls.client_ssl.exists( name='cssl.{0}'.format(domain), partition='Common'): cssl_profile = { 'name': '/Common/cssl.{0}'.format(domain), 'cert': '/Common/{0}.crt'.format(domain), 'key': '/Common/{0}.key'.format(domain), 'chain': '/Common/le-chain.crt', 'defaultsFrom': '/Common/clientssl' } ffivemr.tm.ltm.profile.client_ssls.client_ssl.create(**cssl_profile)