diff --git a/changelogs/fragments/147_lookup.yml b/changelogs/fragments/147_lookup.yml new file mode 100644 index 0000000000..8dfc2e10aa --- /dev/null +++ b/changelogs/fragments/147_lookup.yml @@ -0,0 +1,3 @@ +--- +bugfixes: +- lookup - recommend query instead of lookup (https://github.com/ansible-collections/kubernetes.core/issues/147). diff --git a/molecule/default/tasks/lookup_k8s.yml b/molecule/default/tasks/lookup_k8s.yml index 2ad21c0827..b5733c421d 100644 --- a/molecule/default/tasks/lookup_k8s.yml +++ b/molecule/default/tasks/lookup_k8s.yml @@ -1,6 +1,12 @@ --- - block: - # https://github.com/ansible-collections/kubernetes.core/issues/9 + - set_fact: + pre_test1: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + pre_test2: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}" + pre_test3: "{{ query('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + pre_test4: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}" + + # https://github.com/ansible-collections/kubernetes.core/issues/147 - name: Create a namespace with label kubernetes.core.k8s: definition: @@ -12,15 +18,45 @@ namespace_label: "app_development" - set_fact: - namespace_info: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + test1: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development', wantlist=True) }}" + test2: "{{ query('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + test3: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one', wantlist=True) }}" + test4: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}" + test5: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + test6: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}" + test7: "{{ lookup('kubernetes.core.k8s', kind='Ingress', api_version='networking.k8s.io/vINVALID', errors='ignore') }}" + + - set_fact: + test8: "{{ lookup('kubernetes.core.k8s', kind='Ingress', api_version='networking.k8s.io/vINVALID') }}" + ignore_errors: true - - name: Check if the returned value is list with a single element + - name: Assert that every test is passed assert: that: - - namespace_info is iterable - - not namespace_info is string - - not namespace_info is mapping - - namespace_info | length == 1 + # Before creating object + - pre_test1 is sequence and pre_test1 is not string + - pre_test1 | length == 0 + - pre_test2 is sequence and pre_test2 is not string + - pre_test2 | length == 0 + - pre_test3 is sequence and pre_test3 is not string + - pre_test3 | length == 0 + - pre_test4 is sequence and pre_test4 is not string + - pre_test4 | length == 0 + # After creating object + - test1 is sequence and test1 is not string + - test1 | length == 1 + - test2 is sequence and test2 is not string + - test2 | length == 1 + - test3 is sequence and test3 is not string + - test3 | length == 1 + - test4 is sequence and test4 is not string + - test4 | length == 1 + # Without wantlist=True lookup should return mapping + - test5 is mapping + - test6 is mapping + # errors='ignore' + - test7 is string + - test8 is not defined - name: Create another namespace with label kubernetes.core.k8s: @@ -33,22 +69,44 @@ namespace_label: "app_development" - set_fact: - namespace_info: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + test1: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development', wantlist=True) }}" + test2: "{{ query('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + test3: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one', wantlist=True) }}" + test4: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}" + test5: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-two', wantlist=True) }}" + test6: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-two') }}" + test7: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}" + test8: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}" + test9: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-two') }}" - - name: Check if the returned value is list with 2 elements + - name: Assert that every test is passed after creating second object assert: that: - - namespace_info is iterable - - not namespace_info is string - - not namespace_info is mapping - - namespace_info | length == 2 + # After creating second object + - test1 is sequence and test1 is not string + - test1 | length == 2 + - test2 is sequence and test2 is not string + - test2 | length == 2 + - test3 is sequence and test3 is not string + - test3 | length == 1 + - test4 is sequence and test4 is not string + - test4 | length == 1 + - test5 is sequence and test5 is not string + - test5 | length == 1 + - test6 is sequence and test6 is not string + - test6 | length == 1 + # When label_selector is used it returns list irrespective of wantlist=True + - test7 is sequence and test7 is not string + # Without wantlist=True lookup should return mapping + - test8 is mapping + - test9 is mapping always: - name: Ensure that namespace is removed k8s: kind: Namespace - name: "{{ item }}" + name: "app-development-{{ item }}" state: absent with_items: - - app-development-one - - app-development-two + - one + - two diff --git a/plugins/lookup/k8s.py b/plugins/lookup/k8s.py index b4517fcdf9..7a0a819b02 100644 --- a/plugins/lookup/k8s.py +++ b/plugins/lookup/k8s.py @@ -21,7 +21,10 @@ namespace, or all matching objects for all namespaces, as well as information about the cluster. - Provides access the full range of K8s APIs. - Enables authentication via config file, certificates, password or token. - + notes: + - While querying, please use C(query) or C(lookup) format with C(wantlist=True) to provide an easier and more + consistent interface. For more details, see + U(https://docs.ansible.com/ansible/latest/plugins/lookup.html#forcing-lookups-to-return-lists-query-and-wantlist-true). options: cluster_info: description: @@ -119,23 +122,23 @@ EXAMPLES = """ - name: Fetch a list of namespaces set_fact: - projects: "{{ lookup('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}" + projects: "{{ query('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}" - name: Fetch all deployments set_fact: - deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment') }}" + deployments: "{{ query('kubernetes.core.k8s', kind='Deployment') }}" - name: Fetch all deployments in a namespace set_fact: - deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment', namespace='testing') }}" + deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='testing') }}" - name: Fetch a specific deployment by name set_fact: - deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment', namespace='testing', resource_name='elastic') }}" + deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='testing', resource_name='elastic') }}" - name: Fetch with label selector set_fact: - service: "{{ lookup('kubernetes.core.k8s', kind='Service', label_selector='app=galaxy') }}" + service: "{{ query('kubernetes.core.k8s', kind='Service', label_selector='app=galaxy') }}" # Use parameters from a YAML config @@ -145,11 +148,11 @@ - name: Using the config (loaded from a file in prior task), fetch the latest version of the object set_fact: - service: "{{ lookup('kubernetes.core.k8s', resource_definition=config) }}" + service: "{{ query('kubernetes.core.k8s', resource_definition=config) }}" - name: Use a config from the local filesystem set_fact: - service: "{{ lookup('kubernetes.core.k8s', src='service.yml') }}" + service: "{{ query('kubernetes.core.k8s', src='service.yml') }}" """ RETURN = """ @@ -264,7 +267,7 @@ def run(self, terms, variables=None, **kwargs): if self.name: return [k8s_obj.to_dict()] - return [k8s_obj.to_dict().get('items')] + return k8s_obj.to_dict().get('items') class LookupModule(LookupBase):