11# coding=utf-8
22#
3- # Copyright 2014-2016 F5 Networks Inc.
3+ # Copyright 2017 F5 Networks Inc.
44#
55# Licensed under the Apache License, Version 2.0 (the "License");
66# you may not use this file except in compliance with the License.
2424 ``cm:device:licensing:pool:regkey:licenses:*``
2525"""
2626
27+ import os
28+ import time
29+ import uuid
30+
2731from f5 .bigiq .resource import Collection
32+ from f5 .bigiq .resource import OrganizingCollection
2833from f5 .bigiq .resource import Resource
34+ from f5 .sdk_exception import F5SDKError
2935from f5 .sdk_exception import RequiredOneOf
3036from six import iterkeys
3137
3238
39+ class Regkey (OrganizingCollection ):
40+ def __init__ (self , pool ):
41+ super (Regkey , self ).__init__ (pool )
42+ self ._meta_data ['allowed_lazy_attributes' ] = [
43+ Licenses_s
44+ ]
45+
46+
3347class Licenses_s (Collection ):
3448 def __init__ (self , regkey ):
3549 super (Licenses_s , self ).__init__ (regkey )
3650 self ._meta_data ['required_json_kind' ] = \
3751 'cm:device:licensing:pool:regkey:licenses:regkeypoollicensecollectionstate' # NOQA
38- self ._meta_data ['allowed_lazy_attributes' ] = [License ]
52+ self ._meta_data ['allowed_lazy_attributes' ] = [Licenses ]
3953 self ._meta_data ['attribute_registry' ] = {
40- 'cm:device:licensing:pool:regkey:licenses:regkeypoollicensestate' : License # NOQA
54+ 'cm:device:licensing:pool:regkey:licenses:regkeypoollicensestate' : Licenses # NOQA
4155 }
4256
4357
44- class License (Resource ):
58+ class Licenses (Resource ):
4559 def __init__ (self , licenses_s ):
46- super (License , self ).__init__ (licenses_s )
60+ super (Licenses , self ).__init__ (licenses_s )
4761 self ._meta_data ['required_creation_parameters' ] = {'name' , }
4862 self ._meta_data ['required_json_kind' ] = \
4963 'cm:device:licensing:pool:regkey:licenses:regkeypoollicensestate'
@@ -60,20 +74,21 @@ def __init__(self, license):
6074 super (Offerings_s , self ).__init__ (license )
6175 self ._meta_data ['required_json_kind' ] = \
6276 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkeypoollicenseofferingcollectionstate' # NOQA
63- self ._meta_data ['allowed_lazy_attributes' ] = [Offering ]
77+ self ._meta_data ['allowed_lazy_attributes' ] = [Offerings ]
6478 self ._meta_data ['attribute_registry' ] = {
65- 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkeypoollicenseofferingstate' : Offering # NOQA
79+ 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkeypoollicenseofferingstate' : Offerings # NOQA
6680 }
6781
6882
69- class Offering (Resource ):
83+ class Offerings (Resource ):
7084 def __init__ (self , offerings_s ):
71- super (Offering , self ).__init__ (offerings_s )
85+ super (Offerings , self ).__init__ (offerings_s )
7286 self ._meta_data ['required_creation_parameters' ] = {'regKey' , }
7387 self ._meta_data ['required_json_kind' ] = \
7488 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkeypoollicenseofferingstate' # NOQA
89+ self ._meta_data ['allowed_lazy_attributes' ] = [Members_s ]
7590 self ._meta_data ['attribute_registry' ] = {
76- 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkeypoollicenseofferingstate ' : Offering # NOQA
91+ 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkey:members:regkeypoollicensemembercollectionstate ' : Members_s
7792 }
7893
7994
@@ -82,17 +97,16 @@ def __init__(self, pool):
8297 super (Members_s , self ).__init__ (pool )
8398 self ._meta_data ['required_json_kind' ] = \
8499 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkey:members:regkeypoollicensemembercollectionstate' # NOQA
85- self ._meta_data ['allowed_lazy_attributes' ] = [Member ]
100+ self ._meta_data ['allowed_lazy_attributes' ] = [Members ]
86101 self ._meta_data ['attribute_registry' ] = {
87- 'cm:shared :licensing:pools:licensepoolmemberstate ' : Member
102+ 'cm:device :licensing:pool:regkey:licenses:item:offerings:regkey:members:regkeypoollicensememberstate ' : Members
88103 }
89104
90105
91- class Member (Resource ):
106+ class Members (Resource ):
92107 def __init__ (self , members_s ):
93- super (Member , self ).__init__ (members_s )
94- self ._meta_data ['required_json_kind' ] = \
95- 'cm:shared:licensing:pools:licensepoolmemberstate'
108+ super (Members , self ).__init__ (members_s )
109+ self ._meta_data ['required_json_kind' ] = 'cm:device:licensing:pool:regkey:licenses:item:offerings:regkey:members:regkeypoollicensememberstate'
96110
97111 # This set is empty because the creation checking is done as
98112 # a required_one_of in the create() method
@@ -118,7 +132,7 @@ def create(self, **kwargs):
118132 raise RequiredOneOf (required_one_of )
119133
120134 def delete (self , ** kwargs ):
121- """Deletes a member from an unmanaged license pool
135+ """Deletes a member from a license pool
122136
123137 You need to be careful with this method. When you use it, and it
124138 succeeds on the remote BIG-IP, the configuration of the BIG-IP
@@ -132,17 +146,19 @@ def delete(self, **kwargs):
132146 :param kwargs:
133147 :return:
134148 """
135- if 'deviceAddress' in kwargs :
136- self ._delete_unmanaged_device (** kwargs )
137- else :
138- self ._delete_managed_device (** kwargs )
139-
140- def _delete_managed_device (self , ** kwargs ):
141- self ._delete (** kwargs )
142-
143- def _delete_unmanaged_device (self , ** kwargs ):
144- if 'uuid' not in kwargs :
145- kwargs ['uuid' ] = str (self .uuid )
149+ if 'id' not in kwargs :
150+ # BIG-IQ requires that you provide the ID of the members to revoke
151+ # a license from. This ID is already part of the deletion URL though.
152+ # Therefore, if you do not provide it, we enumerate it for you.
153+ delete_uri = self ._meta_data ['uri' ]
154+ if delete_uri .endswith ('/' ):
155+ delete_uri = delete_uri [0 :- 1 ]
156+ kwargs ['id' ] = os .path .basename (delete_uri )
157+ uid = uuid .UUID (kwargs ['id' ], version = 4 )
158+ if uid .hex != kwargs ['id' ].replace ('-' , '' ):
159+ raise F5SDKError (
160+ "The specified ID is invalid"
161+ )
146162
147163 requests_params = self ._handle_requests_params (kwargs )
148164 kwargs = self ._check_for_python_keywords (kwargs )
@@ -159,3 +175,10 @@ def _delete_unmanaged_device(self, **kwargs):
159175 response = session .delete (delete_uri , json = kwargs , ** requests_params )
160176 if response .status_code == 200 :
161177 self .__dict__ = {'deleted' : True }
178+
179+ # This sleep is necessary to prevent BIG-IQ from being able to remove
180+ # a license. It happens in certain cases that assignments can be revoked
181+ # (and license deletion started) too quickly. Therefore, we must introduce
182+ # an artificial delay here to prevent revoking from returning before
183+ # BIG-IQ would be ready to remove the license.
184+ time .sleep (1 )
0 commit comments