From a9f7d961f973ea027c88c2a728ac2ef36339f4ed Mon Sep 17 00:00:00 2001 From: tomclark0 Date: Tue, 23 Apr 2024 15:41:35 +0200 Subject: [PATCH 1/7] Add remaining network quota options --- plugins/modules/quota.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/plugins/modules/quota.py b/plugins/modules/quota.py index 572d1d7f..6b552cd9 100644 --- a/plugins/modules/quota.py +++ b/plugins/modules/quota.py @@ -20,6 +20,10 @@ backups: description: Maximum number of backups allowed. type: int + check_limit: + description: + - Flag to check the network quota usage before setting the new limit. + type: bool cores: description: Maximum number of CPU's per project. type: int @@ -38,6 +42,9 @@ groups: description: Number of groups that are allowed for the project type: int + health_monitors: + description: Maximum number of health monitors that can be created. + type: int injected_file_content_bytes: description: - Maximum file size in bytes. @@ -61,6 +68,12 @@ key_pairs: description: Number of key pairs to allow. type: int + l7_policies: + description: The maximum amount of L7 policies you can create. + type: int + listeners: + description: The maximum number of listeners you can create. + type: int load_balancers: description: The maximum amount of load balancers you can create type: int @@ -231,9 +244,24 @@ description: Network service quotas type: dict contains: + check_limit: + description: Flag to check the quota usage before setting + the new limit. + type: bool floating_ips: description: Number of floating IP's to allow. type: int + health_monitors: + description: Maximum number of health monitors that can be + created. + type: int + l7_policies: + description: The maximum amount of L7 policies you can + create. + type: int + listeners: + description: The maximum number of listeners you can create. + type: int load_balancers: description: The maximum amount of load balancers one can create @@ -312,6 +340,9 @@ server_groups: 10, network: floating_ips: 50, + health_monitors: 10, + l7_policies: 10, + listeners: 10, load_balancers: 10, networks: 10, pools: 10, @@ -337,12 +368,10 @@ class QuotaModule(OpenStackModule): - # TODO: Add missing network quota options 'check_limit', 'health_monitors', - # 'l7_policies', 'listeners' to argument_spec, DOCUMENTATION and - # RETURN docstrings argument_spec = dict( backup_gigabytes=dict(type='int'), backups=dict(type='int'), + check_limit=dict(type='bool'), cores=dict(type='int'), fixed_ips=dict(type='int'), floating_ips=dict( @@ -350,6 +379,7 @@ class QuotaModule(OpenStackModule): 'network_floating_ips']), gigabytes=dict(type='int'), groups=dict(type='int'), + health_monitors=dict(type='int'), injected_file_content_bytes=dict(type='int', aliases=['injected_file_size']), injected_file_path_bytes=dict(type='int', @@ -357,6 +387,8 @@ class QuotaModule(OpenStackModule): injected_files=dict(type='int'), instances=dict(type='int'), key_pairs=dict(type='int', no_log=False), + l7_policies=dict(type='int'), + listeners=dict(type='int'), load_balancers=dict(type='int', aliases=['loadbalancer']), metadata_items=dict(type='int'), name=dict(required=True), From 065e18e770209d171135eb7a30047d9b2866af45 Mon Sep 17 00:00:00 2001 From: Tom Clark Date: Wed, 24 Apr 2024 17:53:40 +0200 Subject: [PATCH 2/7] Towards loadbalancer quota support At this stage, support has been added for setting the pool and health_monitor quotas. --- plugins/modules/quota.py | 69 ++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/plugins/modules/quota.py b/plugins/modules/quota.py index 6b552cd9..d609f5d1 100644 --- a/plugins/modules/quota.py +++ b/plugins/modules/quota.py @@ -81,6 +81,9 @@ metadata_items: description: Number of metadata items allowed per instance. type: int + members: + description: Number of members allowed for loadbalancer. + type: int name: description: Name of the OpenStack Project to manage. required: true @@ -240,17 +243,10 @@ server_groups: description: Number of server groups to allow. type: int - network: - description: Network service quotas + load_balancer: + description: Load_balancer service quotas type: dict contains: - check_limit: - description: Flag to check the quota usage before setting - the new limit. - type: bool - floating_ips: - description: Number of floating IP's to allow. - type: int health_monitors: description: Maximum number of health monitors that can be created. @@ -266,12 +262,24 @@ description: The maximum amount of load balancers one can create type: int - networks: - description: Number of networks to allow. + aliases: [loadbalancer] + members: + description: The maximum amount of members for loadbalancers. type: int pools: description: The maximum amount of pools one can create. type: int + + network: + description: Network service quotas + type: dict + contains: + floating_ips: + description: Number of floating IP's to allow. + type: int + networks: + description: Number of networks to allow. + type: int ports: description: Number of Network ports to allow, this needs to be greater than the instances limit. @@ -340,12 +348,7 @@ server_groups: 10, network: floating_ips: 50, - health_monitors: 10, - l7_policies: 10, - listeners: 10, - load_balancers: 10, networks: 10, - pools: 10, ports: 160, rbac_policies: 10, routers: 10, @@ -361,6 +364,13 @@ per_volume_gigabytes: -1, snapshots: 10, volumes: 10, + load_balancer: + health_monitors: 10, + load_balancer: 10, + l7_policies: 10, + listeners: 10, + pool: 5, + members: 5, ''' from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule @@ -389,8 +399,9 @@ class QuotaModule(OpenStackModule): key_pairs=dict(type='int', no_log=False), l7_policies=dict(type='int'), listeners=dict(type='int'), - load_balancers=dict(type='int', aliases=['loadbalancer']), + load_balancers=dict(type='int'), aliases=['loadbalancer']), metadata_items=dict(type='int'), + members=dict(type='int'), name=dict(required=True), networks=dict(type='int', aliases=['network']), per_volume_gigabytes=dict(type='int'), @@ -429,7 +440,16 @@ class QuotaModule(OpenStackModule): # 'injected_file_path_bytes', # Nova API # 'injected_files', # version 2.56 }, - 'network': {'name'}, + 'load_balancer': {'name'}, + 'network': { + 'name', + 'l7_policies', + 'load_balancers', # Available only via load_balancer + 'health_monitors', # Available only via load_balancer + 'pools', # Available only via load_balancer + 'listeners', # Available only via load_balancer + 'listener', + }, 'volume': {'name'}, } @@ -441,12 +461,17 @@ def _get_quotas(self, project): self.warn('Block storage service aka volume service is not' ' supported by your cloud. Ignoring volume quotas.') + if self.conn.has_service('load_balancer'): # There is currently no has_service('load_balancer') + quota['load_balancer'] = self.conn.load_balancer.get_quota(project.id) + else: + self.warn('Loadbalancer service does not support detection. Trying anyway') + quota['load_balancer'] = self.conn.load_balancer.get_quota(project.id) + if self.conn.has_service('network'): quota['network'] = self.conn.network.get_quota(project.id) else: self.warn('Network service is not supported by your cloud.' ' Ignoring network quotas.') - quota['compute'] = self.conn.compute.get_quota_set(project.id) return quota @@ -484,7 +509,6 @@ def run(self): # Get current quota values quotas = self._get_quotas(project) - changed = False if self.ansible.check_mode: @@ -500,6 +524,9 @@ def run(self): self.conn.network.delete_quota(project.id) if 'volume' in quotas: self.conn.block_storage.revert_quota_set(project) + if 'load_balancer' in quotas: + self.conn.load_balancer.delete_quota(project.id) + # Necessary since we can't tell what the default quotas are quotas = self._get_quotas(project) @@ -517,6 +544,8 @@ def run(self): if 'network' in changes: quotas['network'] = self.conn.network.update_quota( project.id, **changes['network']) + if 'load_balancer' in changes: + quotas['load_balancer'] = self.conn.load_balancer.update_quota(project.id, **changes['load_balancer']) changed = True quotas = {k: v.to_dict(computed=False) for k, v in quotas.items()} From 8e82ca3c15ae907193ee0ddb3bdd47068ec48aa3 Mon Sep 17 00:00:00 2001 From: Tom Clark Date: Wed, 24 Apr 2024 17:55:48 +0200 Subject: [PATCH 3/7] Formatting --- plugins/modules/quota.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/modules/quota.py b/plugins/modules/quota.py index d609f5d1..746a07f1 100644 --- a/plugins/modules/quota.py +++ b/plugins/modules/quota.py @@ -399,7 +399,7 @@ class QuotaModule(OpenStackModule): key_pairs=dict(type='int', no_log=False), l7_policies=dict(type='int'), listeners=dict(type='int'), - load_balancers=dict(type='int'), aliases=['loadbalancer']), + load_balancers=dict(type='int', aliases=['loadbalancer']), metadata_items=dict(type='int'), members=dict(type='int'), name=dict(required=True), @@ -472,6 +472,7 @@ def _get_quotas(self, project): else: self.warn('Network service is not supported by your cloud.' ' Ignoring network quotas.') + quota['compute'] = self.conn.compute.get_quota_set(project.id) return quota From b505b267714e0660af69e438f3a38bd6434fb24a Mon Sep 17 00:00:00 2001 From: Tom Clark Date: Wed, 24 Apr 2024 23:17:48 +0200 Subject: [PATCH 4/7] Add correct service-name + style --- plugins/modules/quota.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/plugins/modules/quota.py b/plugins/modules/quota.py index 746a07f1..46a14394 100644 --- a/plugins/modules/quota.py +++ b/plugins/modules/quota.py @@ -77,7 +77,6 @@ load_balancers: description: The maximum amount of load balancers you can create type: int - aliases: [loadbalancer] metadata_items: description: Number of metadata items allowed per instance. type: int @@ -256,20 +255,20 @@ create. type: int listeners: - description: The maximum number of listeners you can create. + description: The maximum number of listeners you can create type: int load_balancers: description: The maximum amount of load balancers one can create type: int - aliases: [loadbalancer] members: - description: The maximum amount of members for loadbalancers. + description: The maximum amount of members for + loadbalancer. type: int pools: description: The maximum amount of pools one can create. type: int - + network: description: Network service quotas type: dict @@ -366,10 +365,10 @@ volumes: 10, load_balancer: health_monitors: 10, - load_balancer: 10, + load_balancers: 10, l7_policies: 10, listeners: 10, - pool: 5, + pools: 5, members: 5, ''' @@ -399,7 +398,7 @@ class QuotaModule(OpenStackModule): key_pairs=dict(type='int', no_log=False), l7_policies=dict(type='int'), listeners=dict(type='int'), - load_balancers=dict(type='int', aliases=['loadbalancer']), + load_balancers=dict(type='int'), metadata_items=dict(type='int'), members=dict(type='int'), name=dict(required=True), @@ -443,12 +442,12 @@ class QuotaModule(OpenStackModule): 'load_balancer': {'name'}, 'network': { 'name', - 'l7_policies', - 'load_balancers', # Available only via load_balancer + 'l7_policies', # Advertised but non-functional + 'load_balancers', # Advertised but non-functional + 'loadbalancer', # Advertised but non-functional 'health_monitors', # Available only via load_balancer 'pools', # Available only via load_balancer 'listeners', # Available only via load_balancer - 'listener', }, 'volume': {'name'}, } @@ -461,18 +460,18 @@ def _get_quotas(self, project): self.warn('Block storage service aka volume service is not' ' supported by your cloud. Ignoring volume quotas.') - if self.conn.has_service('load_balancer'): # There is currently no has_service('load_balancer') - quota['load_balancer'] = self.conn.load_balancer.get_quota(project.id) + if self.conn.has_service('load-balancer'): + quota['load_balancer'] = self.conn.load_balancer.get_quota( + project.id) else: - self.warn('Loadbalancer service does not support detection. Trying anyway') - quota['load_balancer'] = self.conn.load_balancer.get_quota(project.id) + self.warn('Loadbalancer service is not supported by your' + ' cloud. Ignoring loadbalancer quotas.') if self.conn.has_service('network'): quota['network'] = self.conn.network.get_quota(project.id) else: self.warn('Network service is not supported by your cloud.' ' Ignoring network quotas.') - quota['compute'] = self.conn.compute.get_quota_set(project.id) return quota @@ -527,7 +526,6 @@ def run(self): self.conn.block_storage.revert_quota_set(project) if 'load_balancer' in quotas: self.conn.load_balancer.delete_quota(project.id) - # Necessary since we can't tell what the default quotas are quotas = self._get_quotas(project) @@ -546,7 +544,9 @@ def run(self): quotas['network'] = self.conn.network.update_quota( project.id, **changes['network']) if 'load_balancer' in changes: - quotas['load_balancer'] = self.conn.load_balancer.update_quota(project.id, **changes['load_balancer']) + quotas['load_balancer'] = \ + self.conn.load_balancer.update_quota( + project.id, **changes['load_balancer']) changed = True quotas = {k: v.to_dict(computed=False) for k, v in quotas.items()} From 8e66dc3bebb6ccae0166b0c68ce4e0f0afa37eff Mon Sep 17 00:00:00 2001 From: Tom Clark Date: Wed, 24 Apr 2024 23:37:33 +0200 Subject: [PATCH 5/7] Return aliases + TODO --- plugins/modules/quota.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/modules/quota.py b/plugins/modules/quota.py index 46a14394..aa8f6cf2 100644 --- a/plugins/modules/quota.py +++ b/plugins/modules/quota.py @@ -70,13 +70,14 @@ type: int l7_policies: description: The maximum amount of L7 policies you can create. - type: int + type: int listeners: description: The maximum number of listeners you can create. type: int load_balancers: description: The maximum amount of load balancers you can create type: int + aliases: [loadbalancer] metadata_items: description: Number of metadata items allowed per instance. type: int @@ -377,6 +378,8 @@ class QuotaModule(OpenStackModule): + # TODO: Add missing network quota options 'check_limit', and 'l7_policies' + # to argument_spec, DOCUMENTATION and RETURN docstrings argument_spec = dict( backup_gigabytes=dict(type='int'), backups=dict(type='int'), @@ -398,7 +401,7 @@ class QuotaModule(OpenStackModule): key_pairs=dict(type='int', no_log=False), l7_policies=dict(type='int'), listeners=dict(type='int'), - load_balancers=dict(type='int'), + load_balancers=dict(type='int', aliases=['loadbalancer']), metadata_items=dict(type='int'), members=dict(type='int'), name=dict(required=True), From fff34f1f7e3d1ed9f8ddaa43287315a4cc5475f6 Mon Sep 17 00:00:00 2001 From: Tom Clark Date: Wed, 8 May 2024 14:49:21 +0200 Subject: [PATCH 6/7] Add default quota for tests --- ci/roles/quota/defaults/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ci/roles/quota/defaults/main.yml b/ci/roles/quota/defaults/main.yml index eafed1cd..fee1641e 100644 --- a/ci/roles/quota/defaults/main.yml +++ b/ci/roles/quota/defaults/main.yml @@ -28,3 +28,9 @@ test_compute_quota: ram: 5 server_group_members: 5 server_groups: 5 +test_loadbalancer_quota: + load_balancers: 5 + health_monitors: 5 + listeners: 5 + pools: 5 + members: 5 From 86e77cc3ea23b12ee1e382404cac61f502c34316 Mon Sep 17 00:00:00 2001 From: Tom Clark Date: Wed, 8 May 2024 14:58:32 +0200 Subject: [PATCH 7/7] Include loadbalancer quota in CI testing --- ci/roles/quota/tasks/main.yml | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/ci/roles/quota/tasks/main.yml b/ci/roles/quota/tasks/main.yml index 10475a93..3226c0da 100644 --- a/ci/roles/quota/tasks/main.yml +++ b/ci/roles/quota/tasks/main.yml @@ -79,6 +79,26 @@ openstack.cloud.quota: "{{ test_compute_quota }}" register: quotas + - name: Set load_balancer quotas + openstack.cloud.quotas: "{{ test_load_balancer_quota }}" + register: quotas + + - name: Assert changed + assert: + that: quotas is changed + + - name: Assert field values + assert: + that: quotas.quotas.load_balancer[item.key] == item.value + loop: "{{ test_load_balancer_quota | dict2items }}" + + - name: Set load_balancer quotas again + openstack.cloud.quota: "{{ test_load_balancer_quota }}" + + - name: Assert not changed + assert: + that: quotas is not changed + - name: Unset all quotas openstack.cloud.quota: state: absent @@ -90,7 +110,7 @@ - name: Set all quotas at once openstack.cloud.quota: - "{{ [test_network_quota, test_volume_quota, test_compute_quota] | combine }}" + "{{ [test_network_quota, test_volume_quota, test_compute_quota, test_load_balancer_quota] | combine }}" register: quotas - name: Assert changed @@ -112,9 +132,13 @@ that: quotas.quotas.compute[item.key] == item.value loop: "{{ test_compute_quota | dict2items }}" + - name: Assert load_balancer values + assert: + that: quotas.quotas.load_balancer[item.key] == item.value + - name: Set all quotas at once again openstack.cloud.quota: - "{{ [test_network_quota, test_volume_quota, test_compute_quota] | combine }}" + "{{ [test_network_quota, test_volume_quota, test_compute_quota, test_load_balancer_quota] | combine }}" register: quotas - name: Assert not changed