示例#1
0
 def rmcsvserver_bulk(self, client):
     try:
         csvs = [csvserver() for _ in range(5)]
         for i in range(0, 5):
             csvs[i].name = "csvserver" + str(i)
         csvserver.delete(client, csvs)
         print("rmcsvserver_bulk::rc= done")
     except nitro_exception as e:
         print("Exception::rmcsvserver_bulk::rc=" + str(e.errorcode) + " , Message =" + e.message)
     except Exception as e:
         print("Exception::rmcsvserver_bulk::message=" + str(e.args))
示例#2
0
def call_nitro_commands(ns_session):
    try:
        ns_session.clear_config(force=True, level='full')
        logging.debug('Clear config executed')
        needed_features = [
            nsfeature.Feature.CS, nsfeature.Feature.LB, nsfeature.Feature.SSL,
            nsfeature.Feature.RESPONDER, nsfeature.Feature.REWRITE
        ]
        ns_session.enable_features(needed_features)

        logging.debug('Adding CS vserver')
        csvserver_instance = csvserver()
        csvserver_instance.name = 'drinks_sample'
        csvserver_instance.ipv46 = '127.0.0.1'
        csvserver_instance.servicetype = 'http'
        csvserver_instance.port = '443'
        csvserver_instance.add(ns_session, csvserver_instance)

        logging.debug('Adding LB vserver')
        lbvserver_instance = lbvserver()
        lbvserver_instance.name = 'lbvs_hotdrink_http_example'
        lbvserver_instance.ipv46 = '0.0.0.0'
        lbvserver_instance.port = 0
        lbvserver_instance.servicetype = 'http'
        lbvserver_instance.add(ns_session, lbvserver_instance)

        logging.debug('Adding servicegroup')
        servicegroup_instance = servicegroup()
        servicegroup_instance.servicegroupname = 'sg_hotdrink_http_example'
        servicegroup_instance.servicetype = 'http'
        servicegroup_instance.add(ns_session, servicegroup_instance)

        logging.debug('Adding servieegroup binding')
        servicegroup_servicegroupmember_binding_instance = servicegroup_servicegroupmember_binding(
        )
        servicegroup_servicegroupmember_binding_instance.servicegroupname = 'sg_hotdrink_http_example'
        servicegroup_servicegroupmember_binding_instance.ip = '172.100.100.3'
        servicegroup_servicegroupmember_binding_instance.port = 80
        servicegroup_servicegroupmember_binding_instance.add(
            ns_session, servicegroup_servicegroupmember_binding_instance)

        logging.debug('Adding servicegroup lb vserver binding')
        lbvserver_servicegroup_binding_instance = lbvserver_servicegroup_binding(
        )
        lbvserver_servicegroup_binding_instance.name = 'lbvs_hotdrink_http_example'
        lbvserver_servicegroup_binding_instance.servicegroupname = 'sg_hotdrink_http_example'
        lbvserver_servicegroup_binding_instance.add(
            ns_session, lbvserver_servicegroup_binding_instance)

        logging.debug('SUCCESS: Configuration completed')
    except Exception as e:
        logging.error('FAILURE: Error during configuration: {}'.format(
            e.message))
示例#3
0
 def rmcsvserver_bulk(self, client):
     try:
         csvs = [csvserver() for _ in range(5)]
         for i in range(0, 5):
             csvs[i].name = "csvserver" + str(i)
         csvserver.delete(client, csvs)
         print("rmcsvserver_bulk::rc= done")
     except nitro_exception as e:
         print("Exception::rmcsvserver_bulk::rc=" + str(e.errorcode) +
               " , Message =" + e.message)
     except Exception as e:
         print("Exception::rmcsvserver_bulk::message=" + str(e.args))
    def add_csvserver(self, client,csvserverhttp,csvserverssl,cs_ip) :
        try :
            obj = csvserver()
            obj.name = csvserverhttp
            obj.servicetype = csvserver.Servicetype.HTTP
            obj.ipv46 = cs_ip
            obj.port = 80
            csvserver.add(client, obj)
            print("\nadd_csvserver "+obj.name+"- Done\n")

            obj1 = csvserver()
            obj1.name = csvserverssl
            obj1.servicetype = csvserver.Servicetype.SSL
            obj1.ipv46 = cs_ip
            obj1.port = 443
            csvserver.add(client, obj1)
            print("add_csvserver "+obj1.name+"- Done\n")

        except nitro_exception as e :
            print("Exception::add_csvserver::errorcode="+str(e.errorcode)+",message="+ e.message)
        except Exception as e:
            print("Exception::add_csvserver::message="+str(e.args))
