From f5475ed3f2acc01e28f9e29c7fc7ec2f1ad4768d Mon Sep 17 00:00:00 2001 From: "Paul C. Buetow (mars.fritz.box)" Date: Tue, 29 Apr 2014 07:49:42 +0200 Subject: some restyle --- src/fapi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/fapi b/src/fapi index 5d26e2a..ffa6a40 100755 --- a/src/fapi +++ b/src/fapi @@ -202,8 +202,8 @@ class Fapi(FapiBase): try: self.verbose('Trying to login to \'%s\'' % loadbalancer) self._f5 = bigsuds.BIGIP(hostname = loadbalancer, - username = username, - password = password) + username = username, + password = password) self._f5.Management.Partition.set_active_partition(self._folder) self.verbose('Set folder/adm. partition to \'%s\'' % self._folder) err = None @@ -449,8 +449,8 @@ class Fapi(FapiBase): resource = { 'type': 'RESOURCE_TYPE_POOL' } if poolname: resource['default_pool_name'] = poolname profile = { - 'profile_context': 'PROFILE_CONTEXT_TYPE_ALL', - 'profile_name': profile, + 'profile_context': 'PROFILE_CONTEXT_TYPE_ALL', + 'profile_name': profile, } self.verbose("vserver:%s netmask:%s resource:%s, profile:%s" % (vserver, netmask, resource, profile)) @@ -494,7 +494,7 @@ class Fapi(FapiBase): else: _, ip, _ = self.lookup(a.name) name = ip - + # Do the actual stuff if a.sub == 'get': if a.sub2 == 'detail': def detail(f5): -- cgit v1.2.3 From 288742e561977c8af28365a61a2af2f39fd4dc39 Mon Sep 17 00:00:00 2001 From: "Paul C. Buetow (mars.fritz.box)" Date: Tue, 29 Apr 2014 08:08:43 +0200 Subject: initial preparation for the bulk operation --- src/fapi | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/fapi b/src/fapi index ffa6a40..c4a848c 100755 --- a/src/fapi +++ b/src/fapi @@ -654,36 +654,41 @@ class Fapi(FapiBase): orders = { 'device': a.sub3, 'order': a.sub4 } return lambda: f5().remove_all_ha_orders([a.name]) - def run(self): - ''' Do the actual stuff. - We are doning some lazy evaluation stuff here. The command line - tool does not do anything with the slow F5 API until it is clear - what to do and that there is no semantic or syntax error. ''' + def _lazy(self): + ''' Get the lazy code block to be executed ''' a = self._args - lazy = None if a.name: # Remove the /partition/ prefix, setting default partition after # login instead a.name = re.sub(self._folder, '', a.name) a.name = re.sub('^/+', '', a.name) if a.what == 'node': - lazy = self.__do_node(lambda: self._f5.LocalLB.NodeAddressV2) + return self.__do_node(lambda: self._f5.LocalLB.NodeAddressV2) elif a.what == 'monitor': - lazy = self.__do_monitor(lambda: self._f5.LocalLB.Monitor) + return self.__do_monitor(lambda: self._f5.LocalLB.Monitor) elif a.what == 'pool': - lazy = self.__do_pool(lambda: self._f5.LocalLB.Pool) + return self.__do_pool(lambda: self._f5.LocalLB.Pool) elif a.what == 'vserver': - lazy = self.__do_vserver(lambda: self._f5.LocalLB.VirtualServer) + return self.__do_vserver(lambda: self._f5.LocalLB.VirtualServer) elif a.what == 'vip': - lazy = self.__do_vip(lambda: self._f5.LocalLB.VirtualAddressV2) + return self.__do_vip(lambda: self._f5.LocalLB.VirtualAddressV2) elif a.what == 'vlan': - lazy = self.__do_vlan(lambda: self._f5.Networking.VLAN) + return self.__do_vlan(lambda: self._f5.Networking.VLAN) elif a.what == 'selfip': - lazy = self.__do_selfip(lambda: self._f5.Networking.SelfIPV2) + return self.__do_selfip(lambda: self._f5.Networking.SelfIPV2) elif a.what == 'tgroup': - lazy = self.__do_tgroup(lambda: self._f5.Management.TrafficGroup) + return self.__do_tgroup(lambda: self._f5.Management.TrafficGroup) elif a.what == 'folder': - lazy = self.__do_folder(lambda: self._f5.Management.Folder) + return self.__do_folder(lambda: self._f5.Management.Folder) + + + def run(self): + ''' Do the actual stuff. + We are doning some lazy evaluation stuff here. The command line + tool does not do anything with the slow F5 API until it is clear + what to do and that there is no semantic or syntax error. ''' + a = self._args + lazy = self._lazy() if isfunction(lazy): self.verbose('Doing some stuf via the API, it may take a while') self.__login() -- cgit v1.2.3 From 56ec0398d58b192c6870a636e91ecede7ce5943c Mon Sep 17 00:00:00 2001 From: "Paul C. Buetow (mars.fritz.box)" Date: Tue, 29 Apr 2014 08:11:47 +0200 Subject: rename ./-n to ./-d --- src/fapi | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/fapi b/src/fapi index c4a848c..a316392 100755 --- a/src/fapi +++ b/src/fapi @@ -36,7 +36,7 @@ class FapiBase(object): def info(self, message, color=''): ''' Prints an informational message to stderr ''' - if self._args.n: + if self._args.d: color = reset = '' else: reset = '' if color == '' else Style.RESET_ALL @@ -57,7 +57,7 @@ class FapiBase(object): def print_synopsis(self): ''' Prints the full Synopsis string ''' - if self._args.n: + if self._args.d: style = reset = '' else: style = Style.DIM @@ -131,13 +131,13 @@ class ArgumentParser(FapiBase): self._parser = parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-b', action='store', help='Forces to use the secified loadbalancer (overwrites -e)') + parser.add_argument('-d', action='store_true', help='Disable colorful output') parser.add_argument('-e', action='store', help='Env to use, e.g. dev,qa,live', default='qa') parser.add_argument('-f', action='store', help='Overwrite partition/folder from fapi.conf') parser.add_argument('-h', action='store_true', help='Print this help') parser.add_argument('-i', action='store_true', help='Interactive shell') parser.add_argument('-l', action='store_true', help='Use list output') - parser.add_argument('-n', action='store_true', help='No color (disable colorful output)') parser.add_argument('-v', action='store_true', help='Verbose') parser.add_argument('-V', action='store_true', help='Print program version') parser.add_argument('-C', action='store', help='Config file', @@ -681,13 +681,14 @@ class Fapi(FapiBase): elif a.what == 'folder': return self.__do_folder(lambda: self._f5.Management.Folder) - def run(self): ''' Do the actual stuff. We are doning some lazy evaluation stuff here. The command line tool does not do anything with the slow F5 API until it is clear what to do and that there is no semantic or syntax error. ''' a = self._args + if a.name == '_': + print "BULK" lazy = self._lazy() if isfunction(lazy): self.verbose('Doing some stuf via the API, it may take a while') -- cgit v1.2.3 From 34dd414cebebcc9059d15870c2ea2a1c396895c5 Mon Sep 17 00:00:00 2001 From: "Paul C. Buetow (mars.fritz.box)" Date: Tue, 29 Apr 2014 08:14:46 +0200 Subject: introduce -n for no-op --- src/fapi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/fapi b/src/fapi index a316392..80b600b 100755 --- a/src/fapi +++ b/src/fapi @@ -138,6 +138,7 @@ class ArgumentParser(FapiBase): parser.add_argument('-h', action='store_true', help='Print this help') parser.add_argument('-i', action='store_true', help='Interactive shell') parser.add_argument('-l', action='store_true', help='Use list output') + parser.add_argument('-n', action='store_true', help='No-op (don\'t do actual stuff)') parser.add_argument('-v', action='store_true', help='Verbose') parser.add_argument('-V', action='store_true', help='Print program version') parser.add_argument('-C', action='store', help='Config file', @@ -691,10 +692,13 @@ class Fapi(FapiBase): print "BULK" lazy = self._lazy() if isfunction(lazy): - self.verbose('Doing some stuf via the API, it may take a while') - self.__login() - self.out(lazy()) - self.info('done', Fore.GREEN) + if a.n: + self.info('no-op', Fore.GREEN) + else: + self.verbose('Doing some stuf via the API, it may take a while') + self.__login() + self.out(lazy()) + self.info('done', Fore.GREEN) else: self.print_synopsis() return 1 -- cgit v1.2.3 From bd872471737964416061c8d061b21bd93e6a0635 Mon Sep 17 00:00:00 2001 From: "Paul C. Buetow (mars.fritz.box)" Date: Tue, 29 Apr 2014 08:57:33 +0200 Subject: trying to implement a smart bulk edit --- src/fapi | 64 +++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/fapi b/src/fapi index 80b600b..1418aea 100755 --- a/src/fapi +++ b/src/fapi @@ -171,6 +171,8 @@ class ArgumentParser(FapiBase): class Fapi(FapiBase): ''' The main F5 API Tool Object ''' + __loggedin = False + def __init__(self, args): ''' Initialize the config file, username and password ''' FapiBase.__init__(self, args) @@ -183,6 +185,7 @@ class Fapi(FapiBase): def __login(self): ''' Logs into the F5 BigIP SOAP API and changes the folder/adm. partition''' + if __loggedin: return c = self._config a = self._args if c.has_option('fapi', 'username'): @@ -214,6 +217,7 @@ class Fapi(FapiBase): pass if err: raise Exception(err) + __loggedin = True def lookup(self, what): ''' Does a DNS lookup to fetch the name (mostly FQDN) and the IPs @@ -258,6 +262,22 @@ class Fapi(FapiBase): self.verbose("Looked \'%s\' up to name:\'%s\', ip:\'%s\', port:\'%s\'" % (what, name, ip, port)) return (name, ip, port) + + def li(self, name): + ''' Checks if name is a list and returns a list if not. ''' + return name if isinstance(name, list) else [name] + + + def pa(self, length, params): + ''' Checks if name is a list and returns a list of params if so ''' + paramlist = [] + if length > 1: + for _ in xrange(length): paramlist.append(params) + else: + paramlist.append(params) + return paramlist + + def __do_node(self, f5): ''' Do stuff concerning nodes ''' a = self._args @@ -267,24 +287,26 @@ class Fapi(FapiBase): if a.sub2 == 'detail': def detail(f5): d = {} - d['connection_limit'] = f5().get_connection_limit([a.name]) + d['connection_limit'] = f5().get_connection_limit(li(a.name)) d['default_node_monitor'] = f5().get_default_node_monitor() - d['description'] = f5().get_description([a.name]) - d['dynamic_ratio'] = f5().get_dynamic_ratio_v2([a.name]) - d['monitor_instance'] = f5().get_monitor_instance([a.name]) - d['monitor_rule'] = f5().get_monitor_rule([a.name]) - d['monitor_status'] = f5().get_monitor_status([a.name]) - d['object_status'] = f5().get_object_status([a.name]) - d['rate_limit'] = f5().get_rate_limit([a.name]) - d['ratio'] = f5().get_ratio([a.name]) - d['session_status'] = f5().get_session_status([a.name]) + d['description'] = f5().get_description(li(a.name)) + d['dynamic_ratio'] = f5().get_dynamic_ratio_v2(li(a.name)) + d['monitor_instance'] = f5().get_monitor_instance(li(a.name)) + d['monitor_rule'] = f5().get_monitor_rule(li(a.name)) + d['monitor_status'] = f5().get_monitor_status(li(a.name)) + d['object_status'] = f5().get_object_status(li(a.name)) + d['rate_limit'] = f5().get_rate_limit(li(a.name)) + d['ratio'] = f5().get_ratio(li(a.name)) + d['session_status'] = f5().get_session_status(li(a.name)) return d return lambda: detail(f5) if a.sub2 == 'status': - return lambda: f5().get_monitor_status([a.name]) + return lambda: f5().get_monitor_status(li(a.name)) elif a.sub == 'create': fqdn_or_ip, ip, _ = self.lookup(a.name) - return lambda: f5().create([fqdn_or_ip],[ip],[0]) + return lambda: f5().create(li(fqdn_or_ip), + [ip], + pa(len(fqdn_or_ip),0)) elif a.sub == 'delete': fqdn_or_ip, _, _ = self.lookup(a.name) return lambda: f5().delete_node_address([fqdn_or_ip]) @@ -658,11 +680,17 @@ class Fapi(FapiBase): def _lazy(self): ''' Get the lazy code block to be executed ''' a = self._args - if a.name: + def namify(name): # Remove the /partition/ prefix, setting default partition after # login instead - a.name = re.sub(self._folder, '', a.name) - a.name = re.sub('^/+', '', a.name) + name = re.sub(self._folder, '', name) + name = re.sub('^/+', '', name) + return name + if a.name: + if isinstance(a.name, list): + a.name = map(namify, a.name) + else: + a.name = namify(a.name) if a.what == 'node': return self.__do_node(lambda: self._f5.LocalLB.NodeAddressV2) elif a.what == 'monitor': @@ -688,11 +716,13 @@ class Fapi(FapiBase): tool does not do anything with the slow F5 API until it is clear what to do and that there is no semantic or syntax error. ''' a = self._args - if a.name == '_': - print "BULK" + # Inline bulk + if a.name and ',' in a.name: + a.name = a.name.split(',') lazy = self._lazy() if isfunction(lazy): if a.n: + self.verbose(lazy) self.info('no-op', Fore.GREEN) else: self.verbose('Doing some stuf via the API, it may take a while') -- cgit v1.2.3 From 5226f622e1c20ebf1c836c19e5d57ff7a3aa5591 Mon Sep 17 00:00:00 2001 From: "Paul C. Buetow (mars.fritz.box)" Date: Sun, 25 May 2014 10:12:32 +0200 Subject: add note about python --- src/fapi | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/fapi b/src/fapi index 0a78306..ca3e801 100755 --- a/src/fapi +++ b/src/fapi @@ -1,6 +1,8 @@ #!/usr/bin/env python # 2014 (c) Paul C. Buetow +# I'm sorry, but this is my first Python program to find out if it's worth +# using it. I'm more into Perl, and it will stay so. import argparse import base64 -- cgit v1.2.3