-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4669 from kwoodson/storageclass
Merged by openshift-bot
- Loading branch information
Showing
10 changed files
with
2,240 additions
and
16 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# pylint: skip-file | ||
# flake8: noqa | ||
|
||
def main(): | ||
''' | ||
ansible oc module for storageclass | ||
''' | ||
|
||
module = AnsibleModule( | ||
argument_spec=dict( | ||
kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'), | ||
state=dict(default='present', type='str', choices=['present', 'absent', 'list']), | ||
debug=dict(default=False, type='bool'), | ||
name=dict(default=None, type='str'), | ||
annotations=dict(default=None, type='dict'), | ||
parameters=dict(default=None, type='dict'), | ||
provisioner=dict(default='aws-ebs', type='str', choices=['aws-ebs', 'gce-pd', 'glusterfs', 'cinder']), | ||
api_version=dict(default='v1', type='str'), | ||
default_storage_class=dict(default="false", type='str'), | ||
), | ||
supports_check_mode=True, | ||
) | ||
|
||
rval = OCStorageClass.run_ansible(module.params, module.check_mode) | ||
if 'failed' in rval: | ||
return module.fail_json(**rval) | ||
|
||
return module.exit_json(**rval) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# pylint: skip-file | ||
# flake8: noqa | ||
|
||
# pylint: disable=too-many-instance-attributes | ||
class OCStorageClass(OpenShiftCLI): | ||
''' Class to wrap the oc command line tools ''' | ||
kind = 'storageclass' | ||
|
||
# pylint allows 5 | ||
# pylint: disable=too-many-arguments | ||
def __init__(self, | ||
config, | ||
verbose=False): | ||
''' Constructor for OCStorageClass ''' | ||
super(OCStorageClass, self).__init__(None, kubeconfig=config.kubeconfig, verbose=verbose) | ||
self.config = config | ||
self.storage_class = None | ||
|
||
def exists(self): | ||
''' return whether a storageclass exists''' | ||
if self.storage_class: | ||
return True | ||
|
||
return False | ||
|
||
def get(self): | ||
'''return storageclass ''' | ||
result = self._get(self.kind, self.config.name) | ||
if result['returncode'] == 0: | ||
self.storage_class = StorageClass(content=result['results'][0]) | ||
elif '\"%s\" not found' % self.config.name in result['stderr']: | ||
result['returncode'] = 0 | ||
result['results'] = [{}] | ||
|
||
return result | ||
|
||
def delete(self): | ||
'''delete the object''' | ||
return self._delete(self.kind, self.config.name) | ||
|
||
def create(self): | ||
'''create the object''' | ||
return self._create_from_content(self.config.name, self.config.data) | ||
|
||
def update(self): | ||
'''update the object''' | ||
# parameters are currently unable to be updated. need to delete and recreate | ||
self.delete() | ||
# pause here and attempt to wait for delete. | ||
# Better option would be to poll | ||
import time | ||
time.sleep(5) | ||
return self.create() | ||
|
||
def needs_update(self): | ||
''' verify an update is needed ''' | ||
# check if params have updated | ||
if self.storage_class.get_parameters() != self.config.parameters: | ||
return True | ||
|
||
for anno_key, anno_value in self.storage_class.get_annotations().items(): | ||
if 'is-default-class' in anno_key and anno_value != self.config.default_storage_class: | ||
return True | ||
|
||
return False | ||
|
||
@staticmethod | ||
# pylint: disable=too-many-return-statements,too-many-branches | ||
# TODO: This function should be refactored into its individual parts. | ||
def run_ansible(params, check_mode): | ||
'''run the ansible idempotent code''' | ||
|
||
rconfig = StorageClassConfig(params['name'], | ||
provisioner="kubernetes.io/{}".format(params['provisioner']), | ||
parameters=params['parameters'], | ||
annotations=params['annotations'], | ||
api_version="storage.k8s.io/{}".format(params['api_version']), | ||
default_storage_class=params.get('default_storage_class', 'false'), | ||
kubeconfig=params['kubeconfig'], | ||
) | ||
|
||
oc_sc = OCStorageClass(rconfig, verbose=params['debug']) | ||
|
||
state = params['state'] | ||
|
||
api_rval = oc_sc.get() | ||
|
||
##### | ||
# Get | ||
##### | ||
if state == 'list': | ||
return {'changed': False, 'results': api_rval['results'], 'state': 'list'} | ||
|
||
######## | ||
# Delete | ||
######## | ||
if state == 'absent': | ||
if oc_sc.exists(): | ||
|
||
if check_mode: | ||
return {'changed': True, 'msg': 'Would have performed a delete.'} | ||
|
||
api_rval = oc_sc.delete() | ||
|
||
return {'changed': True, 'results': api_rval, 'state': 'absent'} | ||
|
||
return {'changed': False, 'state': 'absent'} | ||
|
||
if state == 'present': | ||
######## | ||
# Create | ||
######## | ||
if not oc_sc.exists(): | ||
|
||
if check_mode: | ||
return {'changed': True, 'msg': 'Would have performed a create.'} | ||
|
||
# Create it here | ||
api_rval = oc_sc.create() | ||
|
||
if api_rval['returncode'] != 0: | ||
return {'failed': True, 'msg': api_rval} | ||
|
||
# return the created object | ||
api_rval = oc_sc.get() | ||
|
||
if api_rval['returncode'] != 0: | ||
return {'failed': True, 'msg': api_rval} | ||
|
||
return {'changed': True, 'results': api_rval, 'state': 'present'} | ||
|
||
######## | ||
# Update | ||
######## | ||
if oc_sc.needs_update(): | ||
api_rval = oc_sc.update() | ||
|
||
if api_rval['returncode'] != 0: | ||
return {'failed': True, 'msg': api_rval} | ||
|
||
# return the created object | ||
api_rval = oc_sc.get() | ||
|
||
if api_rval['returncode'] != 0: | ||
return {'failed': True, 'msg': api_rval} | ||
|
||
return {'changed': True, 'results': api_rval, 'state': 'present'} | ||
|
||
return {'changed': False, 'results': api_rval, 'state': 'present'} | ||
|
||
|
||
return {'failed': True, | ||
'changed': False, | ||
'msg': 'Unknown state passed. %s' % state, | ||
'state': 'unknown'} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# flake8: noqa | ||
# pylint: skip-file | ||
|
||
DOCUMENTATION = ''' | ||
--- | ||
module: oc_storageclass | ||
short_description: Create, modify, and idempotently manage openshift storageclasses. | ||
description: | ||
- Manage openshift storageclass objects programmatically. | ||
options: | ||
state: | ||
description: | ||
- State represents whether to create, modify, delete, or list | ||
required: False | ||
default: present | ||
choices: ["present", "absent", "list"] | ||
aliases: [] | ||
kubeconfig: | ||
description: | ||
- The path for the kubeconfig file to use for authentication | ||
required: false | ||
default: /etc/origin/master/admin.kubeconfig | ||
aliases: [] | ||
debug: | ||
description: | ||
- Turn on debug output. | ||
required: false | ||
default: False | ||
aliases: [] | ||
name: | ||
description: | ||
- Name of the object that is being queried. | ||
required: false | ||
default: None | ||
aliases: [] | ||
provisioner: | ||
description: | ||
- Any annotations to add to the storageclass | ||
required: false | ||
default: 'aws-ebs' | ||
aliases: [] | ||
default_storage_class: | ||
description: | ||
- Whether or not this is the default storage class | ||
required: false | ||
default: False | ||
aliases: [] | ||
parameters: | ||
description: | ||
- A dictionary with the parameters to configure the storageclass. This will be based on provisioner | ||
required: false | ||
default: None | ||
aliases: [] | ||
api_version: | ||
description: | ||
- The api version. | ||
required: false | ||
default: v1 | ||
aliases: [] | ||
author: | ||
- "Kenny Woodson <[email protected]>" | ||
extends_documentation_fragment: [] | ||
''' | ||
|
||
EXAMPLES = ''' | ||
- name: get storageclass | ||
run_once: true | ||
oc_storageclass: | ||
name: gp2 | ||
state: list | ||
register: registry_sc_out | ||
|
||
- name: create the storageclass | ||
oc_storageclass: | ||
run_once: true | ||
name: gp2 | ||
parameters: | ||
type: gp2 | ||
encrypted: 'true' | ||
kmsKeyId: '<full kms key arn>' | ||
provisioner: aws-ebs | ||
default_storage_class: False | ||
register: sc_out | ||
notify: | ||
- restart openshift master services | ||
''' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# pylint: skip-file | ||
# flake8: noqa | ||
|
||
|
||
# pylint: disable=too-many-instance-attributes | ||
class StorageClassConfig(object): | ||
''' Handle service options ''' | ||
# pylint: disable=too-many-arguments | ||
def __init__(self, | ||
name, | ||
provisioner=None, | ||
parameters=None, | ||
annotations=None, | ||
default_storage_class="false", | ||
api_version='v1', | ||
kubeconfig='/etc/origin/master/admin.kubeconfig'): | ||
''' constructor for handling storageclass options ''' | ||
self.name = name | ||
self.parameters = parameters | ||
self.annotations = annotations | ||
self.provisioner = provisioner | ||
self.api_version = api_version | ||
self.default_storage_class = str(default_storage_class).lower() | ||
self.kubeconfig = kubeconfig | ||
self.data = {} | ||
|
||
self.create_dict() | ||
|
||
def create_dict(self): | ||
''' instantiates a storageclass dict ''' | ||
self.data['apiVersion'] = self.api_version | ||
self.data['kind'] = 'StorageClass' | ||
self.data['metadata'] = {} | ||
self.data['metadata']['name'] = self.name | ||
|
||
self.data['metadata']['annotations'] = {} | ||
if self.annotations is not None: | ||
self.data['metadata']['annotations'] = self.annotations | ||
|
||
self.data['metadata']['annotations']['storageclass.beta.kubernetes.io/is-default-class'] = \ | ||
self.default_storage_class | ||
|
||
if self.provisioner is None: | ||
self.data['provisioner'] = 'kubernetes.io/aws-ebs' | ||
else: | ||
self.data['provisioner'] = self.provisioner | ||
|
||
self.data['parameters'] = {} | ||
if self.parameters is not None: | ||
self.data['parameters'].update(self.parameters) | ||
|
||
# default to aws if no params were passed | ||
else: | ||
self.data['parameters']['type'] = 'gp2' | ||
|
||
|
||
|
||
# pylint: disable=too-many-instance-attributes,too-many-public-methods | ||
class StorageClass(Yedit): | ||
''' Class to model the oc storageclass object ''' | ||
annotations_path = "metadata.annotations" | ||
provisioner_path = "provisioner" | ||
parameters_path = "parameters" | ||
kind = 'StorageClass' | ||
|
||
def __init__(self, content): | ||
'''StorageClass constructor''' | ||
super(StorageClass, self).__init__(content=content) | ||
|
||
def get_annotations(self): | ||
''' get a list of ports ''' | ||
return self.get(StorageClass.annotations_path) or {} | ||
|
||
def get_parameters(self): | ||
''' get the service selector''' | ||
return self.get(StorageClass.parameters_path) or {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.