mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
1941 lines
71 KiB
Python
1941 lines
71 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2017 Citrix Systems
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
__metaclass__ = type
|
|
|
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
'status': ['preview'],
|
|
'supported_by': 'community'}
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: netscaler_lb_vserver
|
|
short_description: Manage load balancing vserver configuration
|
|
description:
|
|
- Manage load balancing vserver configuration
|
|
- This module is intended to run either on the ansible control node or a bastion (jumpserver) with access to the actual netscaler instance
|
|
|
|
|
|
author: George Nikolopoulos (@giorgos-nikolopoulos)
|
|
|
|
options:
|
|
|
|
name:
|
|
description:
|
|
- >-
|
|
Name for the virtual server. Must begin with an ASCII alphanumeric or underscore C(_) character, and
|
|
must contain only ASCII alphanumeric, underscore, hash C(#), period C(.), space C( ), colon C(:), at sign
|
|
C(@), equal sign C(=), and hyphen C(-) characters. Can be changed after the virtual server is created.
|
|
- "Minimum length = 1"
|
|
|
|
servicetype:
|
|
choices:
|
|
- 'HTTP'
|
|
- 'FTP'
|
|
- 'TCP'
|
|
- 'UDP'
|
|
- 'SSL'
|
|
- 'SSL_BRIDGE'
|
|
- 'SSL_TCP'
|
|
- 'DTLS'
|
|
- 'NNTP'
|
|
- 'DNS'
|
|
- 'DHCPRA'
|
|
- 'ANY'
|
|
- 'SIP_UDP'
|
|
- 'SIP_TCP'
|
|
- 'SIP_SSL'
|
|
- 'DNS_TCP'
|
|
- 'RTSP'
|
|
- 'PUSH'
|
|
- 'SSL_PUSH'
|
|
- 'RADIUS'
|
|
- 'RDP'
|
|
- 'MYSQL'
|
|
- 'MSSQL'
|
|
- 'DIAMETER'
|
|
- 'SSL_DIAMETER'
|
|
- 'TFTP'
|
|
- 'ORACLE'
|
|
- 'SMPP'
|
|
- 'SYSLOGTCP'
|
|
- 'SYSLOGUDP'
|
|
- 'FIX'
|
|
- 'SSL_FIX'
|
|
description:
|
|
- "Protocol used by the service (also called the service type)."
|
|
|
|
ipv46:
|
|
description:
|
|
- "IPv4 or IPv6 address to assign to the virtual server."
|
|
|
|
ippattern:
|
|
description:
|
|
- >-
|
|
IP address pattern, in dotted decimal notation, for identifying packets to be accepted by the virtual
|
|
server. The IP Mask parameter specifies which part of the destination IP address is matched against
|
|
the pattern. Mutually exclusive with the IP Address parameter.
|
|
- >-
|
|
For example, if the IP pattern assigned to the virtual server is C(198.51.100.0) and the IP mask is
|
|
C(255.255.240.0) (a forward mask), the first 20 bits in the destination IP addresses are matched with
|
|
the first 20 bits in the pattern. The virtual server accepts requests with IP addresses that range
|
|
from C(198.51.96.1) to C(198.51.111.254). You can also use a pattern such as C(0.0.2.2) and a mask such as
|
|
C(0.0.255.255) (a reverse mask).
|
|
- >-
|
|
If a destination IP address matches more than one IP pattern, the pattern with the longest match is
|
|
selected, and the associated virtual server processes the request. For example, if virtual servers
|
|
C(vs1) and C(vs2) have the same IP pattern, C(0.0.100.128), but different IP masks of C(0.0.255.255) and
|
|
C(0.0.224.255), a destination IP address of C(198.51.100.128) has the longest match with the IP pattern of
|
|
vs1. If a destination IP address matches two or more virtual servers to the same extent, the request
|
|
is processed by the virtual server whose port number matches the port number in the request.
|
|
|
|
ipmask:
|
|
description:
|
|
- >-
|
|
IP mask, in dotted decimal notation, for the IP Pattern parameter. Can have leading or trailing
|
|
non-zero octets (for example, C(255.255.240.0) or C(0.0.255.255)). Accordingly, the mask specifies whether
|
|
the first n bits or the last n bits of the destination IP address in a client request are to be
|
|
matched with the corresponding bits in the IP pattern. The former is called a forward mask. The
|
|
latter is called a reverse mask.
|
|
|
|
port:
|
|
description:
|
|
- "Port number for the virtual server."
|
|
- "Range C(1) - C(65535)"
|
|
- "* in CLI is represented as C(65535) in NITRO API"
|
|
|
|
range:
|
|
description:
|
|
- >-
|
|
Number of IP addresses that the appliance must generate and assign to the virtual server. The virtual
|
|
server then functions as a network virtual server, accepting traffic on any of the generated IP
|
|
addresses. The IP addresses are generated automatically, as follows:
|
|
- >-
|
|
* For a range of n, the last octet of the address specified by the IP Address parameter increments
|
|
n-1 times.
|
|
- "* If the last octet exceeds 255, it rolls over to 0 and the third octet increments by 1."
|
|
- >-
|
|
Note: The Range parameter assigns multiple IP addresses to one virtual server. To generate an array
|
|
of virtual servers, each of which owns only one IP address, use brackets in the IP Address and Name
|
|
parameters to specify the range. For example:
|
|
- "add lb vserver my_vserver[1-3] HTTP 192.0.2.[1-3] 80."
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(254)"
|
|
|
|
persistencetype:
|
|
choices:
|
|
- 'SOURCEIP'
|
|
- 'COOKIEINSERT'
|
|
- 'SSLSESSION'
|
|
- 'RULE'
|
|
- 'URLPASSIVE'
|
|
- 'CUSTOMSERVERID'
|
|
- 'DESTIP'
|
|
- 'SRCIPDESTIP'
|
|
- 'CALLID'
|
|
- 'RTSPSID'
|
|
- 'DIAMETER'
|
|
- 'FIXSESSION'
|
|
- 'NONE'
|
|
description:
|
|
- "Type of persistence for the virtual server. Available settings function as follows:"
|
|
- "* C(SOURCEIP) - Connections from the same client IP address belong to the same persistence session."
|
|
- >-
|
|
* C(COOKIEINSERT) - Connections that have the same HTTP Cookie, inserted by a Set-Cookie directive from
|
|
a server, belong to the same persistence session.
|
|
- "* C(SSLSESSION) - Connections that have the same SSL Session ID belong to the same persistence session."
|
|
- >-
|
|
* C(CUSTOMSERVERID) - Connections with the same server ID form part of the same session. For this
|
|
persistence type, set the Server ID (CustomServerID) parameter for each service and configure the
|
|
Rule parameter to identify the server ID in a request.
|
|
- "* C(RULE) - All connections that match a user defined rule belong to the same persistence session."
|
|
- >-
|
|
* C(URLPASSIVE) - Requests that have the same server ID in the URL query belong to the same persistence
|
|
session. The server ID is the hexadecimal representation of the IP address and port of the service to
|
|
which the request must be forwarded. This persistence type requires a rule to identify the server ID
|
|
in the request.
|
|
- "* C(DESTIP) - Connections to the same destination IP address belong to the same persistence session."
|
|
- >-
|
|
* C(SRCIPDESTIP) - Connections that have the same source IP address and destination IP address belong to
|
|
the same persistence session.
|
|
- "* C(CALLID) - Connections that have the same CALL-ID SIP header belong to the same persistence session."
|
|
- "* C(RTSPSID) - Connections that have the same RTSP Session ID belong to the same persistence session."
|
|
- >-
|
|
* FIXSESSION - Connections that have the same SenderCompID and TargetCompID values belong to the same
|
|
persistence session.
|
|
|
|
timeout:
|
|
description:
|
|
- "Time period for which a persistence session is in effect."
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(1440)"
|
|
|
|
persistencebackup:
|
|
choices:
|
|
- 'SOURCEIP'
|
|
- 'NONE'
|
|
description:
|
|
- >-
|
|
Backup persistence type for the virtual server. Becomes operational if the primary persistence
|
|
mechanism fails.
|
|
|
|
backuppersistencetimeout:
|
|
description:
|
|
- "Time period for which backup persistence is in effect."
|
|
- "Minimum value = C(2)"
|
|
- "Maximum value = C(1440)"
|
|
|
|
lbmethod:
|
|
choices:
|
|
- 'ROUNDROBIN'
|
|
- 'LEASTCONNECTION'
|
|
- 'LEASTRESPONSETIME'
|
|
- 'URLHASH'
|
|
- 'DOMAINHASH'
|
|
- 'DESTINATIONIPHASH'
|
|
- 'SOURCEIPHASH'
|
|
- 'SRCIPDESTIPHASH'
|
|
- 'LEASTBANDWIDTH'
|
|
- 'LEASTPACKETS'
|
|
- 'TOKEN'
|
|
- 'SRCIPSRCPORTHASH'
|
|
- 'LRTM'
|
|
- 'CALLIDHASH'
|
|
- 'CUSTOMLOAD'
|
|
- 'LEASTREQUEST'
|
|
- 'AUDITLOGHASH'
|
|
- 'STATICPROXIMITY'
|
|
description:
|
|
- "Load balancing method. The available settings function as follows:"
|
|
- >-
|
|
* C(ROUNDROBIN) - Distribute requests in rotation, regardless of the load. Weights can be assigned to
|
|
services to enforce weighted round robin distribution.
|
|
- "* C(LEASTCONNECTION) (default) - Select the service with the fewest connections."
|
|
- "* C(LEASTRESPONSETIME) - Select the service with the lowest average response time."
|
|
- "* C(LEASTBANDWIDTH) - Select the service currently handling the least traffic."
|
|
- "* C(LEASTPACKETS) - Select the service currently serving the lowest number of packets per second."
|
|
- "* C(CUSTOMLOAD) - Base service selection on the SNMP metrics obtained by custom load monitors."
|
|
- >-
|
|
* C(LRTM) - Select the service with the lowest response time. Response times are learned through
|
|
monitoring probes. This method also takes the number of active connections into account.
|
|
- >-
|
|
Also available are a number of hashing methods, in which the appliance extracts a predetermined
|
|
portion of the request, creates a hash of the portion, and then checks whether any previous requests
|
|
had the same hash value. If it finds a match, it forwards the request to the service that served
|
|
those previous requests. Following are the hashing methods:
|
|
- "* C(URLHASH) - Create a hash of the request URL (or part of the URL)."
|
|
- >-
|
|
* C(DOMAINHASH) - Create a hash of the domain name in the request (or part of the domain name). The
|
|
domain name is taken from either the URL or the Host header. If the domain name appears in both
|
|
locations, the URL is preferred. If the request does not contain a domain name, the load balancing
|
|
method defaults to C(LEASTCONNECTION).
|
|
- "* C(DESTINATIONIPHASH) - Create a hash of the destination IP address in the IP header."
|
|
- "* C(SOURCEIPHASH) - Create a hash of the source IP address in the IP header."
|
|
- >-
|
|
* C(TOKEN) - Extract a token from the request, create a hash of the token, and then select the service
|
|
to which any previous requests with the same token hash value were sent.
|
|
- >-
|
|
* C(SRCIPDESTIPHASH) - Create a hash of the string obtained by concatenating the source IP address and
|
|
destination IP address in the IP header.
|
|
- "* C(SRCIPSRCPORTHASH) - Create a hash of the source IP address and source port in the IP header."
|
|
- "* C(CALLIDHASH) - Create a hash of the SIP Call-ID header."
|
|
|
|
hashlength:
|
|
description:
|
|
- >-
|
|
Number of bytes to consider for the hash value used in the URLHASH and DOMAINHASH load balancing
|
|
methods.
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(4096)"
|
|
|
|
netmask:
|
|
description:
|
|
- >-
|
|
IPv4 subnet mask to apply to the destination IP address or source IP address when the load balancing
|
|
method is C(DESTINATIONIPHASH) or C(SOURCEIPHASH).
|
|
- "Minimum length = 1"
|
|
|
|
v6netmasklen:
|
|
description:
|
|
- >-
|
|
Number of bits to consider in an IPv6 destination or source IP address, for creating the hash that is
|
|
required by the C(DESTINATIONIPHASH) and C(SOURCEIPHASH) load balancing methods.
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(128)"
|
|
|
|
backuplbmethod:
|
|
choices:
|
|
- 'ROUNDROBIN'
|
|
- 'LEASTCONNECTION'
|
|
- 'LEASTRESPONSETIME'
|
|
- 'SOURCEIPHASH'
|
|
- 'LEASTBANDWIDTH'
|
|
- 'LEASTPACKETS'
|
|
- 'CUSTOMLOAD'
|
|
description:
|
|
- "Backup load balancing method. Becomes operational if the primary load balancing me"
|
|
- "thod fails or cannot be used."
|
|
- "Valid only if the primary method is based on static proximity."
|
|
|
|
cookiename:
|
|
description:
|
|
- >-
|
|
Use this parameter to specify the cookie name for C(COOKIE) persistence type. It specifies the name of
|
|
cookie with a maximum of 32 characters. If not specified, cookie name is internally generated.
|
|
|
|
|
|
listenpolicy:
|
|
description:
|
|
- >-
|
|
Default syntax expression identifying traffic accepted by the virtual server. Can be either an
|
|
expression (for example, C(CLIENT.IP.DST.IN_SUBNET(192.0.2.0/24)) or the name of a named expression. In
|
|
the above example, the virtual server accepts all requests whose destination IP address is in the
|
|
192.0.2.0/24 subnet.
|
|
|
|
listenpriority:
|
|
description:
|
|
- >-
|
|
Integer specifying the priority of the listen policy. A higher number specifies a lower priority. If
|
|
a request matches the listen policies of more than one virtual server the virtual server whose listen
|
|
policy has the highest priority (the lowest priority number) accepts the request.
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(101)"
|
|
|
|
resrule:
|
|
description:
|
|
- >-
|
|
Default syntax expression specifying which part of a server's response to use for creating rule based
|
|
persistence sessions (persistence type RULE). Can be either an expression or the name of a named
|
|
expression.
|
|
- "Example:"
|
|
- 'C(HTTP.RES.HEADER("setcookie").VALUE(0).TYPECAST_NVLIST_T("=",";").VALUE("server1")).'
|
|
|
|
persistmask:
|
|
description:
|
|
- "Persistence mask for IP based persistence types, for IPv4 virtual servers."
|
|
- "Minimum length = 1"
|
|
|
|
v6persistmasklen:
|
|
description:
|
|
- "Persistence mask for IP based persistence types, for IPv6 virtual servers."
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(128)"
|
|
|
|
rtspnat:
|
|
description:
|
|
- "Use network address translation (NAT) for RTSP data connections."
|
|
type: bool
|
|
|
|
m:
|
|
choices:
|
|
- 'IP'
|
|
- 'MAC'
|
|
- 'IPTUNNEL'
|
|
- 'TOS'
|
|
description:
|
|
- "Redirection mode for load balancing. Available settings function as follows:"
|
|
- >-
|
|
* C(IP) - Before forwarding a request to a server, change the destination IP address to the server's IP
|
|
address.
|
|
- >-
|
|
* C(MAC) - Before forwarding a request to a server, change the destination MAC address to the server's
|
|
MAC address. The destination IP address is not changed. MAC-based redirection mode is used mostly in
|
|
firewall load balancing deployments.
|
|
- >-
|
|
* C(IPTUNNEL) - Perform IP-in-IP encapsulation for client IP packets. In the outer IP headers, set the
|
|
destination IP address to the IP address of the server and the source IP address to the subnet IP
|
|
(SNIP). The client IP packets are not modified. Applicable to both IPv4 and IPv6 packets.
|
|
- "* C(TOS) - Encode the virtual server's TOS ID in the TOS field of the IP header."
|
|
- "You can use either the C(IPTUNNEL) or the C(TOS) option to implement Direct Server Return (DSR)."
|
|
|
|
tosid:
|
|
description:
|
|
- >-
|
|
TOS ID of the virtual server. Applicable only when the load balancing redirection mode is set to TOS.
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(63)"
|
|
|
|
datalength:
|
|
description:
|
|
- >-
|
|
Length of the token to be extracted from the data segment of an incoming packet, for use in the token
|
|
method of load balancing. The length of the token, specified in bytes, must not be greater than 24
|
|
KB. Applicable to virtual servers of type TCP.
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(100)"
|
|
|
|
dataoffset:
|
|
description:
|
|
- >-
|
|
Offset to be considered when extracting a token from the TCP payload. Applicable to virtual servers,
|
|
of type TCP, using the token method of load balancing. Must be within the first 24 KB of the TCP
|
|
payload.
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(25400)"
|
|
|
|
sessionless:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- >-
|
|
Perform load balancing on a per-packet basis, without establishing sessions. Recommended for load
|
|
balancing of intrusion detection system (IDS) servers and scenarios involving direct server return
|
|
(DSR), where session information is unnecessary.
|
|
|
|
connfailover:
|
|
choices:
|
|
- 'DISABLED'
|
|
- 'STATEFUL'
|
|
- 'STATELESS'
|
|
description:
|
|
- >-
|
|
Mode in which the connection failover feature must operate for the virtual server. After a failover,
|
|
established TCP connections and UDP packet flows are kept active and resumed on the secondary
|
|
appliance. Clients remain connected to the same servers. Available settings function as follows:
|
|
- >-
|
|
* C(STATEFUL) - The primary appliance shares state information with the secondary appliance, in real
|
|
time, resulting in some runtime processing overhead.
|
|
- >-
|
|
* C(STATELESS) - State information is not shared, and the new primary appliance tries to re-create the
|
|
packet flow on the basis of the information contained in the packets it receives.
|
|
- "* C(DISABLED) - Connection failover does not occur."
|
|
|
|
redirurl:
|
|
description:
|
|
- "URL to which to redirect traffic if the virtual server becomes unavailable."
|
|
- >-
|
|
WARNING! Make sure that the domain in the URL does not match the domain specified for a content
|
|
switching policy. If it does, requests are continuously redirected to the unavailable virtual server.
|
|
- "Minimum length = 1"
|
|
|
|
cacheable:
|
|
description:
|
|
- >-
|
|
Route cacheable requests to a cache redirection virtual server. The load balancing virtual server can
|
|
forward requests only to a transparent cache redirection virtual server that has an IP address and
|
|
port combination of *:80, so such a cache redirection virtual server must be configured on the
|
|
appliance.
|
|
type: bool
|
|
|
|
clttimeout:
|
|
description:
|
|
- "Idle time, in seconds, after which a client connection is terminated."
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(31536000)"
|
|
|
|
somethod:
|
|
choices:
|
|
- 'CONNECTION'
|
|
- 'DYNAMICCONNECTION'
|
|
- 'BANDWIDTH'
|
|
- 'HEALTH'
|
|
- 'NONE'
|
|
description:
|
|
- "Type of threshold that, when exceeded, triggers spillover. Available settings function as follows:"
|
|
- "* C(CONNECTION) - Spillover occurs when the number of client connections exceeds the threshold."
|
|
- >-
|
|
* DYNAMICCONNECTION - Spillover occurs when the number of client connections at the virtual server
|
|
exceeds the sum of the maximum client (Max Clients) settings for bound services. Do not specify a
|
|
spillover threshold for this setting, because the threshold is implied by the Max Clients settings of
|
|
bound services.
|
|
- >-
|
|
* C(BANDWIDTH) - Spillover occurs when the bandwidth consumed by the virtual server's incoming and
|
|
outgoing traffic exceeds the threshold.
|
|
- >-
|
|
* C(HEALTH) - Spillover occurs when the percentage of weights of the services that are UP drops below
|
|
the threshold. For example, if services svc1, svc2, and svc3 are bound to a virtual server, with
|
|
weights 1, 2, and 3, and the spillover threshold is 50%, spillover occurs if svc1 and svc3 or svc2
|
|
and svc3 transition to DOWN.
|
|
- "* C(NONE) - Spillover does not occur."
|
|
|
|
sopersistence:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- >-
|
|
If spillover occurs, maintain source IP address based persistence for both primary and backup virtual
|
|
servers.
|
|
|
|
sopersistencetimeout:
|
|
description:
|
|
- "Timeout for spillover persistence, in minutes."
|
|
- "Minimum value = C(2)"
|
|
- "Maximum value = C(1440)"
|
|
|
|
healththreshold:
|
|
description:
|
|
- >-
|
|
Threshold in percent of active services below which vserver state is made down. If this threshold is
|
|
0, vserver state will be up even if one bound service is up.
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(100)"
|
|
|
|
sothreshold:
|
|
description:
|
|
- >-
|
|
Threshold at which spillover occurs. Specify an integer for the C(CONNECTION) spillover method, a
|
|
bandwidth value in kilobits per second for the C(BANDWIDTH) method (do not enter the units), or a
|
|
percentage for the C(HEALTH) method (do not enter the percentage symbol).
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(4294967287)"
|
|
|
|
sobackupaction:
|
|
choices:
|
|
- 'DROP'
|
|
- 'ACCEPT'
|
|
- 'REDIRECT'
|
|
description:
|
|
- >-
|
|
Action to be performed if spillover is to take effect, but no backup chain to spillover is usable or
|
|
exists.
|
|
|
|
redirectportrewrite:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- "Rewrite the port and change the protocol to ensure successful HTTP redirects from services."
|
|
|
|
downstateflush:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- >-
|
|
Flush all active transactions associated with a virtual server whose state transitions from UP to
|
|
DOWN. Do not enable this option for applications that must complete their transactions.
|
|
|
|
disableprimaryondown:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- >-
|
|
If the primary virtual server goes down, do not allow it to return to primary status until manually
|
|
enabled.
|
|
|
|
insertvserveripport:
|
|
choices:
|
|
- 'OFF'
|
|
- 'VIPADDR'
|
|
- 'V6TOV4MAPPING'
|
|
description:
|
|
- >-
|
|
Insert an HTTP header, whose value is the IP address and port number of the virtual server, before
|
|
forwarding a request to the server. The format of the header is <vipHeader>: <virtual server IP
|
|
address>_<port number >, where vipHeader is the name that you specify for the header. If the virtual
|
|
server has an IPv6 address, the address in the header is enclosed in brackets ([ and ]) to separate
|
|
it from the port number. If you have mapped an IPv4 address to a virtual server's IPv6 address, the
|
|
value of this parameter determines which IP address is inserted in the header, as follows:
|
|
- >-
|
|
* C(VIPADDR) - Insert the IP address of the virtual server in the HTTP header regardless of whether the
|
|
virtual server has an IPv4 address or an IPv6 address. A mapped IPv4 address, if configured, is
|
|
ignored.
|
|
- >-
|
|
* C(V6TOV4MAPPING) - Insert the IPv4 address that is mapped to the virtual server's IPv6 address. If a
|
|
mapped IPv4 address is not configured, insert the IPv6 address.
|
|
- "* C(OFF) - Disable header insertion."
|
|
|
|
vipheader:
|
|
description:
|
|
- "Name for the inserted header. The default name is vip-header."
|
|
- "Minimum length = 1"
|
|
|
|
authenticationhost:
|
|
description:
|
|
- >-
|
|
Fully qualified domain name (FQDN) of the authentication virtual server to which the user must be
|
|
redirected for authentication. Make sure that the Authentication parameter is set to C(yes).
|
|
- "Minimum length = 3"
|
|
- "Maximum length = 252"
|
|
|
|
authentication:
|
|
description:
|
|
- "Enable or disable user authentication."
|
|
type: bool
|
|
|
|
authn401:
|
|
description:
|
|
- "Enable or disable user authentication with HTTP 401 responses."
|
|
type: bool
|
|
|
|
authnvsname:
|
|
description:
|
|
- "Name of an authentication virtual server with which to authenticate users."
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 252"
|
|
|
|
push:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- "Process traffic with the push virtual server that is bound to this load balancing virtual server."
|
|
|
|
pushvserver:
|
|
description:
|
|
- >-
|
|
Name of the load balancing virtual server, of type PUSH or SSL_PUSH, to which the server pushes
|
|
updates received on the load balancing virtual server that you are configuring.
|
|
- "Minimum length = 1"
|
|
|
|
pushlabel:
|
|
description:
|
|
- >-
|
|
Expression for extracting a label from the server's response. Can be either an expression or the name
|
|
of a named expression.
|
|
|
|
pushmulticlients:
|
|
description:
|
|
- >-
|
|
Allow multiple Web 2.0 connections from the same client to connect to the virtual server and expect
|
|
updates.
|
|
type: bool
|
|
|
|
tcpprofilename:
|
|
description:
|
|
- "Name of the TCP profile whose settings are to be applied to the virtual server."
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 127"
|
|
|
|
httpprofilename:
|
|
description:
|
|
- "Name of the HTTP profile whose settings are to be applied to the virtual server."
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 127"
|
|
|
|
dbprofilename:
|
|
description:
|
|
- "Name of the DB profile whose settings are to be applied to the virtual server."
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 127"
|
|
|
|
comment:
|
|
description:
|
|
- "Any comments that you might want to associate with the virtual server."
|
|
|
|
l2conn:
|
|
description:
|
|
- >-
|
|
Use Layer 2 parameters (channel number, MAC address, and VLAN ID) in addition to the 4-tuple (<source
|
|
IP>:<source port>::<destination IP>:<destination port>) that is used to identify a connection. Allows
|
|
multiple TCP and non-TCP connections with the same 4-tuple to co-exist on the NetScaler appliance.
|
|
type: bool
|
|
|
|
oracleserverversion:
|
|
choices:
|
|
- '10G'
|
|
- '11G'
|
|
description:
|
|
- "Oracle server version."
|
|
|
|
mssqlserverversion:
|
|
choices:
|
|
- '70'
|
|
- '2000'
|
|
- '2000SP1'
|
|
- '2005'
|
|
- '2008'
|
|
- '2008R2'
|
|
- '2012'
|
|
- '2014'
|
|
description:
|
|
- >-
|
|
For a load balancing virtual server of type C(MSSQL), the Microsoft SQL Server version. Set this
|
|
parameter if you expect some clients to run a version different from the version of the database.
|
|
This setting provides compatibility between the client-side and server-side connections by ensuring
|
|
that all communication conforms to the server's version.
|
|
|
|
mysqlprotocolversion:
|
|
description:
|
|
- "MySQL protocol version that the virtual server advertises to clients."
|
|
|
|
mysqlserverversion:
|
|
description:
|
|
- "MySQL server version string that the virtual server advertises to clients."
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 31"
|
|
|
|
mysqlcharacterset:
|
|
description:
|
|
- "Character set that the virtual server advertises to clients."
|
|
|
|
mysqlservercapabilities:
|
|
description:
|
|
- "Server capabilities that the virtual server advertises to clients."
|
|
|
|
appflowlog:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- "Apply AppFlow logging to the virtual server."
|
|
|
|
netprofile:
|
|
description:
|
|
- >-
|
|
Name of the network profile to associate with the virtual server. If you set this parameter, the
|
|
virtual server uses only the IP addresses in the network profile as source IP addresses when
|
|
initiating connections with servers.
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 127"
|
|
|
|
icmpvsrresponse:
|
|
choices:
|
|
- 'PASSIVE'
|
|
- 'ACTIVE'
|
|
description:
|
|
- >-
|
|
How the NetScaler appliance responds to ping requests received for an IP address that is common to
|
|
one or more virtual servers. Available settings function as follows:
|
|
- >-
|
|
* If set to C(PASSIVE) on all the virtual servers that share the IP address, the appliance always
|
|
responds to the ping requests.
|
|
- >-
|
|
* If set to C(ACTIVE) on all the virtual servers that share the IP address, the appliance responds to
|
|
the ping requests if at least one of the virtual servers is UP. Otherwise, the appliance does not
|
|
respond.
|
|
- >-
|
|
* If set to C(ACTIVE) on some virtual servers and PASSIVE on the others, the appliance responds if at
|
|
least one virtual server with the ACTIVE setting is UP. Otherwise, the appliance does not respond.
|
|
- >-
|
|
Note: This parameter is available at the virtual server level. A similar parameter, ICMP Response, is
|
|
available at the IP address level, for IPv4 addresses of type VIP. To set that parameter, use the add
|
|
ip command in the CLI or the Create IP dialog box in the GUI.
|
|
|
|
rhistate:
|
|
choices:
|
|
- 'PASSIVE'
|
|
- 'ACTIVE'
|
|
description:
|
|
- >-
|
|
Route Health Injection (RHI) functionality of the NetSaler appliance for advertising the route of the
|
|
VIP address associated with the virtual server. When Vserver RHI Level (RHI) parameter is set to
|
|
VSVR_CNTRLD, the following are different RHI behaviors for the VIP address on the basis of RHIstate
|
|
(RHI STATE) settings on the virtual servers associated with the VIP address:
|
|
- >-
|
|
* If you set C(rhistate) to C(PASSIVE) on all virtual servers, the NetScaler ADC always advertises the
|
|
route for the VIP address.
|
|
- >-
|
|
* If you set C(rhistate) to C(ACTIVE) on all virtual servers, the NetScaler ADC advertises the route for
|
|
the VIP address if at least one of the associated virtual servers is in UP state.
|
|
- >-
|
|
* If you set C(rhistate) to C(ACTIVE) on some and PASSIVE on others, the NetScaler ADC advertises the
|
|
route for the VIP address if at least one of the associated virtual servers, whose C(rhistate) set to
|
|
C(ACTIVE), is in UP state.
|
|
|
|
newservicerequest:
|
|
description:
|
|
- >-
|
|
Number of requests, or percentage of the load on existing services, by which to increase the load on
|
|
a new service at each interval in slow-start mode. A non-zero value indicates that slow-start is
|
|
applicable. A zero value indicates that the global RR startup parameter is applied. Changing the
|
|
value to zero will cause services currently in slow start to take the full traffic as determined by
|
|
the LB method. Subsequently, any new services added will use the global RR factor.
|
|
|
|
newservicerequestunit:
|
|
choices:
|
|
- 'PER_SECOND'
|
|
- 'PERCENT'
|
|
description:
|
|
- "Units in which to increment load at each interval in slow-start mode."
|
|
|
|
newservicerequestincrementinterval:
|
|
description:
|
|
- >-
|
|
Interval, in seconds, between successive increments in the load on a new service or a service whose
|
|
state has just changed from DOWN to UP. A value of 0 (zero) specifies manual slow start.
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(3600)"
|
|
|
|
minautoscalemembers:
|
|
description:
|
|
- "Minimum number of members expected to be present when vserver is used in Autoscale."
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(5000)"
|
|
|
|
maxautoscalemembers:
|
|
description:
|
|
- "Maximum number of members expected to be present when vserver is used in Autoscale."
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(5000)"
|
|
|
|
persistavpno:
|
|
description:
|
|
- "Persist AVP number for Diameter Persistency."
|
|
- "In case this AVP is not defined in Base RFC 3588 and it is nested inside a Grouped AVP,"
|
|
- "define a sequence of AVP numbers (max 3) in order of parent to child. So say persist AVP number X"
|
|
- "is nested inside AVP Y which is nested in Z, then define the list as Z Y X."
|
|
- "Minimum value = C(1)"
|
|
|
|
skippersistency:
|
|
choices:
|
|
- 'Bypass'
|
|
- 'ReLb'
|
|
- 'None'
|
|
description:
|
|
- >-
|
|
This argument decides the behavior incase the service which is selected from an existing persistence
|
|
session has reached threshold.
|
|
|
|
td:
|
|
description:
|
|
- >-
|
|
Integer value that uniquely identifies the traffic domain in which you want to configure the entity.
|
|
If you do not specify an ID, the entity becomes part of the default traffic domain, which has an ID
|
|
of 0.
|
|
- "Minimum value = C(0)"
|
|
- "Maximum value = C(4094)"
|
|
|
|
authnprofile:
|
|
description:
|
|
- "Name of the authentication profile to be used when authentication is turned on."
|
|
|
|
macmoderetainvlan:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- "This option is used to retain vlan information of incoming packet when macmode is enabled."
|
|
|
|
dbslb:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- "Enable database specific load balancing for MySQL and MSSQL service types."
|
|
|
|
dns64:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- "This argument is for enabling/disabling the C(dns64) on lbvserver."
|
|
|
|
bypassaaaa:
|
|
description:
|
|
- >-
|
|
If this option is enabled while resolving DNS64 query AAAA queries are not sent to back end dns
|
|
server.
|
|
type: bool
|
|
|
|
recursionavailable:
|
|
description:
|
|
- >-
|
|
When set to YES, this option causes the DNS replies from this vserver to have the RA bit turned on.
|
|
Typically one would set this option to YES, when the vserver is load balancing a set of DNS servers
|
|
thatsupport recursive queries.
|
|
type: bool
|
|
|
|
processlocal:
|
|
choices:
|
|
- 'enabled'
|
|
- 'disabled'
|
|
description:
|
|
- >-
|
|
By turning on this option packets destined to a vserver in a cluster will not under go any steering.
|
|
Turn this option for single packet request response mode or when the upstream device is performing a
|
|
proper RSS for connection based distribution.
|
|
|
|
dnsprofilename:
|
|
description:
|
|
- >-
|
|
Name of the DNS profile to be associated with the VServer. DNS profile properties will be applied to
|
|
the transactions processed by a VServer. This parameter is valid only for DNS and DNS-TCP VServers.
|
|
- "Minimum length = 1"
|
|
- "Maximum length = 127"
|
|
|
|
servicebindings:
|
|
description:
|
|
- List of services along with the weights that are load balanced.
|
|
- The following suboptions are available.
|
|
suboptions:
|
|
servicename:
|
|
description:
|
|
- "Service to bind to the virtual server."
|
|
- "Minimum length = 1"
|
|
weight:
|
|
description:
|
|
- "Weight to assign to the specified service."
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(100)"
|
|
|
|
servicegroupbindings:
|
|
description:
|
|
- List of service groups along with the weights that are load balanced.
|
|
- The following suboptions are available.
|
|
suboptions:
|
|
servicegroupname:
|
|
description:
|
|
- "The service group name bound to the selected load balancing virtual server."
|
|
weight:
|
|
description:
|
|
- >-
|
|
Integer specifying the weight of the service. A larger number specifies a greater weight. Defines the
|
|
capacity of the service relative to the other services in the load balancing configuration.
|
|
Determines the priority given to the service in load balancing decisions.
|
|
- "Minimum value = C(1)"
|
|
- "Maximum value = C(100)"
|
|
|
|
ssl_certkey:
|
|
description:
|
|
- The name of the ssl certificate that is bound to this service.
|
|
- The ssl certificate must already exist.
|
|
- Creating the certificate can be done with the M(netscaler_ssl_certkey) module.
|
|
- This option is only applicable only when C(servicetype) is C(SSL).
|
|
|
|
disabled:
|
|
description:
|
|
- When set to C(yes) the lb vserver will be disabled.
|
|
- When set to C(no) the lb vserver will be enabled.
|
|
- >-
|
|
Note that due to limitations of the underlying NITRO API a C(disabled) state change alone
|
|
does not cause the module result to report a changed status.
|
|
type: bool
|
|
default: 'no'
|
|
|
|
extends_documentation_fragment:
|
|
- community.general.netscaler
|
|
|
|
requirements:
|
|
- nitro python sdk
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
# Netscaler services service-http-1, service-http-2 must have been already created with the netscaler_service module
|
|
|
|
- name: Create a load balancing vserver bound to services
|
|
delegate_to: localhost
|
|
netscaler_lb_vserver:
|
|
nsip: 172.18.0.2
|
|
nitro_user: nsroot
|
|
nitro_pass: nsroot
|
|
validate_certs: no
|
|
|
|
state: present
|
|
|
|
name: lb_vserver_1
|
|
servicetype: HTTP
|
|
timeout: 12
|
|
ipv46: 6.93.3.3
|
|
port: 80
|
|
servicebindings:
|
|
- servicename: service-http-1
|
|
weight: 80
|
|
- servicename: service-http-2
|
|
weight: 20
|
|
|
|
# Service group service-group-1 must have been already created with the netscaler_servicegroup module
|
|
|
|
- name: Create load balancing vserver bound to servicegroup
|
|
delegate_to: localhost
|
|
netscaler_lb_vserver:
|
|
nsip: 172.18.0.2
|
|
nitro_user: nsroot
|
|
nitro_pass: nsroot
|
|
validate_certs: no
|
|
state: present
|
|
|
|
name: lb_vserver_2
|
|
servicetype: HTTP
|
|
ipv46: 6.92.2.2
|
|
port: 80
|
|
timeout: 10
|
|
servicegroupbindings:
|
|
- servicegroupname: service-group-1
|
|
'''
|
|
|
|
RETURN = '''
|
|
loglines:
|
|
description: list of logged messages by the module
|
|
returned: always
|
|
type: list
|
|
sample: ['message 1', 'message 2']
|
|
|
|
msg:
|
|
description: Message detailing the failure reason
|
|
returned: failure
|
|
type: str
|
|
sample: "Action does not exist"
|
|
|
|
diff:
|
|
description: List of differences between the actual configured object and the configuration specified in the module
|
|
returned: failure
|
|
type: dict
|
|
sample: { 'clttimeout': 'difference. ours: (float) 10.0 other: (float) 20.0' }
|
|
'''
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
from ansible_collections.community.general.plugins.module_utils.network.netscaler.netscaler import (
|
|
ConfigProxy,
|
|
get_nitro_client,
|
|
netscaler_common_arguments,
|
|
log,
|
|
loglines,
|
|
get_immutables_intersection,
|
|
ensure_feature_is_enabled
|
|
)
|
|
import copy
|
|
|
|
try:
|
|
from nssrc.com.citrix.netscaler.nitro.resource.config.lb.lbvserver import lbvserver
|
|
from nssrc.com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding import lbvserver_servicegroup_binding
|
|
from nssrc.com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding import lbvserver_service_binding
|
|
from nssrc.com.citrix.netscaler.nitro.resource.config.ssl.sslvserver_sslcertkey_binding import sslvserver_sslcertkey_binding
|
|
from nssrc.com.citrix.netscaler.nitro.exception.nitro_exception import nitro_exception
|
|
|
|
PYTHON_SDK_IMPORTED = True
|
|
except ImportError as e:
|
|
IMPORT_ERROR = str(e)
|
|
PYTHON_SDK_IMPORTED = False
|
|
|
|
|
|
def lb_vserver_exists(client, module):
|
|
log('Checking if lb vserver exists')
|
|
if lbvserver.count_filtered(client, 'name:%s' % module.params['name']) > 0:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def lb_vserver_identical(client, module, lbvserver_proxy):
|
|
log('Checking if configured lb vserver is identical')
|
|
lbvserver_list = lbvserver.get_filtered(client, 'name:%s' % module.params['name'])
|
|
if lbvserver_proxy.has_equal_attributes(lbvserver_list[0]):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def lb_vserver_diff(client, module, lbvserver_proxy):
|
|
lbvserver_list = lbvserver.get_filtered(client, 'name:%s' % module.params['name'])
|
|
return lbvserver_proxy.diff_object(lbvserver_list[0])
|
|
|
|
|
|
def get_configured_service_bindings(client, module):
|
|
log('Getting configured service bindings')
|
|
|
|
readwrite_attrs = [
|
|
'weight',
|
|
'name',
|
|
'servicename',
|
|
'servicegroupname'
|
|
]
|
|
readonly_attrs = [
|
|
'preferredlocation',
|
|
'vserverid',
|
|
'vsvrbindsvcip',
|
|
'servicetype',
|
|
'cookieipport',
|
|
'port',
|
|
'vsvrbindsvcport',
|
|
'curstate',
|
|
'ipv46',
|
|
'dynamicweight',
|
|
]
|
|
|
|
configured_bindings = {}
|
|
if 'servicebindings' in module.params and module.params['servicebindings'] is not None:
|
|
for binding in module.params['servicebindings']:
|
|
attribute_values_dict = copy.deepcopy(binding)
|
|
attribute_values_dict['name'] = module.params['name']
|
|
key = binding['servicename'].strip()
|
|
configured_bindings[key] = ConfigProxy(
|
|
actual=lbvserver_service_binding(),
|
|
client=client,
|
|
attribute_values_dict=attribute_values_dict,
|
|
readwrite_attrs=readwrite_attrs,
|
|
readonly_attrs=readonly_attrs,
|
|
)
|
|
return configured_bindings
|
|
|
|
|
|
def get_configured_servicegroup_bindings(client, module):
|
|
log('Getting configured service group bindings')
|
|
readwrite_attrs = [
|
|
'weight',
|
|
'name',
|
|
'servicename',
|
|
'servicegroupname',
|
|
]
|
|
readonly_attrs = []
|
|
|
|
configured_bindings = {}
|
|
|
|
if 'servicegroupbindings' in module.params and module.params['servicegroupbindings'] is not None:
|
|
for binding in module.params['servicegroupbindings']:
|
|
attribute_values_dict = copy.deepcopy(binding)
|
|
attribute_values_dict['name'] = module.params['name']
|
|
key = binding['servicegroupname'].strip()
|
|
configured_bindings[key] = ConfigProxy(
|
|
actual=lbvserver_servicegroup_binding(),
|
|
client=client,
|
|
attribute_values_dict=attribute_values_dict,
|
|
readwrite_attrs=readwrite_attrs,
|
|
readonly_attrs=readonly_attrs,
|
|
)
|
|
|
|
return configured_bindings
|
|
|
|
|
|
def get_actual_service_bindings(client, module):
|
|
log('Getting actual service bindings')
|
|
bindings = {}
|
|
try:
|
|
if lbvserver_service_binding.count(client, module.params['name']) == 0:
|
|
return bindings
|
|
except nitro_exception as e:
|
|
if e.errorcode == 258:
|
|
return bindings
|
|
else:
|
|
raise
|
|
|
|
bindigs_list = lbvserver_service_binding.get(client, module.params['name'])
|
|
|
|
for item in bindigs_list:
|
|
key = item.servicename
|
|
bindings[key] = item
|
|
|
|
return bindings
|
|
|
|
|
|
def get_actual_servicegroup_bindings(client, module):
|
|
log('Getting actual service group bindings')
|
|
bindings = {}
|
|
|
|
try:
|
|
if lbvserver_servicegroup_binding.count(client, module.params['name']) == 0:
|
|
return bindings
|
|
except nitro_exception as e:
|
|
if e.errorcode == 258:
|
|
return bindings
|
|
else:
|
|
raise
|
|
|
|
bindigs_list = lbvserver_servicegroup_binding.get(client, module.params['name'])
|
|
|
|
for item in bindigs_list:
|
|
key = item.servicegroupname
|
|
bindings[key] = item
|
|
|
|
return bindings
|
|
|
|
|
|
def service_bindings_identical(client, module):
|
|
log('service_bindings_identical')
|
|
|
|
# Compare service keysets
|
|
configured_service_bindings = get_configured_service_bindings(client, module)
|
|
service_bindings = get_actual_service_bindings(client, module)
|
|
configured_keyset = set(configured_service_bindings.keys())
|
|
service_keyset = set(service_bindings.keys())
|
|
if len(configured_keyset ^ service_keyset) > 0:
|
|
return False
|
|
|
|
# Compare service item to item
|
|
for key in configured_service_bindings.keys():
|
|
conf = configured_service_bindings[key]
|
|
serv = service_bindings[key]
|
|
log('s diff %s' % conf.diff_object(serv))
|
|
if not conf.has_equal_attributes(serv):
|
|
return False
|
|
|
|
# Fallthrough to success
|
|
return True
|
|
|
|
|
|
def servicegroup_bindings_identical(client, module):
|
|
log('servicegroup_bindings_identical')
|
|
|
|
# Compare servicegroup keysets
|
|
configured_servicegroup_bindings = get_configured_servicegroup_bindings(client, module)
|
|
servicegroup_bindings = get_actual_servicegroup_bindings(client, module)
|
|
configured_keyset = set(configured_servicegroup_bindings.keys())
|
|
service_keyset = set(servicegroup_bindings.keys())
|
|
log('len %s' % len(configured_keyset ^ service_keyset))
|
|
if len(configured_keyset ^ service_keyset) > 0:
|
|
return False
|
|
|
|
# Compare servicegroup item to item
|
|
for key in configured_servicegroup_bindings.keys():
|
|
conf = configured_servicegroup_bindings[key]
|
|
serv = servicegroup_bindings[key]
|
|
log('sg diff %s' % conf.diff_object(serv))
|
|
if not conf.has_equal_attributes(serv):
|
|
return False
|
|
|
|
# Fallthrough to success
|
|
return True
|
|
|
|
|
|
def sync_service_bindings(client, module):
|
|
log('sync_service_bindings')
|
|
|
|
actual_bindings = get_actual_service_bindings(client, module)
|
|
configured_bindigns = get_configured_service_bindings(client, module)
|
|
|
|
# Delete actual but not configured
|
|
delete_keys = list(set(actual_bindings.keys()) - set(configured_bindigns.keys()))
|
|
for key in delete_keys:
|
|
log('Deleting service binding %s' % key)
|
|
actual_bindings[key].servicegroupname = ''
|
|
actual_bindings[key].delete(client, actual_bindings[key])
|
|
|
|
# Add configured but not in actual
|
|
add_keys = list(set(configured_bindigns.keys()) - set(actual_bindings.keys()))
|
|
for key in add_keys:
|
|
log('Adding service binding %s' % key)
|
|
configured_bindigns[key].add()
|
|
|
|
# Update existing if changed
|
|
modify_keys = list(set(configured_bindigns.keys()) & set(actual_bindings.keys()))
|
|
for key in modify_keys:
|
|
if not configured_bindigns[key].has_equal_attributes(actual_bindings[key]):
|
|
log('Updating service binding %s' % key)
|
|
actual_bindings[key].servicegroupname = ''
|
|
actual_bindings[key].delete(client, actual_bindings[key])
|
|
configured_bindigns[key].add()
|
|
|
|
|
|
def sync_servicegroup_bindings(client, module):
|
|
log('sync_servicegroup_bindings')
|
|
|
|
actual_bindings = get_actual_servicegroup_bindings(client, module)
|
|
configured_bindigns = get_configured_servicegroup_bindings(client, module)
|
|
|
|
# Delete actual but not configured
|
|
delete_keys = list(set(actual_bindings.keys()) - set(configured_bindigns.keys()))
|
|
for key in delete_keys:
|
|
log('Deleting servicegroup binding %s' % key)
|
|
actual_bindings[key].servicename = None
|
|
actual_bindings[key].delete(client, actual_bindings[key])
|
|
|
|
# Add configured but not in actual
|
|
add_keys = list(set(configured_bindigns.keys()) - set(actual_bindings.keys()))
|
|
for key in add_keys:
|
|
log('Adding servicegroup binding %s' % key)
|
|
configured_bindigns[key].add()
|
|
|
|
# Update existing if changed
|
|
modify_keys = list(set(configured_bindigns.keys()) & set(actual_bindings.keys()))
|
|
for key in modify_keys:
|
|
if not configured_bindigns[key].has_equal_attributes(actual_bindings[key]):
|
|
log('Updating servicegroup binding %s' % key)
|
|
actual_bindings[key].servicename = None
|
|
actual_bindings[key].delete(client, actual_bindings[key])
|
|
configured_bindigns[key].add()
|
|
|
|
|
|
def ssl_certkey_bindings_identical(client, module):
|
|
log('Entering ssl_certkey_bindings_identical')
|
|
vservername = module.params['name']
|
|
|
|
if sslvserver_sslcertkey_binding.count(client, vservername) == 0:
|
|
bindings = []
|
|
else:
|
|
bindings = sslvserver_sslcertkey_binding.get(client, vservername)
|
|
|
|
log('Existing certs %s' % bindings)
|
|
|
|
if module.params['ssl_certkey'] is None:
|
|
if len(bindings) == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
else:
|
|
certificate_list = [item.certkeyname for item in bindings]
|
|
log('certificate_list %s' % certificate_list)
|
|
if certificate_list == [module.params['ssl_certkey']]:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def ssl_certkey_bindings_sync(client, module):
|
|
log('Syncing ssl certificates')
|
|
vservername = module.params['name']
|
|
if sslvserver_sslcertkey_binding.count(client, vservername) == 0:
|
|
bindings = []
|
|
else:
|
|
bindings = sslvserver_sslcertkey_binding.get(client, vservername)
|
|
log('bindings len is %s' % len(bindings))
|
|
|
|
# Delete existing bindings
|
|
for binding in bindings:
|
|
sslvserver_sslcertkey_binding.delete(client, binding)
|
|
|
|
# Add binding if appropriate
|
|
if module.params['ssl_certkey'] is not None:
|
|
binding = sslvserver_sslcertkey_binding()
|
|
binding.vservername = module.params['name']
|
|
binding.certkeyname = module.params['ssl_certkey']
|
|
sslvserver_sslcertkey_binding.add(client, binding)
|
|
|
|
|
|
def do_state_change(client, module, lbvserver_proxy):
|
|
if module.params['disabled']:
|
|
log('Disabling lb server')
|
|
result = lbvserver.disable(client, lbvserver_proxy.actual)
|
|
else:
|
|
log('Enabling lb server')
|
|
result = lbvserver.enable(client, lbvserver_proxy.actual)
|
|
return result
|
|
|
|
|
|
def main():
|
|
|
|
module_specific_arguments = dict(
|
|
name=dict(type='str'),
|
|
servicetype=dict(
|
|
type='str',
|
|
choices=[
|
|
'HTTP',
|
|
'FTP',
|
|
'TCP',
|
|
'UDP',
|
|
'SSL',
|
|
'SSL_BRIDGE',
|
|
'SSL_TCP',
|
|
'DTLS',
|
|
'NNTP',
|
|
'DNS',
|
|
'DHCPRA',
|
|
'ANY',
|
|
'SIP_UDP',
|
|
'SIP_TCP',
|
|
'SIP_SSL',
|
|
'DNS_TCP',
|
|
'RTSP',
|
|
'PUSH',
|
|
'SSL_PUSH',
|
|
'RADIUS',
|
|
'RDP',
|
|
'MYSQL',
|
|
'MSSQL',
|
|
'DIAMETER',
|
|
'SSL_DIAMETER',
|
|
'TFTP',
|
|
'ORACLE',
|
|
'SMPP',
|
|
'SYSLOGTCP',
|
|
'SYSLOGUDP',
|
|
'FIX',
|
|
'SSL_FIX',
|
|
]
|
|
),
|
|
ipv46=dict(type='str'),
|
|
ippattern=dict(type='str'),
|
|
ipmask=dict(type='str'),
|
|
port=dict(type='int'),
|
|
range=dict(type='float'),
|
|
persistencetype=dict(
|
|
type='str',
|
|
choices=[
|
|
'SOURCEIP',
|
|
'COOKIEINSERT',
|
|
'SSLSESSION',
|
|
'RULE',
|
|
'URLPASSIVE',
|
|
'CUSTOMSERVERID',
|
|
'DESTIP',
|
|
'SRCIPDESTIP',
|
|
'CALLID',
|
|
'RTSPSID',
|
|
'DIAMETER',
|
|
'FIXSESSION',
|
|
'NONE',
|
|
]
|
|
),
|
|
timeout=dict(type='float'),
|
|
persistencebackup=dict(
|
|
type='str',
|
|
choices=[
|
|
'SOURCEIP',
|
|
'NONE',
|
|
]
|
|
),
|
|
backuppersistencetimeout=dict(type='float'),
|
|
lbmethod=dict(
|
|
type='str',
|
|
choices=[
|
|
'ROUNDROBIN',
|
|
'LEASTCONNECTION',
|
|
'LEASTRESPONSETIME',
|
|
'URLHASH',
|
|
'DOMAINHASH',
|
|
'DESTINATIONIPHASH',
|
|
'SOURCEIPHASH',
|
|
'SRCIPDESTIPHASH',
|
|
'LEASTBANDWIDTH',
|
|
'LEASTPACKETS',
|
|
'TOKEN',
|
|
'SRCIPSRCPORTHASH',
|
|
'LRTM',
|
|
'CALLIDHASH',
|
|
'CUSTOMLOAD',
|
|
'LEASTREQUEST',
|
|
'AUDITLOGHASH',
|
|
'STATICPROXIMITY',
|
|
]
|
|
),
|
|
hashlength=dict(type='float'),
|
|
netmask=dict(type='str'),
|
|
v6netmasklen=dict(type='float'),
|
|
backuplbmethod=dict(
|
|
type='str',
|
|
choices=[
|
|
'ROUNDROBIN',
|
|
'LEASTCONNECTION',
|
|
'LEASTRESPONSETIME',
|
|
'SOURCEIPHASH',
|
|
'LEASTBANDWIDTH',
|
|
'LEASTPACKETS',
|
|
'CUSTOMLOAD',
|
|
]
|
|
),
|
|
cookiename=dict(type='str'),
|
|
listenpolicy=dict(type='str'),
|
|
listenpriority=dict(type='float'),
|
|
persistmask=dict(type='str'),
|
|
v6persistmasklen=dict(type='float'),
|
|
rtspnat=dict(type='bool'),
|
|
m=dict(
|
|
type='str',
|
|
choices=[
|
|
'IP',
|
|
'MAC',
|
|
'IPTUNNEL',
|
|
'TOS',
|
|
]
|
|
),
|
|
tosid=dict(type='float'),
|
|
datalength=dict(type='float'),
|
|
dataoffset=dict(type='float'),
|
|
sessionless=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
connfailover=dict(
|
|
type='str',
|
|
choices=[
|
|
'DISABLED',
|
|
'STATEFUL',
|
|
'STATELESS',
|
|
]
|
|
),
|
|
redirurl=dict(type='str'),
|
|
cacheable=dict(type='bool'),
|
|
clttimeout=dict(type='float'),
|
|
somethod=dict(
|
|
type='str',
|
|
choices=[
|
|
'CONNECTION',
|
|
'DYNAMICCONNECTION',
|
|
'BANDWIDTH',
|
|
'HEALTH',
|
|
'NONE',
|
|
]
|
|
),
|
|
sopersistence=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
sopersistencetimeout=dict(type='float'),
|
|
healththreshold=dict(type='float'),
|
|
sothreshold=dict(type='float'),
|
|
sobackupaction=dict(
|
|
type='str',
|
|
choices=[
|
|
'DROP',
|
|
'ACCEPT',
|
|
'REDIRECT',
|
|
]
|
|
),
|
|
redirectportrewrite=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
downstateflush=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
disableprimaryondown=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
insertvserveripport=dict(
|
|
type='str',
|
|
choices=[
|
|
'OFF',
|
|
'VIPADDR',
|
|
'V6TOV4MAPPING',
|
|
]
|
|
),
|
|
vipheader=dict(type='str'),
|
|
authenticationhost=dict(type='str'),
|
|
authentication=dict(type='bool'),
|
|
authn401=dict(type='bool'),
|
|
authnvsname=dict(type='str'),
|
|
push=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
pushvserver=dict(type='str'),
|
|
pushlabel=dict(type='str'),
|
|
pushmulticlients=dict(type='bool'),
|
|
tcpprofilename=dict(type='str'),
|
|
httpprofilename=dict(type='str'),
|
|
dbprofilename=dict(type='str'),
|
|
comment=dict(type='str'),
|
|
l2conn=dict(type='bool'),
|
|
oracleserverversion=dict(
|
|
type='str',
|
|
choices=[
|
|
'10G',
|
|
'11G',
|
|
]
|
|
),
|
|
mssqlserverversion=dict(
|
|
type='str',
|
|
choices=[
|
|
'70',
|
|
'2000',
|
|
'2000SP1',
|
|
'2005',
|
|
'2008',
|
|
'2008R2',
|
|
'2012',
|
|
'2014',
|
|
]
|
|
),
|
|
mysqlprotocolversion=dict(type='float'),
|
|
mysqlserverversion=dict(type='str'),
|
|
mysqlcharacterset=dict(type='float'),
|
|
mysqlservercapabilities=dict(type='float'),
|
|
appflowlog=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
netprofile=dict(type='str'),
|
|
icmpvsrresponse=dict(
|
|
type='str',
|
|
choices=[
|
|
'PASSIVE',
|
|
'ACTIVE',
|
|
]
|
|
),
|
|
rhistate=dict(
|
|
type='str',
|
|
choices=[
|
|
'PASSIVE',
|
|
'ACTIVE',
|
|
]
|
|
),
|
|
newservicerequest=dict(type='float'),
|
|
newservicerequestunit=dict(
|
|
type='str',
|
|
choices=[
|
|
'PER_SECOND',
|
|
'PERCENT',
|
|
]
|
|
),
|
|
newservicerequestincrementinterval=dict(type='float'),
|
|
minautoscalemembers=dict(type='float'),
|
|
maxautoscalemembers=dict(type='float'),
|
|
skippersistency=dict(
|
|
type='str',
|
|
choices=[
|
|
'Bypass',
|
|
'ReLb',
|
|
'None',
|
|
]
|
|
),
|
|
authnprofile=dict(type='str'),
|
|
macmoderetainvlan=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
dbslb=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
dns64=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
bypassaaaa=dict(type='bool'),
|
|
recursionavailable=dict(type='bool'),
|
|
processlocal=dict(
|
|
type='str',
|
|
choices=[
|
|
'enabled',
|
|
'disabled',
|
|
]
|
|
),
|
|
dnsprofilename=dict(type='str'),
|
|
)
|
|
|
|
hand_inserted_arguments = dict(
|
|
servicebindings=dict(type='list'),
|
|
servicegroupbindings=dict(type='list'),
|
|
ssl_certkey=dict(type='str'),
|
|
disabled=dict(
|
|
type='bool',
|
|
default=False
|
|
),
|
|
)
|
|
|
|
argument_spec = dict()
|
|
|
|
argument_spec.update(netscaler_common_arguments)
|
|
argument_spec.update(module_specific_arguments)
|
|
argument_spec.update(hand_inserted_arguments)
|
|
|
|
module = AnsibleModule(
|
|
argument_spec=argument_spec,
|
|
supports_check_mode=True,
|
|
)
|
|
module_result = dict(
|
|
changed=False,
|
|
failed=False,
|
|
loglines=loglines,
|
|
)
|
|
|
|
# Fail the module if imports failed
|
|
if not PYTHON_SDK_IMPORTED:
|
|
module.fail_json(msg='Could not load nitro python sdk')
|
|
|
|
# Fallthrough to rest of execution
|
|
client = get_nitro_client(module)
|
|
|
|
try:
|
|
client.login()
|
|
except nitro_exception as e:
|
|
msg = "nitro exception during login. errorcode=%s, message=%s" % (str(e.errorcode), e.message)
|
|
module.fail_json(msg=msg)
|
|
except Exception as e:
|
|
if str(type(e)) == "<class 'requests.exceptions.ConnectionError'>":
|
|
module.fail_json(msg='Connection error %s' % str(e))
|
|
elif str(type(e)) == "<class 'requests.exceptions.SSLError'>":
|
|
module.fail_json(msg='SSL Error %s' % str(e))
|
|
else:
|
|
module.fail_json(msg='Unexpected error during login %s' % str(e))
|
|
|
|
readwrite_attrs = [
|
|
'name',
|
|
'servicetype',
|
|
'ipv46',
|
|
'ippattern',
|
|
'ipmask',
|
|
'port',
|
|
'range',
|
|
'persistencetype',
|
|
'timeout',
|
|
'persistencebackup',
|
|
'backuppersistencetimeout',
|
|
'lbmethod',
|
|
'hashlength',
|
|
'netmask',
|
|
'v6netmasklen',
|
|
'backuplbmethod',
|
|
'cookiename',
|
|
'listenpolicy',
|
|
'listenpriority',
|
|
'persistmask',
|
|
'v6persistmasklen',
|
|
'rtspnat',
|
|
'm',
|
|
'tosid',
|
|
'datalength',
|
|
'dataoffset',
|
|
'sessionless',
|
|
'connfailover',
|
|
'redirurl',
|
|
'cacheable',
|
|
'clttimeout',
|
|
'somethod',
|
|
'sopersistence',
|
|
'sopersistencetimeout',
|
|
'healththreshold',
|
|
'sothreshold',
|
|
'sobackupaction',
|
|
'redirectportrewrite',
|
|
'downstateflush',
|
|
'disableprimaryondown',
|
|
'insertvserveripport',
|
|
'vipheader',
|
|
'authenticationhost',
|
|
'authentication',
|
|
'authn401',
|
|
'authnvsname',
|
|
'push',
|
|
'pushvserver',
|
|
'pushlabel',
|
|
'pushmulticlients',
|
|
'tcpprofilename',
|
|
'httpprofilename',
|
|
'dbprofilename',
|
|
'comment',
|
|
'l2conn',
|
|
'oracleserverversion',
|
|
'mssqlserverversion',
|
|
'mysqlprotocolversion',
|
|
'mysqlserverversion',
|
|
'mysqlcharacterset',
|
|
'mysqlservercapabilities',
|
|
'appflowlog',
|
|
'netprofile',
|
|
'icmpvsrresponse',
|
|
'rhistate',
|
|
'newservicerequest',
|
|
'newservicerequestunit',
|
|
'newservicerequestincrementinterval',
|
|
'minautoscalemembers',
|
|
'maxautoscalemembers',
|
|
'skippersistency',
|
|
'authnprofile',
|
|
'macmoderetainvlan',
|
|
'dbslb',
|
|
'dns64',
|
|
'bypassaaaa',
|
|
'recursionavailable',
|
|
'processlocal',
|
|
'dnsprofilename',
|
|
]
|
|
|
|
readonly_attrs = [
|
|
'value',
|
|
'ipmapping',
|
|
'ngname',
|
|
'type',
|
|
'curstate',
|
|
'effectivestate',
|
|
'status',
|
|
'lbrrreason',
|
|
'redirect',
|
|
'precedence',
|
|
'homepage',
|
|
'dnsvservername',
|
|
'domain',
|
|
'policyname',
|
|
'cachevserver',
|
|
'health',
|
|
'gotopriorityexpression',
|
|
'ruletype',
|
|
'groupname',
|
|
'cookiedomain',
|
|
'map',
|
|
'gt2gb',
|
|
'consolidatedlconn',
|
|
'consolidatedlconngbl',
|
|
'thresholdvalue',
|
|
'bindpoint',
|
|
'invoke',
|
|
'labeltype',
|
|
'labelname',
|
|
'version',
|
|
'totalservices',
|
|
'activeservices',
|
|
'statechangetimesec',
|
|
'statechangetimeseconds',
|
|
'statechangetimemsec',
|
|
'tickssincelaststatechange',
|
|
'isgslb',
|
|
'vsvrdynconnsothreshold',
|
|
'backupvserverstatus',
|
|
'__count',
|
|
]
|
|
|
|
immutable_attrs = [
|
|
'name',
|
|
'servicetype',
|
|
'ipv46',
|
|
'port',
|
|
'range',
|
|
'state',
|
|
'redirurl',
|
|
'vipheader',
|
|
'newservicerequestunit',
|
|
'td',
|
|
]
|
|
|
|
transforms = {
|
|
'rtspnat': ['bool_on_off'],
|
|
'authn401': ['bool_on_off'],
|
|
'bypassaaaa': ['bool_yes_no'],
|
|
'authentication': ['bool_on_off'],
|
|
'cacheable': ['bool_yes_no'],
|
|
'l2conn': ['bool_on_off'],
|
|
'pushmulticlients': ['bool_yes_no'],
|
|
'recursionavailable': ['bool_yes_no'],
|
|
'sessionless': [lambda v: v.upper()],
|
|
'sopersistence': [lambda v: v.upper()],
|
|
'redirectportrewrite': [lambda v: v.upper()],
|
|
'downstateflush': [lambda v: v.upper()],
|
|
'disableprimaryondown': [lambda v: v.upper()],
|
|
'push': [lambda v: v.upper()],
|
|
'appflowlog': [lambda v: v.upper()],
|
|
'macmoderetainvlan': [lambda v: v.upper()],
|
|
'dbslb': [lambda v: v.upper()],
|
|
'dns64': [lambda v: v.upper()],
|
|
'processlocal': [lambda v: v.upper()],
|
|
}
|
|
|
|
lbvserver_proxy = ConfigProxy(
|
|
actual=lbvserver(),
|
|
client=client,
|
|
attribute_values_dict=module.params,
|
|
readwrite_attrs=readwrite_attrs,
|
|
readonly_attrs=readonly_attrs,
|
|
immutable_attrs=immutable_attrs,
|
|
transforms=transforms,
|
|
)
|
|
|
|
try:
|
|
ensure_feature_is_enabled(client, 'LB')
|
|
if module.params['state'] == 'present':
|
|
log('Applying actions for state present')
|
|
|
|
if not lb_vserver_exists(client, module):
|
|
log('Add lb vserver')
|
|
if not module.check_mode:
|
|
lbvserver_proxy.add()
|
|
if module.params['save_config']:
|
|
client.save_config()
|
|
module_result['changed'] = True
|
|
elif not lb_vserver_identical(client, module, lbvserver_proxy):
|
|
|
|
# Check if we try to change value of immutable attributes
|
|
diff_dict = lb_vserver_diff(client, module, lbvserver_proxy)
|
|
immutables_changed = get_immutables_intersection(lbvserver_proxy, diff_dict.keys())
|
|
if immutables_changed != []:
|
|
msg = 'Cannot update immutable attributes %s. Must delete and recreate entity.' % (immutables_changed,)
|
|
module.fail_json(msg=msg, diff=diff_dict, **module_result)
|
|
|
|
log('Update lb vserver')
|
|
if not module.check_mode:
|
|
lbvserver_proxy.update()
|
|
if module.params['save_config']:
|
|
client.save_config()
|
|
module_result['changed'] = True
|
|
else:
|
|
log('Present noop')
|
|
|
|
if not service_bindings_identical(client, module):
|
|
if not module.check_mode:
|
|
sync_service_bindings(client, module)
|
|
if module.params['save_config']:
|
|
client.save_config()
|
|
module_result['changed'] = True
|
|
|
|
if not servicegroup_bindings_identical(client, module):
|
|
if not module.check_mode:
|
|
sync_servicegroup_bindings(client, module)
|
|
if module.params['save_config']:
|
|
client.save_config()
|
|
module_result['changed'] = True
|
|
|
|
if module.params['servicetype'] != 'SSL' and module.params['ssl_certkey'] is not None:
|
|
module.fail_json(msg='ssl_certkey is applicable only to SSL vservers', **module_result)
|
|
|
|
# Check if SSL certkey is sane
|
|
if module.params['servicetype'] == 'SSL':
|
|
if not ssl_certkey_bindings_identical(client, module):
|
|
if not module.check_mode:
|
|
ssl_certkey_bindings_sync(client, module)
|
|
|
|
module_result['changed'] = True
|
|
|
|
if not module.check_mode:
|
|
res = do_state_change(client, module, lbvserver_proxy)
|
|
if res.errorcode != 0:
|
|
msg = 'Error when setting disabled state. errorcode: %s message: %s' % (res.errorcode, res.message)
|
|
module.fail_json(msg=msg, **module_result)
|
|
|
|
# Sanity check
|
|
log('Sanity checks for state present')
|
|
if not module.check_mode:
|
|
if not lb_vserver_exists(client, module):
|
|
module.fail_json(msg='Did not create lb vserver', **module_result)
|
|
|
|
if not lb_vserver_identical(client, module, lbvserver_proxy):
|
|
msg = 'lb vserver is not configured correctly'
|
|
module.fail_json(msg=msg, diff=lb_vserver_diff(client, module, lbvserver_proxy), **module_result)
|
|
|
|
if not service_bindings_identical(client, module):
|
|
module.fail_json(msg='service bindings are not identical', **module_result)
|
|
|
|
if not servicegroup_bindings_identical(client, module):
|
|
module.fail_json(msg='servicegroup bindings are not identical', **module_result)
|
|
|
|
if module.params['servicetype'] == 'SSL':
|
|
if not ssl_certkey_bindings_identical(client, module):
|
|
module.fail_json(msg='sll certkey bindings not identical', **module_result)
|
|
|
|
elif module.params['state'] == 'absent':
|
|
log('Applying actions for state absent')
|
|
if lb_vserver_exists(client, module):
|
|
if not module.check_mode:
|
|
log('Delete lb vserver')
|
|
lbvserver_proxy.delete()
|
|
if module.params['save_config']:
|
|
client.save_config()
|
|
module_result['changed'] = True
|
|
else:
|
|
log('Absent noop')
|
|
module_result['changed'] = False
|
|
|
|
# Sanity check
|
|
log('Sanity checks for state absent')
|
|
if not module.check_mode:
|
|
if lb_vserver_exists(client, module):
|
|
module.fail_json(msg='lb vserver still exists', **module_result)
|
|
|
|
except nitro_exception as e:
|
|
msg = "nitro exception errorcode=%s, message=%s" % (str(e.errorcode), e.message)
|
|
module.fail_json(msg=msg, **module_result)
|
|
|
|
client.logout()
|
|
module.exit_json(**module_result)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|