-
Notifications
You must be signed in to change notification settings - Fork 23.7k
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
Add kubevirt_cdi_upload module #52990
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright: (c) 2019, Ansible Project | ||
# 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 | ||
|
||
|
||
ANSIBLE_METADATA = {'metadata_version': '1.1', | ||
'status': ['preview'], | ||
'supported_by': 'community'} | ||
|
||
DOCUMENTATION = ''' | ||
|
||
module: kubevirt_cdi_upload | ||
|
||
short_description: Upload local VM images to CDI Upload Proxy. | ||
|
||
version_added: "2.8" | ||
|
||
author: KubeVirt Team (@kubevirt) | ||
|
||
|
||
description: | ||
- Use Openshift Python SDK to create UploadTokenRequest objects. | ||
- Transfer contents of local files to the CDI Upload Proxy. | ||
|
||
options: | ||
pvc_name: | ||
description: | ||
- Use to specify the name of the target PersistentVolumeClaim. | ||
required: true | ||
pvc_namespace: | ||
description: | ||
- Use to specify the namespace of the target PersistentVolumeClaim. | ||
required: true | ||
upload_host: | ||
description: | ||
- URL containing the host and port on which the CDI Upload Proxy is available. | ||
- "More info: U(https://github.com/kubevirt/containerized-data-importer/blob/master/doc/upload.md#expose-cdi-uploadproxy-service)" | ||
upload_host_verify_ssl: | ||
description: | ||
- Whether or not to verify the CDI Upload Proxy's SSL certificates against your system's CA trust store. | ||
default: true | ||
type: bool | ||
path: | ||
description: | ||
- Path of local image file to transfer. | ||
merge_type: | ||
description: | ||
- Whether to override the default patch merge approach with a specific type. By default, the strategic | ||
merge will typically be used. | ||
type: list | ||
choices: [ json, merge, strategic-merge ] | ||
|
||
extends_documentation_fragment: | ||
- k8s_auth_options | ||
|
||
requirements: | ||
- python >= 2.7 | ||
- openshift >= 0.8.2 | ||
- requests >= 2.0.0 | ||
''' | ||
|
||
EXAMPLES = ''' | ||
- name: Upload local image to pvc-vm1 | ||
kubevirt_cdi_upload: | ||
pvc_namespace: default | ||
pvc_name: pvc-vm1 | ||
upload_host: https://localhost:8443 | ||
upload_host_verify_ssl: false | ||
path: /tmp/cirros-0.4.0-x86_64-disk.img | ||
''' | ||
|
||
RETURN = '''# ''' | ||
|
||
import copy | ||
import traceback | ||
|
||
from collections import defaultdict | ||
|
||
from ansible.module_utils.k8s.common import AUTH_ARG_SPEC | ||
from ansible.module_utils.k8s.raw import KubernetesRawModule | ||
|
||
# 3rd party imports | ||
try: | ||
import requests | ||
HAS_REQUESTS = True | ||
except ImportError: | ||
HAS_REQUESTS = False | ||
|
||
|
||
SERVICE_ARG_SPEC = { | ||
'pvc_name': {'required': True}, | ||
'pvc_namespace': {'required': True}, | ||
'upload_host': {'required': True}, | ||
'upload_host_verify_ssl': { | ||
'type': 'bool', | ||
'default': True | ||
}, | ||
'path': {'required': True}, | ||
'merge_type': { | ||
'type': 'list', | ||
'choices': ['json', 'merge', 'strategic-merge'] | ||
}, | ||
} | ||
|
||
|
||
class KubeVirtCDIUpload(KubernetesRawModule): | ||
def __init__(self, *args, **kwargs): | ||
super(KubeVirtCDIUpload, self).__init__(*args, k8s_kind='UploadTokenRequest', **kwargs) | ||
|
||
if not HAS_REQUESTS: | ||
self.fail("This module requires the python 'requests' package. Try `pip install requests`.") | ||
|
||
@property | ||
def argspec(self): | ||
""" argspec property builder """ | ||
argument_spec = copy.deepcopy(AUTH_ARG_SPEC) | ||
argument_spec.update(SERVICE_ARG_SPEC) | ||
return argument_spec | ||
|
||
def execute_module(self): | ||
""" Module execution """ | ||
|
||
API = 'v1alpha1' | ||
KIND = 'UploadTokenRequest' | ||
|
||
self.client = self.get_api_client() | ||
|
||
api_version = 'upload.cdi.kubevirt.io/{0}'.format(API) | ||
pvc_name = self.params.get('pvc_name') | ||
pvc_namespace = self.params.get('pvc_namespace') | ||
upload_host = self.params.get('upload_host') | ||
upload_host_verify_ssl = self.params.get('upload_host_verify_ssl') | ||
path = self.params.get('path') | ||
|
||
definition = defaultdict(defaultdict) | ||
|
||
definition['kind'] = KIND | ||
definition['apiVersion'] = api_version | ||
|
||
def_meta = definition['metadata'] | ||
def_meta['name'] = pvc_name | ||
def_meta['namespace'] = pvc_namespace | ||
|
||
def_spec = definition['spec'] | ||
def_spec['pvcName'] = pvc_name | ||
|
||
# Let's check the file's there before we do anything else | ||
imgfile = open(path, 'rb') | ||
|
||
resource = self.find_resource(KIND, api_version, fail=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, sh… I forgot. |
||
definition = self.set_defaults(resource, definition) | ||
result = self.perform_action(resource, definition) | ||
|
||
headers = {'Authorization': "Bearer {0}".format(result['result']['status']['token'])} | ||
files = {'file': imgfile} | ||
url = "{0}/{1}/upload".format(upload_host, API) | ||
requests.post(url, files=files, headers=headers, verify=upload_host_verify_ssl) | ||
|
||
self.exit_json(changed=True) | ||
|
||
|
||
def main(): | ||
module = KubeVirtCDIUpload() | ||
try: | ||
module.execute_module() | ||
except Exception as e: | ||
module.fail_json(msg=str(e), exception=traceback.format_exc()) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,6 +161,7 @@ lib/ansible/modules/cloud/google/gcpubsub_facts.py E322 | |
lib/ansible/modules/cloud/google/gcpubsub_facts.py E324 | ||
lib/ansible/modules/cloud/google/gcpubsub_facts.py E326 | ||
lib/ansible/modules/cloud/google/gcspanner.py E322 | ||
lib/ansible/modules/cloud/kubevirt/kubevirt_cdi_upload.py E203 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we can't fix this issue? AFAIK shouldn't be complex to fix,no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd need to take this and rewrite it: #32049, then get it merged, then modify this patch to use it. The first time this issue came came up (when merging There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, and |
||
lib/ansible/modules/cloud/linode/linode.py E322 | ||
lib/ansible/modules/cloud/linode/linode.py E324 | ||
lib/ansible/modules/cloud/lxc/lxc_container.py E210 | ||
|
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.
Is this different than the equivalent option specified in k8s_auth_options? Does this module connect to two API endpoints, and you could have two different cert-validation settings? Can we re-use the one defined in k8s_auth_options 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.
Yes, this is completely different. Stuff in k8s_auth_options controls connectivity to the kubernetes cluster's api server endpoint. This module does that, but then also connects to a service running on the cluster itself (called the Containerized Data Importer Upload Proxy), which is why it has a completely separate set of
upload_host_*
parameters that control that.It's probable that before The Freeze I'll be attempting to switch the default on
upload_host_verify_ssl
to autodetect (aka "look for a Secret with the certs in a standard place") for ease of use.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.
Thanks for that clarification. Upon reviewing the code, it wasn't obvious to me that this module is actively using both connection paths (to the k8s API and also to the Upload Proxy.) I've taken your word for it and updated my related PR.