New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optionally get service account file path from env var #54407
Conversation
@@ -335,6 +338,12 @@ def parse(self, inventory, loader, path, cache=True): | |||
config_data = {} | |||
config_data = self._read_config_data(path) | |||
|
|||
# this may optionally be read from environment variable | |||
if 'service_account_file' not in config_data: | |||
path = self.get_option('service_account_file') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure how you expect get_option to work since it pulls from config_data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing in _read_config_data
indicated to me that it reads from environment variables
I tested this by putting breakpoints in, and confirmed, yes, that get_option
works where the entry is not present in config_data
. Not being able to explain it doesn't change the fact that I can confirm that it works this way.
Even the syntax in the BaseInventoryPlugin
class seems to confirm that this syntax pattern is common:
if 'cache' in self._options and self.get_option('cache'):
I don't know if this is for the exact same reason, but maybe.
Now, one thing I didn't check, but maybe I should, is to compare self._options
versus config_data
in the locals here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config_data is not supposed to read env vars, get_option
does, you should not access _options
directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see #54426
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so there is a basic problem with this plugin, it is doing it's own validation with incorrect assumptions
I would remove the existing validations like if 'zone' in config_data
and just add required: true
to the config definition.
@@ -335,6 +338,12 @@ def parse(self, inventory, loader, path, cache=True): | |||
config_data = {} | |||
config_data = self._read_config_data(path) | |||
|
|||
# this may optionally be read from environment variable | |||
if 'service_account_file' not in config_data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this conditional is not needed, just use get_option since if read_config_data already consumes the options in the config file
It actually wasn't obvious to me from reading the source code that zones should be required. So I just had to try it without giving zones and see, it gave:
So zones should probably be required. tested the changes for zones, works if I give zones, if I don't give zones:
It is obvious from the prior code that projects should be required, so I made that required in the docs. I already dealt with filters in a prior issue, but this allows it to be handled in the standard way. |
raise AnsibleParserError("Zones must be a list in GCP inventory YAML files") | ||
zones = self.get_option('zones') | ||
config_data['zones'] = zones | ||
if not isinstance(zones, list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also not needed, add type: list
to configuration definition, nothing should be added back to config_data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also not needed, add type: list to configuration definition
I can do that
nothing should be added back to config_data
I can't do that. The entire solution here pivots on putting "service_account_file"
in config data, because I don't know how it is used for the request auth. I would be guessing at what you want this to look like. I need more detail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing should use config_data, its only meant for 'extras not covered by get_option', but that is a preexisting problem here
I tried this: diff --git a/lib/ansible/plugins/inventory/gcp_compute.py b/lib/ansible/plugins/inventory/gcp_compute.py
index 361f56233e..e6b1208b2f 100644
--- a/lib/ansible/plugins/inventory/gcp_compute.py
+++ b/lib/ansible/plugins/inventory/gcp_compute.py
@@ -26,9 +26,11 @@ DOCUMENTATION = '''
description: A list of regions in which to describe GCE instances.
default: all zones available to a given project
required: True
+ type: list
projects:
description: A list of projects in which to describe GCE instances.
required: True
+ type: list
filters:
description: >
A list of filter value pairs. Available filters are listed here
@@ -344,20 +346,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# get user specifications
zones = self.get_option('zones')
- config_data['zones'] = zones
- if not isinstance(zones, list):
- raise AnsibleParserError("Zones must be a list in GCP inventory YAML files")
-
- config_data['filters'] = self.get_option('filters')
-
- service_account_path = self.get_option('service_account_file')
- if service_account_path:
- config_data['service_account_file'] = service_account_path
-
projects = self.get_option('projects')
+ print('projects')
+ print(projects)
+ config_data['zones'] = zones
config_data['projects'] = projects
- if not isinstance(projects, list):
- raise AnsibleParserError("Projects must be a list in GCP inventory YAML files")
+ config_data['filters'] = self.get_option('filters')
+ config_data['service_account_file'] = self.get_option('service_account_file') This isn't working, I can put in dictionary, and |
rebased PR to use new standardized system |
Related #54532 |
What's the status of this? |
This consumes the change made in Ansible core ansible/ansible#54407 which is in Ansible 2.8, allowing the plugin injection logic to share the script logic and to be simplified
This consumes the change made in Ansible core ansible/ansible#54407 which is in Ansible 2.8, allowing the plugin injection logic to share the script logic and to be simplified
This consumes the change made in Ansible core ansible/ansible#54407 which is in Ansible 2.8, allowing the plugin injection logic to share the script logic and to be simplified
SUMMARY
Addresses #54406
ISSUE TYPE
COMPONENT NAME
gcp_compute inventory plugin
ADDITIONAL INFORMATION
Tested with
Where
min.gcp_compute.yml
hasThis will allow users to check their inventory config into source control.