6262 - If C(false), SSL certificates will not be validated.
6363 type: bool
6464 default: true
65- request_pem :
65+ entitlement_name :
6666 description:
67- - The PEM entitlement identifier for the device (e.g. C(CNS_8905_SERVER)).
67+ - The full entitlement name for the device license (e.g. C(MPX 8905 Premium)).
68+ - Combines the device model and edition, with an optional C(FIPS) prefix for FIPS appliances.
6869 type: str
6970 required: true
70- request_ed:
71- description:
72- - The license edition.
73- type: str
74- required: true
75- choices:
76- - Advanced
77- - Premium
78- - Standard
7971 is_fips:
8072 description:
8173 - Set to C(true) for FIPS-enabled appliances.
9991 nitro_pass: "{{ nitro_pass }}"
10092 nitro_protocol: https
10193 validate_certs: false
102- request_pem: CNS_8905_SERVER
103- request_ed: Premium
94+ entitlement_name: MPX 8905 Premium
10495 is_fips: false
10596 las_secrets_json: /etc/netscaler/zmcd_secrets.json
10697
110101 nsip: 10.102.201.231
111102 nitro_user: nsroot
112103 nitro_pass: "{{ nitro_pass }}"
113- request_pem: CNS_V5000_SERVER
114- request_ed: Premium
104+ entitlement_name: FIPS VPX 5000 Premium
115105 is_fips: true
116106 las_secrets_json: /etc/netscaler/zmcd_secrets.json
117107
118- - name: Retrieve activation request package only ( for debugging)
108+ - name: Generate and apply offline LAS license for NS (MPX) Standard edition
119109 delegate_to: localhost
120110 netscaler.adc.nslaslicense_offline:
121111 nsip: 10.102.201.230
122112 nitro_user: nsroot
123113 nitro_pass: "{{ nitro_pass }}"
124- request_pem: CNS_8905_SERVER
125- request_ed: Standard
114+ entitlement_name: MPX 8905 Standard
126115 las_secrets_json: /etc/netscaler/zmcd_secrets.json
127116"""
128117
161150
162151from ..module_utils .las_utils import (
163152 HAS_PARAMIKO ,
164- MPX14K_PEMS ,
153+ LASClient ,
165154 NEW_API_MAPPING_FIPS ,
166155 NEW_API_MAPPING_NS ,
167156 NitroHelper ,
170159 check_ns_version ,
171160 extract_lsguid ,
172161 generate_offline_package ,
173- get_ent_name ,
174162 get_offline_request_package ,
175163)
176164
@@ -187,8 +175,7 @@ def main():
187175 nitro_pass = dict (required = True , type = "str" , no_log = True , fallback = (env_fallback , ["NETSCALER_NITRO_PASS" ])),
188176 nitro_protocol = dict (type = "str" , choices = ["http" , "https" ], default = "https" ),
189177 validate_certs = dict (type = "bool" , default = True , fallback = (env_fallback , ["NETSCALER_VALIDATE_CERTS" ])),
190- request_pem = dict (required = True , type = "str" ),
191- request_ed = dict (required = True , type = "str" , choices = ["Advanced" , "Premium" , "Standard" ]),
178+ entitlement_name = dict (required = True , type = "str" ),
192179 is_fips = dict (type = "bool" , default = False ),
193180 las_secrets_json = dict (required = True , type = "str" , no_log = False ),
194181 )
@@ -207,25 +194,72 @@ def main():
207194 ip = module .params ["nsip" ]
208195 username = module .params ["nitro_user" ]
209196 password = module .params ["nitro_pass" ]
210- request_pem = module .params ["request_pem" ]
211- request_ed = module .params ["request_ed" ]
197+ ent_name = module .params ["entitlement_name" ]
212198 is_fips = module .params ["is_fips" ]
213199 las_secrets_json = module .params ["las_secrets_json" ]
214200 if username != "nsroot" :
215201 module .fail_json (msg = "Only the 'nsroot' account is supported. Got: '{0}'" .format (username ), ** result )
216202
217- if is_fips and request_pem in MPX14K_PEMS :
218- module .fail_json (msg = "MPX 14K devices (CNS_14xxx) do not require the is_fips argument" , ** result )
219-
220203 if not os .path .isfile (las_secrets_json ):
221204 module .fail_json (msg = "las_secrets_json not found: {0}" .format (las_secrets_json ), ** result )
222205
223- ent_name = get_ent_name (request_pem , request_ed , is_fips , loglines )
224- if not ent_name :
206+ _valid_ent_prefixes = (
207+ "FIPS MPX 14" ,
208+ "FIPS MPS 15" ,
209+ "FIPS MPX 16" ,
210+ "FIPS MPS 89" ,
211+ "FIPS MPX 91" ,
212+ "FIPS MPX 92" ,
213+ "MPS 14" ,
214+ "MPX 15" ,
215+ "MPX 16" ,
216+ "MPX 17" ,
217+ "MPS 25" ,
218+ "MPX 26" ,
219+ "MPX 59" ,
220+ "MPX 89" ,
221+ "MPX 91" ,
222+ "MPX 92" ,
223+ "VPX" ,
224+ )
225+ if not ent_name .startswith (_valid_ent_prefixes ):
225226 module .fail_json (
226- msg = "Could not resolve entitlement name for pem={0}, ed={1}, fips={2}" .format (request_pem , request_ed , is_fips ),
227+ msg = "Invalid entitlement_name '{0}'. Must start with one of: {1}" .format (ent_name , ", " .join (_valid_ent_prefixes )),
228+ ** result ,
229+ )
230+
231+ # Derive LAS platform from the matched prefix (spaces → underscores)
232+ matched_prefix = next (p for p in _valid_ent_prefixes if ent_name .startswith (p ))
233+ platform = matched_prefix .replace (" " , "_" )
234+
235+ # Validate entitlement_name against customer entitlements from LAS
236+ las_client = LASClient ("" , las_secrets_json )
237+ bearer = las_client .validate_bearer_cache ()
238+ if not bearer :
239+ bearer = las_client .generate_bearer_token ()
240+ loglines .append ("INFO: New bearer token generated for entitlement validation" )
241+ else :
242+ loglines .append ("INFO: Using cached bearer token for entitlement validation" )
243+ if not bearer :
244+ module .fail_json (msg = "Failed to obtain bearer token from LAS to validate entitlement_name" , ** result )
245+
246+ ent_resp = las_client .get_customer_entitlements (bearer , platform , loglines )
247+ if ent_resp is None :
248+ module .fail_json (
249+ msg = "Failed to fetch customer entitlements from LAS for platform '{0}'" .format (platform ),
250+ ** result ,
251+ )
252+
253+ valid_entitlements = [e .get ("type" , "" ) for e in ent_resp .get ("entitlements" , [])]
254+ loglines .append ("INFO: Valid entitlements for platform '{0}': {1}" .format (platform , valid_entitlements ))
255+ if ent_name not in valid_entitlements :
256+ module .fail_json (
257+ msg = "entitlement_name '{0}' is not a valid customer entitlement for platform '{1}'. Valid entitlements: [{2}]" .format (
258+ ent_name , platform , ", " .join (valid_entitlements ) if valid_entitlements else "none found"
259+ ),
227260 ** result ,
228261 )
262+ loglines .append ("INFO: entitlement_name '{0}' validated successfully against LAS" .format (ent_name ))
229263
230264 nitro = NitroHelper (ip , module .params ["nitro_protocol" ], username , password , module .params ["validate_certs" ], loglines )
231265
0 commit comments