示例#5
0
 def add_csvserver(self, client) :
     try :
         obj = csvserver()
         obj.name = "cs_vip"
         obj.servicetype = csvserver.Servicetype.HTTP
         obj.ipv46 = "9.1.1.8"
         obj.port = 80
         csvserver.add(client, obj)
         print("add_csvserver - Done")
     except nitro_exception as e :
         print("Exception::add_csvserver::errorcode="+str(e.errorcode)+",message="+ e.message)
     except Exception as e:
         print("Exception::add_csvserver::message="+str(e.args))
示例#6
0
    def _create_cs_vserver(self, cs_name, vip, port, service_type="HTTP"):
        try:
            cs = csvserver.get(self.ns_session, cs_name)
            if (cs.name == cs_name):
                logger.info("CS %s is already configured " % cs_name)
                return
        except nitro_exception:
            pass

        cs = csvserver()
        cs.name = cs_name
        cs.servicetype = service_type
        cs.ipv46 = vip
        cs.port = port
        csvserver.add(self.ns_session, cs)
def main():

    module_specific_arguments = dict(
        name=dict(type='str'),
        td=dict(type='float'),
        servicetype=dict(type='str',
                         choices=[
                             'HTTP', 'SSL', 'TCP', 'FTP', 'RTSP', 'SSL_TCP',
                             'UDP', 'DNS', 'SIP_UDP', 'SIP_TCP', 'SIP_SSL',
                             'ANY', 'RADIUS', 'RDP', 'MYSQL', 'MSSQL',
                             'DIAMETER', 'SSL_DIAMETER', 'DNS_TCP', 'ORACLE',
                             'SMPP'
                         ]),
        ipv46=dict(type='str'),
        dnsrecordtype=dict(type='str',
                           choices=[
                               'A',
                               'AAAA',
                               'CNAME',
                               'NAPTR',
                           ]),
        ippattern=dict(type='str'),
        ipmask=dict(type='str'),
        range=dict(type='float'),
        port=dict(type='int'),
        stateupdate=dict(type='str', choices=[
            'enabled',
            'disabled',
        ]),
        cacheable=dict(type='bool'),
        redirecturl=dict(type='str'),
        clttimeout=dict(type='float'),
        precedence=dict(type='str', choices=[
            'RULE',
            'URL',
        ]),
        casesensitive=dict(type='bool'),
        somethod=dict(type='str',
                      choices=[
                          'CONNECTION',
                          'DYNAMICCONNECTION',
                          'BANDWIDTH',
                          'HEALTH',
                          'NONE',
                      ]),
        sopersistence=dict(type='str', choices=[
            'enabled',
            'disabled',
        ]),
        sopersistencetimeout=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'),
        rtspnat=dict(type='bool'),
        authenticationhost=dict(type='str'),
        authentication=dict(type='bool'),
        listenpolicy=dict(type='str'),
        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'),
        oracleserverversion=dict(type='str', choices=[
            '10G',
            '11G',
        ]),
        comment=dict(type='str'),
        mssqlserverversion=dict(type='str',
                                choices=[
                                    '70',
                                    '2000',
                                    '2000SP1',
                                    '2005',
                                    '2008',
                                    '2008R2',
                                    '2012',
                                    '2014',
                                ]),
        l2conn=dict(type='bool'),
        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',
        ]),
        authnprofile=dict(type='str'),
        dnsprofilename=dict(type='str'),
    )

    hand_inserted_arguments = dict(
        policybindings=dict(type='list'),
        ssl_certkey=dict(type='str'),
        disabled=dict(type='bool', default=False),
        lbvserver=dict(type='str'),
    )

    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',
        'td',
        'servicetype',
        'ipv46',
        'dnsrecordtype',
        'ippattern',
        'ipmask',
        'range',
        'port',
        'stateupdate',
        'cacheable',
        'redirecturl',
        'clttimeout',
        'precedence',
        'casesensitive',
        'somethod',
        'sopersistence',
        'sopersistencetimeout',
        'sothreshold',
        'sobackupaction',
        'redirectportrewrite',
        'downstateflush',
        'disableprimaryondown',
        'insertvserveripport',
        'vipheader',
        'rtspnat',
        'authenticationhost',
        'authentication',
        'listenpolicy',
        'authn401',
        'authnvsname',
        'push',
        'pushvserver',
        'pushlabel',
        'pushmulticlients',
        'tcpprofilename',
        'httpprofilename',
        'dbprofilename',
        'oracleserverversion',
        'comment',
        'mssqlserverversion',
        'l2conn',
        'mysqlprotocolversion',
        'mysqlserverversion',
        'mysqlcharacterset',
        'mysqlservercapabilities',
        'appflowlog',
        'netprofile',
        'icmpvsrresponse',
        'rhistate',
        'authnprofile',
        'dnsprofilename',
    ]

    readonly_attrs = [
        'ip',
        'value',
        'ngname',
        'type',
        'curstate',
        'sc',
        'status',
        'cachetype',
        'redirect',
        'homepage',
        'dnsvservername',
        'domain',
        'policyname',
        'servicename',
        'weight',
        'cachevserver',
        'targetvserver',
        'priority',
        'url',
        'gotopriorityexpression',
        'bindpoint',
        'invoke',
        'labeltype',
        'labelname',
        'gt2gb',
        'statechangetimesec',
        'statechangetimemsec',
        'tickssincelaststatechange',
        'ruletype',
        'lbvserver',
        'targetlbvserver',
    ]

    immutable_attrs = [
        'name',
        'td',
        'servicetype',
        'ipv46',
        'targettype',
        'range',
        'port',
        'state',
        'vipheader',
        'newname',
    ]

    transforms = {
        'cacheable': ['bool_yes_no'],
        'rtspnat': ['bool_on_off'],
        'authn401': ['bool_on_off'],
        'casesensitive': ['bool_on_off'],
        'authentication': ['bool_on_off'],
        'l2conn': ['bool_on_off'],
        'pushmulticlients': ['bool_yes_no'],
        'stateupdate': [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()],
    }

    # Instantiate config proxy
    csvserver_proxy = ConfigProxy(
        actual=csvserver(),
        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, 'CS')

        # Apply appropriate state
        if module.params['state'] == 'present':
            log('Applying actions for state present')
            if not cs_vserver_exists(client, module):
                if not module.check_mode:
                    csvserver_proxy.add()
                    if module.params['save_config']:
                        client.save_config()
                module_result['changed'] = True
            elif not cs_vserver_identical(client, module, csvserver_proxy):

                # Check if we try to change value of immutable attributes
                immutables_changed = get_immutables_intersection(
                    csvserver_proxy,
                    diff_list(client, module, csvserver_proxy).keys())
                if immutables_changed != []:
                    module.fail_json(
                        msg='Cannot update immutable attributes %s' %
                        (immutables_changed, ),
                        diff=diff_list(client, module, csvserver_proxy),
                        **module_result)

                if not module.check_mode:
                    csvserver_proxy.update()
                    if module.params['save_config']:
                        client.save_config()
                module_result['changed'] = True
            else:
                module_result['changed'] = False

            # Check policybindings
            if not cs_policybindings_identical(client, module):
                if not module.check_mode:
                    sync_cs_policybindings(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 ssl certkey bindings
            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

            # Check default lb vserver
            if not default_lb_vserver_identical(client, module):
                if not module.check_mode:
                    sync_default_lb_vserver(client, module)
                module_result['changed'] = True

            if not module.check_mode:
                res = do_state_change(client, module, csvserver_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 for state
            if not module.check_mode:
                log('Sanity checks for state present')
                if not cs_vserver_exists(client, module):
                    module.fail_json(msg='CS vserver does not exist',
                                     **module_result)
                if not cs_vserver_identical(client, module, csvserver_proxy):
                    module.fail_json(msg='CS vserver differs from configured',
                                     diff=diff_list(client, module,
                                                    csvserver_proxy),
                                     **module_result)
                if not cs_policybindings_identical(client, module):
                    module.fail_json(msg='Policy bindings differ')

                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 cs_vserver_exists(client, module):
                if not module.check_mode:
                    csvserver_proxy.delete()
                    if module.params['save_config']:
                        client.save_config()
                module_result['changed'] = True
            else:
                module_result['changed'] = False

            # Sanity check for state
            if not module.check_mode:
                log('Sanity checks for state absent')
                if cs_vserver_exists(client, module):
                    module.fail_json(msg='CS 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)
示例#8
0
def main():
    from ansible.module_utils.netscaler import ConfigProxy, get_nitro_client, netscaler_common_arguments, log, loglines, ensure_feature_is_enabled
    try:
        from nssrc.com.citrix.netscaler.nitro.resource.config.cs.csvserver import csvserver
        from nssrc.com.citrix.netscaler.nitro.resource.config.cs.csvserver_cspolicy_binding import csvserver_cspolicy_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:
        python_sdk_imported = False

    module_specific_arguments = dict(
        name=dict(type='str'),
        td=dict(type='float'),
        servicetype=dict(type='str',
                         choices=[
                             u'HTTP', u'SSL', u'TCP', u'FTP', u'RTSP',
                             u'SSL_TCP', u'UDP', u'DNS', u'SIP_UDP',
                             u'SIP_TCP', u'SIP_SSL', u'ANY', u'RADIUS', u'RDP',
                             u'MYSQL', u'MSSQL', u'DIAMETER', u'SSL_DIAMETER',
                             u'DNS_TCP', u'ORACLE', u'SMPP'
                         ]),
        ipv46=dict(type='str'),
        dnsrecordtype=dict(type='str',
                           choices=[u'A', u'AAAA', u'CNAME', u'NAPTR']),
        ippattern=dict(type='str'),
        ipmask=dict(type='str'),
        range=dict(type='float'),
        port=dict(type='int'),
        stateupdate=dict(type='str', choices=[u'ENABLED', u'DISABLED']),
        cacheable=dict(type='str', choices=[u'YES', u'NO']),
        redirecturl=dict(type='str'),
        clttimeout=dict(type='float'),
        precedence=dict(type='str', choices=[u'RULE', u'URL']),
        casesensitive=dict(type='str', choices=[u'ON', u'OFF']),
        somethod=dict(type='str',
                      choices=[
                          u'CONNECTION', u'DYNAMICCONNECTION', u'BANDWIDTH',
                          u'HEALTH', u'NONE'
                      ]),
        sopersistence=dict(type='str', choices=[u'ENABLED', u'DISABLED']),
        sopersistencetimeout=dict(type='float'),
        sothreshold=dict(type='float'),
        sobackupaction=dict(type='str',
                            choices=[u'DROP', u'ACCEPT', u'REDIRECT']),
        redirectportrewrite=dict(type='str', choices=[u'ENABLED',
                                                      u'DISABLED']),
        downstateflush=dict(type='str', choices=[u'ENABLED', u'DISABLED']),
        disableprimaryondown=dict(type='str',
                                  choices=[u'ENABLED', u'DISABLED']),
        insertvserveripport=dict(
            type='str', choices=[u'OFF', u'VIPADDR', u'V6TOV4MAPPING']),
        vipheader=dict(type='str'),
        rtspnat=dict(type='str', choices=[u'ON', u'OFF']),
        authenticationhost=dict(type='str'),
        authentication=dict(type='str', choices=[u'ON', u'OFF']),
        listenpolicy=dict(type='str'),
        authn401=dict(type='str', choices=[u'ON', u'OFF']),
        authnvsname=dict(type='str'),
        push=dict(type='str', choices=[u'ENABLED', u'DISABLED']),
        pushvserver=dict(type='str'),
        pushlabel=dict(type='str'),
        pushmulticlients=dict(type='str', choices=[u'YES', u'NO']),
        tcpprofilename=dict(type='str'),
        httpprofilename=dict(type='str'),
        dbprofilename=dict(type='str'),
        oracleserverversion=dict(type='str', choices=[u'10G', u'11G']),
        comment=dict(type='str'),
        mssqlserverversion=dict(type='str',
                                choices=[
                                    u'70', u'2000', u'2000SP1', u'2005',
                                    u'2008', u'2008R2', u'2012', u'2014'
                                ]),
        l2conn=dict(type='str', choices=[u'ON', u'OFF']),
        mysqlprotocolversion=dict(type='float'),
        mysqlserverversion=dict(type='str'),
        mysqlcharacterset=dict(type='float'),
        mysqlservercapabilities=dict(type='float'),
        appflowlog=dict(type='str', choices=[u'ENABLED', u'DISABLED']),
        netprofile=dict(type='str'),
        icmpvsrresponse=dict(type='str', choices=[u'PASSIVE', u'ACTIVE']),
        rhistate=dict(type='str', choices=[u'PASSIVE', u'ACTIVE']),
        authnprofile=dict(type='str'),
        dnsprofilename=dict(type='str'),
    )

    hand_inserted_arguments = dict(
        policybindings=dict(type='list'),
        ssl_certkey=dict(type='str'),
    )

    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)
    client.login()

    # Instantiate Service Config object

    readwrite_attrs = [
        'name',
        'td',
        'servicetype',
        'ipv46',
        'dnsrecordtype',
        'ippattern',
        'ipmask',
        'range',
        'port',
        'stateupdate',
        'cacheable',
        'redirecturl',
        'clttimeout',
        'precedence',
        'casesensitive',
        'somethod',
        'sopersistence',
        'sopersistencetimeout',
        'sothreshold',
        'sobackupaction',
        'redirectportrewrite',
        'downstateflush',
        'disableprimaryondown',
        'insertvserveripport',
        'vipheader',
        'rtspnat',
        'authenticationhost',
        'authentication',
        'listenpolicy',
        'authn401',
        'authnvsname',
        'push',
        'pushvserver',
        'pushlabel',
        'pushmulticlients',
        'tcpprofilename',
        'httpprofilename',
        'dbprofilename',
        'oracleserverversion',
        'comment',
        'mssqlserverversion',
        'l2conn',
        'mysqlprotocolversion',
        'mysqlserverversion',
        'mysqlcharacterset',
        'mysqlservercapabilities',
        'appflowlog',
        'netprofile',
        'icmpvsrresponse',
        'rhistate',
        'authnprofile',
        'dnsprofilename',
    ]

    readonly_attrs = [
        'ip',
        'value',
        'ngname',
        'type',
        'curstate',
        'sc',
        'status',
        'cachetype',
        'redirect',
        'homepage',
        'dnsvservername',
        'domain',
        'policyname',
        'servicename',
        'weight',
        'cachevserver',
        'targetvserver',
        'priority',
        'url',
        'gotopriorityexpression',
        'bindpoint',
        'invoke',
        'labeltype',
        'labelname',
        'gt2gb',
        'statechangetimesec',
        'statechangetimemsec',
        'tickssincelaststatechange',
        'ruletype',
        'lbvserver',
        'targetlbvserver',
    ]
    csvserver_proxy = ConfigProxy(
        actual=csvserver(),
        client=client,
        attribute_values_dict=module.params,
        readwrite_attrs=readwrite_attrs,
        readonly_attrs=readonly_attrs,
    )

    def cs_vserver_exists():
        if csvserver.count_filtered(client,
                                    'name:%s' % module.params['name']) > 0:
            return True
        else:
            return False

    def cs_vserver_identical():
        csvserver_list = csvserver.get_filtered(
            client, 'name:%s' % module.params['name'])
        diff_dict = csvserver_proxy.diff_object(csvserver_list[0])
        if len(diff_dict) == 0:
            return True
        else:
            return False

    def get_configured_policybindings():
        bindings = {}
        if module.params['policybindings'] is None:
            return bindings

        for binding in module.params['policybindings']:
            binding['name'] = module.params['name']
            key = binding['policyname']
            binding_proxy = ConfigProxy(actual=csvserver_cspolicy_binding(),
                                        client=client,
                                        readwrite_attrs=[
                                            'priority',
                                            'bindpoint',
                                            'policyname',
                                            'labelname',
                                            'name',
                                            'gotopriorityexpression',
                                            'targetlbvserver',
                                            'invoke',
                                            'labeltype',
                                        ],
                                        readonly_attrs=[],
                                        attribute_values_dict=binding)
            bindings[key] = binding_proxy
        return bindings

    def get_actual_policybindings():
        bindings = {}
        if csvserver_cspolicy_binding.count(client,
                                            name=module.params['name']) == 0:
            return bindings

        for binding in csvserver_cspolicy_binding.get(
                client, name=module.params['name']):
            key = binding.policyname
            bindings[key] = binding

        return bindings

    def cs_policybindings_identical():
        actual_bindings = get_actual_policybindings()
        configured_bindings = get_configured_policybindings()

        actual_keyset = set(actual_bindings.keys())
        configured_keyset = set(configured_bindings.keys())
        if len(actual_keyset ^ configured_keyset) > 0:
            return False

        # Compare item to item
        for key in actual_bindings.keys():
            configured_binding_proxy = configured_bindings[key]
            actual_binding_object = actual_bindings[key]
            if not configured_binding_proxy.has_equal_attributes(
                    actual_binding_object):
                return False

        # Fallthrough to success
        return True

    def sync_cs_policybindings():

        # Delete all actual bindings
        for binding in get_actual_policybindings().values():
            csvserver_cspolicy_binding.delete(client, binding)

        # Add all configured bindings

        for binding in get_configured_policybindings().values():
            binding.add()

    def ssl_certkey_bindings_identical():
        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)

        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]
            if certificate_list == [module.params['ssl_certkey']]:
                return True
            else:
                return False

    def ssl_certkey_bindings_sync():
        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 diff_list():
        csvserver_list = csvserver.get_filtered(
            client, 'name:%s' % module.params['name'])
        return csvserver_proxy.diff_object(csvserver_list[0])

    try:
        ensure_feature_is_enabled(client, 'CS')

        # Apply appropriate operation
        if module.params['operation'] == 'present':
            if not cs_vserver_exists():
                if not module.check_mode:
                    csvserver_proxy.add()
                    client.save_config()
                module_result['changed'] = True
            elif not cs_vserver_identical():
                if not module.check_mode:
                    csvserver_proxy.update()
                    client.save_config()
                module_result['changed'] = True
            else:
                module_result['changed'] = False

            # Check policybindings
            if not cs_policybindings_identical():
                if not module.check_mode:
                    sync_cs_policybindings()
                    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 ssl certkey bindings
            if module.params['servicetype'] == 'SSL':
                if not ssl_certkey_bindings_identical():
                    if not module.check_mode:
                        ssl_certkey_bindings_sync()

                    module_result['changed'] = True

            # Sanity check for operation
            if not module.check_mode:
                if not cs_vserver_exists():
                    module.fail_json(msg='Service does not exist',
                                     **module_result)
                if not cs_vserver_identical():
                    module.fail_json(msg='Service differs from configured',
                                     diff=diff_list(),
                                     **module_result)
                if not cs_policybindings_identical():
                    module.fail_json(msg='Policy bindings differ')

                if module.params['servicetype'] == 'SSL':
                    if not ssl_certkey_bindings_identical():
                        module.fail_json(
                            msg='sll certkey bindings not identical',
                            **module_result)

        elif module.params['operation'] == 'absent':
            if cs_vserver_exists():
                if not module.check_mode:
                    csvserver_proxy.delete()
                    client.save_config()
                module_result['changed'] = True
            else:
                module_result['changed'] = False

            # Sanity check for operation
            if cs_vserver_exists():
                module.fail_json(msg='Service still exists', **module_result)

    except nitro_exception as e:
        msg = "nitro exception errorcode=" + str(
            e.errorcode) + ",message=" + e.message
        module.fail_json(msg=msg, **module_result)

    client.logout()
    module.exit_json(**module_result)
