1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/lookup/gcp_storage_file.py
Felix Fontein 75afd83508 Fix plugins (names, constants, FQCNs in examples) (#722)
* cobbler inventory: fix NAME

* oc transport: fix transport name

* Inventory plugins: fix plugin identifications

* Use FQCN in lookup plugin examples.

* Use FQCN in callback plugins.

* Add changelog fragment.

* Adjust documentation.

* Fix lookup plugin linting errors.

* Fix quotes.

(cherry picked from commit ea21341686)
2020-08-18 08:29:44 +02:00

147 lines
4.9 KiB
Python

# (c) 2019, Eric Anderson <eric.sysmin@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
lookup: gcp_storage_file
description:
- This lookup returns the contents from a file residing on Google Cloud Storage
short_description: Return GC Storage content
author: Eric Anderson <eanderson@avinetworks.com>
requirements:
- python >= 2.6
- requests >= 2.18.4
- google-auth >= 1.3.0
options:
src:
description:
- Source location of file (may be local machine or cloud depending on action).
required: false
bucket:
description:
- The name of the bucket.
required: false
extends_documentation_fragment:
- community.general._gcp
'''
EXAMPLES = '''
- ansible.builtin.debug:
msg: |
the value of foo.txt is {{ lookup('community.general.gcp_storage_file',
bucket='gcp-bucket', src='mydir/foo.txt', project='project-name',
auth_kind='serviceaccount', service_account_file='/tmp/myserviceaccountfile.json') }}
'''
RETURN = '''
_raw:
description:
- base64 encoded file content
'''
import base64
import json
import mimetypes
import os
import requests
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
try:
from ansible_collections.google.cloud.plugins.module_utils.gcp_utils import navigate_hash, GcpSession
HAS_GOOGLE_CLOUD_COLLECTION = True
except ImportError:
HAS_GOOGLE_CLOUD_COLLECTION = False
display = Display()
class GcpMockModule(object):
def __init__(self, params):
self.params = params
def fail_json(self, *args, **kwargs):
raise AnsibleError(kwargs['msg'])
def raise_for_status(self, response):
try:
response.raise_for_status()
except getattr(requests.exceptions, 'RequestException'):
self.fail_json(msg="GCP returned error: %s" % response.json())
class GcpFileLookup():
def get_file_contents(self, module):
auth = GcpSession(module, 'storage')
data = auth.get(self.media_link(module))
return base64.b64encode(data.content.rstrip())
def fetch_resource(self, module, link, allow_not_found=True):
auth = GcpSession(module, 'storage')
return self.return_if_object(module, auth.get(link), allow_not_found)
def self_link(self, module):
return "https://www.googleapis.com/storage/v1/b/{bucket}/o/{src}".format(**module.params)
def media_link(self, module):
return "https://www.googleapis.com/storage/v1/b/{bucket}/o/{src}?alt=media".format(**module.params)
def return_if_object(self, module, response, allow_not_found=False):
# If not found, return nothing.
if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
if response.status_code == 204:
return None
try:
module.raise_for_status(response)
result = response.json()
except getattr(json.decoder, 'JSONDecodeError', ValueError) as inst:
raise AnsibleError("Invalid JSON response with error: %s" % inst)
if navigate_hash(result, ['error', 'errors']):
raise AnsibleError(navigate_hash(result, ['error', 'errors']))
return result
def object_headers(self, module):
return {
"name": module.params['src'],
"Content-Type": mimetypes.guess_type(module.params['src'])[0],
"Content-Length": str(os.path.getsize(module.params['src'])),
}
def run(self, terms, variables=None, **kwargs):
params = {
'bucket': kwargs.get('bucket', None),
'src': kwargs.get('src', None),
'projects': kwargs.get('projects', None),
'scopes': kwargs.get('scopes', None),
'zones': kwargs.get('zones', None),
'auth_kind': kwargs.get('auth_kind', None),
'service_account_file': kwargs.get('service_account_file', None),
'service_account_email': kwargs.get('service_account_email', None),
}
if not params['scopes']:
params['scopes'] = ['https://www.googleapis.com/auth/devstorage.full_control']
fake_module = GcpMockModule(params)
# Check if files exist.
remote_object = self.fetch_resource(fake_module, self.self_link(fake_module))
if not remote_object:
raise AnsibleError("File does not exist in bucket")
result = self.get_file_contents(fake_module)
return [result]
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
if not HAS_GOOGLE_CLOUD_COLLECTION:
raise AnsibleError("community.general.gcp_storage_files needs a supported version of the google.cloud collection installed")
return GcpFileLookup().run(terms, variables=variables, **kwargs)