Skip to content

Commit 5ff3566

Browse files
authored
handle aliases for lookup and inventory plugins for authentication options (#500)
Honor aliases for lookup and inventory plugins rebase and extend the following PR #71 ISSUE TYPE Bugfix Pull Request Reviewed-by: Mike Graves <[email protected]>
1 parent c4c12ca commit 5ff3566

File tree

15 files changed

+477
-24
lines changed

15 files changed

+477
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
bugfixes:
2+
- common - handle ``aliases`` passed from inventory and lookup plugins.
3+
- module_utils/k8s/client.py - fix issue when trying to authenticate with host, client_cert and client_key parameters only.

plugins/inventory/k8s.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,10 @@
118118

119119
from ansible.errors import AnsibleError
120120
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
121-
K8sAnsibleMixin,
122121
HAS_K8S_MODULE_HELPER,
123122
k8s_import_exception,
123+
)
124+
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
124125
get_api_client,
125126
)
126127
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
@@ -146,7 +147,7 @@ class K8sInventoryException(Exception):
146147
pass
147148

148149

149-
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable, K8sAnsibleMixin):
150+
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
150151
NAME = "kubernetes.core.k8s"
151152

152153
connection_plugin = "kubernetes.core.kubectl"

plugins/lookup/k8s.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,12 @@
180180
from ansible.module_utils.common._collections_compat import KeysView
181181
from ansible.module_utils.common.validation import check_type_bool
182182

183-
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
184-
K8sAnsibleMixin,
183+
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
185184
get_api_client,
186185
)
186+
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.resource import (
187+
create_definitions,
188+
)
187189

188190
try:
189191
enable_turbo_mode = check_type_bool(os.environ.get("ENABLE_TURBO_MODE"))
@@ -210,7 +212,7 @@
210212
k8s_import_exception = e
211213

212214

213-
class KubernetesLookup(K8sAnsibleMixin):
215+
class KubernetesLookup(object):
214216
def __init__(self):
215217

216218
if not HAS_K8S_MODULE_HELPER:
@@ -240,7 +242,7 @@ def run(self, terms, variables=None, **kwargs):
240242

241243
cluster_info = kwargs.get("cluster_info")
242244
if cluster_info == "version":
243-
return [self.client.version]
245+
return [self.client.client.version]
244246
if cluster_info == "api_groups":
245247
if isinstance(self.client.resources.api_groups, KeysView):
246248
return [list(self.client.resources.api_groups)]
@@ -257,7 +259,12 @@ def run(self, terms, variables=None, **kwargs):
257259
resource_definition = kwargs.get("resource_definition")
258260
src = kwargs.get("src")
259261
if src:
260-
resource_definition = self.load_resource_definitions(src)[0]
262+
definitions = create_definitions(params=dict(src=src))
263+
if definitions:
264+
self.kind = definitions[0].kind
265+
self.name = definitions[0].name
266+
self.namespace = definitions[0].namespace
267+
self.api_version = definitions[0].api_version or "v1"
261268
if resource_definition:
262269
self.kind = resource_definition.get("kind", self.kind)
263270
self.api_version = resource_definition.get("apiVersion", self.api_version)
@@ -272,14 +279,15 @@ def run(self, terms, variables=None, **kwargs):
272279
"using the 'resource_definition' parameter."
273280
)
274281

