diff options
| author | Paul C. Buetow <paul@buetow.org> | 2014-05-26 15:36:44 +0200 |
|---|---|---|
| committer | Paul C. Buetow <paul@buetow.org> | 2014-05-26 15:36:44 +0200 |
| commit | e7a6b6dd3eba65523e66e06d32ce04998dffe5dd (patch) | |
| tree | d767af6350b8b455d9db6a19c0f7d0e8316c2c9e | |
| parent | 259a0937c4dbc395497d7050f1d16d8b5127b877 (diff) | |
| parent | 5226f622e1c20ebf1c836c19e5d57ff7a3aa5591 (diff) | |
Merge branch 'master' of github.com:rantanplan/fapi
| -rw-r--r-- | .version | 2 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | README.pod | 32 | ||||
| -rw-r--r-- | debian/changelog | 22 | ||||
| -rw-r--r-- | debian/files | 2 | ||||
| -rw-r--r-- | docs/fapi.1 | 40 | ||||
| -rw-r--r-- | docs/fapi.pod | 32 | ||||
| -rw-r--r-- | docs/fapi.txt | 33 | ||||
| -rw-r--r-- | docs/synopsis.txt | 13 | ||||
| -rwxr-xr-x | src/fapi | 126 |
10 files changed, 188 insertions, 116 deletions
@@ -1 +1 @@ -0.7.0 +0.7.3 @@ -31,7 +31,7 @@ documentation: ./bin/fapi -h -n > ./docs/synopsis.txt # Build a debian package deb: all - dpkg-buildpackage -us -uc + dpkg-buildpackage # -us -uc dch: dch -i release: dch deb @@ -107,22 +107,12 @@ If you want to list all configured objects on your partition just run A simple nPath service can be created as follows. - # Create a nPath HTTP vserver, 'nPath' also auto disables NAT and PAT - # fapi auto resolves the IP address. fapi vserver myvserver.example.com:80 create PROTOCOL_TCP nPath - - # Add the pool to the vserver. The vservers name inside of BigIP will be - # the FQDN followed by _PORT. In this case it would be: - # myvserver.example.com_80 (or full: /Partition/myvserver.example.com_80) - # The reason is that : are not allowed in vserver names. fapi vserver myvserver.example.com:80 set pool foopool - # Add a nPath HTTPS vserver - fapi vserver myvserver.example.com:443 create PROTOCOL_TCP nPath - fapi vserver myvserver.example.com:443 set pool foopool - - # Restrict the vserver to a specific VLAN (IMPORTANT! security + # Restrict the vservers to a specific VLAN (IMPORTANT! security # hole otherwise!) + fapi vserver myvserver.example.com:80 set vlan VLANNAME fapi vserver myvserver.example.com:443 set vlan VLANNAME # Put the VirtualAddress of the vserver into a specific traffic group @@ -140,13 +130,25 @@ And everything can be deleted as folows: fapi node fooserver1.example.com delete fapi node fooserver2.example.com delete -=head2 Setting up simple NAT Services +=head2 Setting up simple HTTP NAT Services - (Docu to be written) +A simple HTTP NATed service can be created as follows. + + fapi vserver myvserver.example.com:80 create PROTOCOL_TCP /Common/http + fapi vserver myvserver.example.com:80 set vlan VLANNAME + fapi vserver myvserver.example.com:80 set pool foopool + +In order to make this work your application servers need to have setup a +default route to the loadbalancers floating self IP. =head2 Setting up simple SNAT Services - (Docu to be written) +Same as setting up a NATed services, but you don't need to configure default +routes from your application servers to the loadbalancers floating self IP. + +You need also to set the SNAT flag as follows: + + fapi vserver myvserver.example.com:80 set snat automap =head2 About the NAME argument diff --git a/debian/changelog b/debian/changelog index b8812bc..2d47e4f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,30 @@ +fapi (0.7.3) stable; urgency=low + + * Fixes documentation + + -- Paul Buetow <paul@buetow.org> Fri, 16 May 2014 20:13:29 +0200 + +fapi (0.7.2) stable; urgency=low + + * Fixes documentation + + -- Paul Buetow <paul@buetow.org> Fri, 16 May 2014 20:11:45 +0200 + +fapi (0.7.1) stable; urgency=low + + * Add example how to create a NATed VirtualServer... + * Add example how to create a SNATed VirtualServer... + ... to the manpage + + -- Paul Buetow <paul@buetow.org> Fri, 16 May 2014 20:01:48 +0200 + fapi (0.7.0) stable; urgency=low * Can also set and get the vlan of a vserver * Can also set SNAT to automap * Small updates in the documentation - -- Paul Buetow <paul.buetow@1und1.de> Fri, 16 May 2014 17:52:31 +0200 + -- Paul Buetow <paul@buetow.org> Fri, 16 May 2014 17:52:31 +0200 fapi (0.6.2) stable; urgency=low diff --git a/debian/files b/debian/files index 5a378c3..0d3edca 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fapi_0.7.0_all.deb utils optional +fapi_0.7.3_all.deb utils optional diff --git a/docs/fapi.1 b/docs/fapi.1 index 1dc317f..c47300d 100644 --- a/docs/fapi.1 +++ b/docs/fapi.1 @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "FAPI 1" -.TH FAPI 1 "2014-05-16" "fapi 0.7.0" "User Commands" +.TH FAPI 1 "2014-05-16" "fapi 0.7.3" "User Commands" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -245,23 +245,13 @@ If you want to list all configured objects on your partition just run .IX Subsection "Setting up a simple nPath Service" A simple nPath service can be created as follows. .PP -.Vb 3 -\& # Create a nPath HTTP vserver, \*(AqnPath\*(Aq also auto disables NAT and PAT -\& # fapi auto resolves the IP address. +.Vb 2 \& fapi vserver myvserver.example.com:80 create PROTOCOL_TCP nPath -\& -\& # Add the pool to the vserver. The vservers name inside of BigIP will be -\& # the FQDN followed by _PORT. In this case it would be: -\& # myvserver.example.com_80 (or full: /Partition/myvserver.example.com_80) -\& # The reason is that : are not allowed in vserver names. \& fapi vserver myvserver.example.com:80 set pool foopool \& -\& # Add a nPath HTTPS vserver -\& fapi vserver myvserver.example.com:443 create PROTOCOL_TCP nPath -\& fapi vserver myvserver.example.com:443 set pool foopool -\& -\& # Restrict the vserver to a specific VLAN (IMPORTANT! security +\& # Restrict the vservers to a specific VLAN (IMPORTANT! security \& # hole otherwise!) +\& fapi vserver myvserver.example.com:80 set vlan VLANNAME \& fapi vserver myvserver.example.com:443 set vlan VLANNAME \& \& # Put the VirtualAddress of the vserver into a specific traffic group @@ -281,15 +271,27 @@ And everything can be deleted as folows: \& fapi node fooserver1.example.com delete \& fapi node fooserver2.example.com delete .Ve -.SS "Setting up simple \s-1NAT\s0 Services" -.IX Subsection "Setting up simple NAT Services" -.Vb 1 -\& (Docu to be written) +.SS "Setting up simple \s-1HTTP\s0 \s-1NAT\s0 Services" +.IX Subsection "Setting up simple HTTP NAT Services" +A simple \s-1HTTP\s0 NATed service can be created as follows. +.PP +.Vb 3 +\& fapi vserver myvserver.example.com:80 create PROTOCOL_TCP /Common/http +\& fapi vserver myvserver.example.com:80 set vlan VLANNAME +\& fapi vserver myvserver.example.com:80 set pool foopool .Ve +.PP +In order to make this work your application servers need to have setup a +default route to the loadbalancers floating self \s-1IP\s0. .SS "Setting up simple \s-1SNAT\s0 Services" .IX Subsection "Setting up simple SNAT Services" +Same as setting up a NATed services, but you don't need to configure default +routes from your application servers to the loadbalancers floating self \s-1IP\s0. +.PP +You need also to set the \s-1SNAT\s0 flag as follows: +.PP .Vb 1 -\& (Docu to be written) +\& fapi vserver myvserver.example.com:80 set snat automap .Ve .SS "About the \s-1NAME\s0 argument" .IX Subsection "About the NAME argument" diff --git a/docs/fapi.pod b/docs/fapi.pod index b5cfa9b..ca50e31 100644 --- a/docs/fapi.pod +++ b/docs/fapi.pod @@ -107,22 +107,12 @@ If you want to list all configured objects on your partition just run A simple nPath service can be created as follows. - # Create a nPath HTTP vserver, 'nPath' also auto disables NAT and PAT - # fapi auto resolves the IP address. fapi vserver myvserver.example.com:80 create PROTOCOL_TCP nPath - - # Add the pool to the vserver. The vservers name inside of BigIP will be - # the FQDN followed by _PORT. In this case it would be: - # myvserver.example.com_80 (or full: /Partition/myvserver.example.com_80) - # The reason is that : are not allowed in vserver names. fapi vserver myvserver.example.com:80 set pool foopool - # Add a nPath HTTPS vserver - fapi vserver myvserver.example.com:443 create PROTOCOL_TCP nPath - fapi vserver myvserver.example.com:443 set pool foopool - - # Restrict the vserver to a specific VLAN (IMPORTANT! security + # Restrict the vservers to a specific VLAN (IMPORTANT! security # hole otherwise!) + fapi vserver myvserver.example.com:80 set vlan VLANNAME fapi vserver myvserver.example.com:443 set vlan VLANNAME # Put the VirtualAddress of the vserver into a specific traffic group @@ -140,13 +130,25 @@ And everything can be deleted as folows: fapi node fooserver1.example.com delete fapi node fooserver2.example.com delete -=head2 Setting up simple NAT Services +=head2 Setting up simple HTTP NAT Services - (Docu to be written) +A simple HTTP NATed service can be created as follows. + + fapi vserver myvserver.example.com:80 create PROTOCOL_TCP /Common/http + fapi vserver myvserver.example.com:80 set vlan VLANNAME + fapi vserver myvserver.example.com:80 set pool foopool + +In order to make this work your application servers need to have setup a +default route to the loadbalancers floating self IP. =head2 Setting up simple SNAT Services - (Docu to be written) +Same as setting up a NATed services, but you don't need to configure default +routes from your application servers to the loadbalancers floating self IP. + +You need also to set the SNAT flag as follows: + + fapi vserver myvserver.example.com:80 set snat automap =head2 About the NAME argument diff --git a/docs/fapi.txt b/docs/fapi.txt index 698a0cb..67fe651 100644 --- a/docs/fapi.txt +++ b/docs/fapi.txt @@ -95,22 +95,12 @@ EXAMPLES Setting up a simple nPath Service A simple nPath service can be created as follows. - # Create a nPath HTTP vserver, 'nPath' also auto disables NAT and PAT - # fapi auto resolves the IP address. fapi vserver myvserver.example.com:80 create PROTOCOL_TCP nPath - - # Add the pool to the vserver. The vservers name inside of BigIP will be - # the FQDN followed by _PORT. In this case it would be: - # myvserver.example.com_80 (or full: /Partition/myvserver.example.com_80) - # The reason is that : are not allowed in vserver names. fapi vserver myvserver.example.com:80 set pool foopool - # Add a nPath HTTPS vserver - fapi vserver myvserver.example.com:443 create PROTOCOL_TCP nPath - fapi vserver myvserver.example.com:443 set pool foopool - - # Restrict the vserver to a specific VLAN (IMPORTANT! security + # Restrict the vservers to a specific VLAN (IMPORTANT! security # hole otherwise!) + fapi vserver myvserver.example.com:80 set vlan VLANNAME fapi vserver myvserver.example.com:443 set vlan VLANNAME # Put the VirtualAddress of the vserver into a specific traffic group @@ -128,11 +118,24 @@ EXAMPLES fapi node fooserver1.example.com delete fapi node fooserver2.example.com delete - Setting up simple NAT Services - (Docu to be written) + Setting up simple HTTP NAT Services + A simple HTTP NATed service can be created as follows. + + fapi vserver myvserver.example.com:80 create PROTOCOL_TCP /Common/http + fapi vserver myvserver.example.com:80 set vlan VLANNAME + fapi vserver myvserver.example.com:80 set pool foopool + + In order to make this work your application servers need to have setup a + default route to the loadbalancers floating self IP. Setting up simple SNAT Services - (Docu to be written) + Same as setting up a NATed services, but you don't need to configure + default routes from your application servers to the loadbalancers + floating self IP. + + You need also to set the SNAT flag as follows: + + fapi vserver myvserver.example.com:80 set snat automap About the NAME argument In most cases NAME can be a hostname, FQDN or an IP address. Optionally diff --git a/docs/synopsis.txt b/docs/synopsis.txt index 054543f..8e7317c 100644 --- a/docs/synopsis.txt +++ b/docs/synopsis.txt @@ -1,4 +1,4 @@ -usage: fapi [-b B] [-e E] [-f F] [-h] [-i] [-l] [-n] [-v] [-V] [-C C] +usage: fapi [-b B] [-d] [-e E] [-f F] [-h] [-i] [-l] [-n] [-v] [-V] [-C C] [what] [name] [sub] [sub2] [sub3] [sub4] [sub5] positional arguments: @@ -12,19 +12,20 @@ positional arguments: optional arguments: -b B Forces to use the secified loadbalancer (overwrites -e) + -d Disable colorful output -e E Env to use, e.g. dev,qa,live -f F Overwrite partition/folder from fapi.conf -h Print this help -i Interactive shell -l Use list output - -n No color (disable colorful output) + -n No-op (don't do actual stuff) -v Verbose -V Print program version -C C Config file Synopsis: - monitor +[2m monitor monitor NAME get desc|state node node NODENAME create|delete @@ -50,9 +51,9 @@ Synopsis: vserver NAME set nat|pat disabled|enabled vserver NAME set pool POOLNAME vserver NAME set snat automap|none - vserver NAME set vlan [list,of,vlans,to,allow] + vserver NAME set vlan [list,of,vlans,to,allow][0m The following partially needs admininstrator privileges on / and /Common - -f Common -b balancer.example.com selfip +[2m -f Common -b balancer.example.com selfip -f Common -b balancer.example.com selfip NAME create NETMASK VLANNAME [TGROUP] -f Common -b balancer.example.com selfip NAME delete -f Common -b balancer.example.com selfip NAME get detail|tgroup @@ -72,5 +73,5 @@ The following partially needs admininstrator privileges on / and /Common -f / folder -f / folder NAME create|delete -f / folder NAME get detail|dgroup|tgroup - -f / folder NAME set dgroup|tgroup DGROUP|TGROUP + -f / folder NAME set dgroup|tgroup DGROUP|TGROUP[0m Please consult the manpage for examples. @@ -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 @@ -36,7 +38,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 +59,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 @@ -132,13 +134,14 @@ 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('-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', @@ -171,6 +174,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 +188,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'): @@ -203,8 +209,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 @@ -214,6 +220,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 +265,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 +290,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]) @@ -452,8 +477,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)) @@ -506,7 +531,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): @@ -666,41 +691,58 @@ 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: + 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': - 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 + # Inline bulk + if a.name and ',' in a.name: + a.name = a.name.split(',') + 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.verbose(lazy) + 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 |