def main():

    module_specific_arguments = dict(

        name=dict(type='str'),
        td=dict(type='float'),
        servicetype=dict(
            type='str',
            choices=[
                'HTTP',
                'SSL',
                'TCP',
                'FTP',
                'RTSP',
                'SSL_TCP',
                'UDP',
                'DNS',
                'SIP_UDP',
                'SIP_TCP',
                'SIP_SSL',
                'ANY',
                'RADIUS',
                'RDP',
                'MYSQL',
                'MSSQL',
                'DIAMETER',
                'SSL_DIAMETER',
                'DNS_TCP',
                'ORACLE',
                'SMPP'
            ]
        ),

        ipv46=dict(type='str'),
        dnsrecordtype=dict(
            type='str',
            choices=[
                'A',
                'AAAA',
                'CNAME',
                'NAPTR',
            ]
        ),
        ippattern=dict(type='str'),
        ipmask=dict(type='str'),
        range=dict(type='float'),
        port=dict(type='int'),
        stateupdate=dict(
            type='str',
            choices=[
                'enabled',
                'disabled',
            ]
        ),
        cacheable=dict(type='bool'),
        redirecturl=dict(type='str'),
        clttimeout=dict(type='float'),
        precedence=dict(
            type='str',
            choices=[
                'RULE',
                'URL',
            ]
        ),
        casesensitive=dict(type='bool'),
        somethod=dict(
            type='str',
            choices=[
                'CONNECTION',
                'DYNAMICCONNECTION',
                'BANDWIDTH',
                'HEALTH',
                'NONE',
            ]
        ),
        sopersistence=dict(
            type='str',
            choices=[
                'enabled',
                'disabled',
            ]
        ),
        sopersistencetimeout=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'),
        rtspnat=dict(type='bool'),
        authenticationhost=dict(type='str'),
        authentication=dict(type='bool'),
        listenpolicy=dict(type='str'),
        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'),
        oracleserverversion=dict(
            type='str',
            choices=[
                '10G',
                '11G',
            ]
        ),
        comment=dict(type='str'),
        mssqlserverversion=dict(
            type='str',
            choices=[
                '70',
                '2000',
                '2000SP1',
                '2005',
                '2008',
                '2008R2',
                '2012',
                '2014',
            ]
        ),
        l2conn=dict(type='bool'),
        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',
            ]
        ),
        authnprofile=dict(type='str'),
        dnsprofilename=dict(type='str'),
    )

    hand_inserted_arguments = dict(
        policybindings=dict(type='list'),
        ssl_certkey=dict(type='str'),
        disabled=dict(
            type='bool',
            default=False
        ),
        lbvserver=dict(type='str'),
    )

    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',
        'td',
        'servicetype',
        'ipv46',
        'dnsrecordtype',
        'ippattern',
        'ipmask',
        'range',
        'port',
        'stateupdate',
        'cacheable',
        'redirecturl',
        'clttimeout',
        'precedence',
        'casesensitive',
        'somethod',
        'sopersistence',
        'sopersistencetimeout',
        'sothreshold',
        'sobackupaction',
        'redirectportrewrite',
        'downstateflush',
        'disableprimaryondown',
        'insertvserveripport',
        'vipheader',
        'rtspnat',
        'authenticationhost',
        'authentication',
        'listenpolicy',
        'authn401',
        'authnvsname',
        'push',
        'pushvserver',
        'pushlabel',
        'pushmulticlients',
        'tcpprofilename',
        'httpprofilename',
        'dbprofilename',
        'oracleserverversion',
        'comment',
        'mssqlserverversion',
        'l2conn',
        'mysqlprotocolversion',
        'mysqlserverversion',
        'mysqlcharacterset',
        'mysqlservercapabilities',
        'appflowlog',
        'netprofile',
        'icmpvsrresponse',
        'rhistate',
        'authnprofile',
        'dnsprofilename',
    ]

    readonly_attrs = [
        'ip',
        'value',
        'ngname',
        'type',
        'curstate',
        'sc',
        'status',
        'cachetype',
        'redirect',
        'homepage',
        'dnsvservername',
        'domain',
        'policyname',
        'servicename',
        'weight',
        'cachevserver',
        'targetvserver',
        'priority',
        'url',
        'gotopriorityexpression',
        'bindpoint',
        'invoke',
        'labeltype',
        'labelname',
        'gt2gb',
        'statechangetimesec',
        'statechangetimemsec',
        'tickssincelaststatechange',
        'ruletype',
        'lbvserver',
        'targetlbvserver',
    ]

    immutable_attrs = [
        'name',
        'td',
        'servicetype',
        'ipv46',
        'targettype',
        'range',
        'port',
        'state',
        'vipheader',
        'newname',
    ]

    transforms = {
        'cacheable': ['bool_yes_no'],
        'rtspnat': ['bool_on_off'],
        'authn401': ['bool_on_off'],
        'casesensitive': ['bool_on_off'],
        'authentication': ['bool_on_off'],
        'l2conn': ['bool_on_off'],
        'pushmulticlients': ['bool_yes_no'],
        'stateupdate': [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()],
    }

    # Instantiate config proxy
    csvserver_proxy = ConfigProxy(
        actual=csvserver(),
        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, 'CS')

        # Apply appropriate state
        if module.params['state'] == 'present':
            log('Applying actions for state present')
            if not cs_vserver_exists(client, module):
                if not module.check_mode:
                    csvserver_proxy.add()
                    if module.params['save_config']:
                        client.save_config()
                module_result['changed'] = True
            elif not cs_vserver_identical(client, module, csvserver_proxy):

                # Check if we try to change value of immutable attributes
                immutables_changed = get_immutables_intersection(csvserver_proxy, diff_list(client, module, csvserver_proxy).keys())
                if immutables_changed != []:
                    module.fail_json(
                        msg='Cannot update immutable attributes %s' % (immutables_changed,),
                        diff=diff_list(client, module, csvserver_proxy),
                        **module_result
                    )

                if not module.check_mode:
                    csvserver_proxy.update()
                    if module.params['save_config']:
                        client.save_config()
                module_result['changed'] = True
            else:
                module_result['changed'] = False

            # Check policybindings
            if not cs_policybindings_identical(client, module):
                if not module.check_mode:
                    sync_cs_policybindings(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 ssl certkey bindings
            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

            # Check default lb vserver
            if not default_lb_vserver_identical(client, module):
                if not module.check_mode:
                    sync_default_lb_vserver(client, module)
                module_result['changed'] = True

            if not module.check_mode:
                res = do_state_change(client, module, csvserver_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 for state
            if not module.check_mode:
                log('Sanity checks for state present')
                if not cs_vserver_exists(client, module):
                    module.fail_json(msg='CS vserver does not exist', **module_result)
                if not cs_vserver_identical(client, module, csvserver_proxy):
                    module.fail_json(msg='CS vserver differs from configured', diff=diff_list(client, module, csvserver_proxy), **module_result)
                if not cs_policybindings_identical(client, module):
                    module.fail_json(msg='Policy bindings differ')

                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 cs_vserver_exists(client, module):
                if not module.check_mode:
                    csvserver_proxy.delete()
                    if module.params['save_config']:
                        client.save_config()
                module_result['changed'] = True
            else:
                module_result['changed'] = False

            # Sanity check for state
            if not module.check_mode:
                log('Sanity checks for state absent')
                if cs_vserver_exists(client, module):
                    module.fail_json(msg='CS 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)