275-
resource = self.find_resource(self.kind, self.api_version, fail=True)
282+
resource = self.client.resource(self.kind, self.api_version)
276283
try:
277-
k8s_obj = resource.get(
284+
params = dict(
278285
name=self.name,
279286
namespace=self.namespace,
280287
label_selector=self.label_selector,
281288
field_selector=self.field_selector,
282289
)
290+
k8s_obj = self.client.get(resource, **params)
283291
except NotFoundError:
284292
return []
285293

plugins/module_utils/k8s/client.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ def _create_auth_spec(module=None, **kwargs) -> Dict:
8181
auth[true_name] = module.params.get(arg_name)
8282
elif arg_name in kwargs and kwargs.get(arg_name) is not None:
8383
auth[true_name] = kwargs.get(arg_name)
84+
elif true_name in kwargs and kwargs.get(true_name) is not None:
85+
# Aliases in kwargs
86+
auth[true_name] = kwargs.get(true_name)
8487
elif arg_name == "proxy_headers":
8588
# specific case for 'proxy_headers' which is a dictionary
8689
proxy_headers = {}
@@ -131,7 +134,11 @@ def auth_set(*names: list) -> bool:
131134
# Removing trailing slashes if any from hostname
132135
auth["host"] = auth.get("host").rstrip("/")
133136

134-
if auth_set("username", "password", "host") or auth_set("api_key", "host"):
137+
if (
138+
auth_set("username", "password", "host")
139+
or auth_set("api_key", "host")
140+
or auth_set("cert_file", "key_file", "host")
141+
):
135142
# We have enough in the parameters to authenticate, no need to load incluster or kubeconfig
136143
pass
137144
elif auth_set("kubeconfig") or auth_set("context"):
@@ -346,10 +353,14 @@ def get_api_client(module=None, **kwargs: Optional[Any]) -> K8SClient:
346353
msg = "Could not create API client: {0}".format(e)
347354
raise CoreException(msg) from e
348355

356+
dry_run = False
357+
if module:
358+
dry_run = module.params.get("dry_run", False)
359+
349360
k8s_client = K8SClient(
350361
configuration=configuration,
351362
client=client,
352-
dry_run=module.params.get("dry_run", False),
363+
dry_run=dry_run,
353364
)
354365

355366
return k8s_client
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
- name: Create inventory files
3+
hosts: localhost
4+
gather_facts: false
5+
6+
collections:
7+
- kubernetes.core
8+
9+
roles:
10+
- role: setup_kubeconfig
11+
kubeconfig_operation: 'save'
12+
13+
tasks:
14+
- name: Create inventory files
15+
copy:
16+
content: "{{ item.content }}"
17+
dest: "{{ item.path }}"
18+
vars:
19+
hostname: "{{ lookup('file', user_credentials_dir + '/host_data.txt') }}"
20+
test_cert_file: "{{ user_credentials_dir | realpath + '/cert_file_data.txt' }}"
21+
test_key_file: "{{ user_credentials_dir | realpath + '/key_file_data.txt' }}"
22+
test_ca_cert: "{{ user_credentials_dir | realpath + '/ssl_ca_cert_data.txt' }}"
23+
with_items:
24+
- path: "test_inventory_aliases_with_ssl_k8s.yml"
25+
content: |
26+
---
27+
plugin: kubernetes.core.k8s
28+
connections:
29+
- namespaces:
30+
- inventory
31+
host: "{{ hostname }}"
32+
cert_file: "{{ test_cert_file }}"
33+
key_file: "{{ test_key_file }}"
34+
verify_ssl: true
35+
ssl_ca_cert: "{{ test_ca_cert }}"
36+
- path: "test_inventory_aliases_no_ssl_k8s.yml"
37+
content: |
38+
---
39+
plugin: kubernetes.core.k8s
40+
connections:
41+
- namespaces:
42+
- inventory
43+
host: "{{ hostname }}"
44+
cert_file: "{{ test_cert_file }}"
45+
key_file: "{{ test_key_file }}"
46+
verify_ssl: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
- name: Delete inventory namespace
3+
hosts: localhost
4+
connection: local
5+
gather_facts: true
6+
7+
roles:
8+
- role: setup_kubeconfig
9+
kubeconfig_operation: 'revert'
10+
11+
tasks:
12+
- name: Delete temporary files
13+
file:
14+
state: absent
15+
path: "{{ user_credentials_dir ~ '/' ~ item }}"
16+
ignore_errors: true
17+
with_items:
18+
- test_inventory_aliases_with_ssl_k8s.yml
19+
- test_inventory_aliases_no_ssl_k8s.yml
20+
- ssl_ca_cert_data.txt
21+
- key_file_data.txt
22+
- cert_file_data.txt
23+
- host_data.txt
24+
25+
- name: Remove inventory namespace
26+
k8s:
27+
api_version: v1
28+
kind: Namespace
29+
name: inventory
30+
state: absent

tests/integration/targets/inventory_k8s/playbooks/play.yml

-12
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,3 @@
8888
- name: Assert the file content matches expectations
8989
assert:
9090
that: (slurped_file.content|b64decode) == file_content
91-
92-
- name: Delete inventory namespace
93-
hosts: localhost
94-
connection: local
95-
gather_facts: no
96-
tasks:
97-
- name: Remove inventory namespace
98-
k8s:
99-
api_version: v1
100-
kind: Namespace
101-
name: inventory
102-
state: absent

tests/integration/targets/inventory_k8s/runme.sh

+22-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,28 @@
22

33
set -eux
44

5+
export ANSIBLE_ROLES_PATH="../"
6+
USER_CREDENTIALS_DIR=$(pwd)
7+
8+
ansible-playbook playbooks/delete_resources.yml -e "user_credentials_dir=${USER_CREDENTIALS_DIR}" "$@"
9+
10+
{
511
export ANSIBLE_INVENTORY_ENABLED=kubernetes.core.k8s,yaml
612
export ANSIBLE_PYTHON_INTERPRETER=auto_silent
713

8-
ansible-playbook playbooks/play.yml -i playbooks/test.inventory_k8s.yml "$@"
14+
ansible-playbook playbooks/play.yml -i playbooks/test.inventory_k8s.yml "$@" &&
15+
16+
ansible-playbook playbooks/create_resources.yml -e "user_credentials_dir=${USER_CREDENTIALS_DIR}" "$@" &&
17+
18+
ansible-inventory -i playbooks/test_inventory_aliases_with_ssl_k8s.yml --list "$@" &&
19+
20+
ansible-inventory -i playbooks/test_inventory_aliases_no_ssl_k8s.yml --list "$@" &&
21+
22+
unset ANSIBLE_INVENTORY_ENABLED &&
23+
24+
ansible-playbook playbooks/delete_resources.yml -e "user_credentials_dir=${USER_CREDENTIALS_DIR}" "$@"
25+
26+
} || {
27+
ansible-playbook playbooks/delete_resources.yml -e "user_credentials_dir=${USER_CREDENTIALS_DIR}" "$@"
28+
exit 1
29+
}

tests/integration/targets/lookup_k8s/defaults/main.yml

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
test_namespace:
33
- app-development-one
44
- app-development-two
5+
- app-development-three
6+
configmap_data: "This is a simple config map data."
7+
configmap_name: "test-configmap"

0 commit comments

Comments
 (0)