├── .gitignore
├── README.rst
├── ansible.cfg
├── backup.yaml
├── backup_and_restore.yaml
├── file_system_deployment.yaml
├── library
└── commvault.py
└── update_subclient_description.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Ansible Commvault module
2 | ========================
3 |
4 | `Ansible `_ is a radically simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs.
5 |
6 | `How Ansible Works | Ansible.com `_
7 |
8 | `Getting started with Ansible `_
9 |
10 | `Getting started with playbooks `_
11 |
12 | Introduction
13 | ------------
14 |
15 | Ansible Commvault module can be used in playbooks to automate commvault operations
16 |
17 |
18 |
19 |
20 | Commvault module uses `CVPySDK `_ to perform operations
21 |
22 | All agents supported by CVPySDK are supported by commvault ansible module
23 |
24 | CVPySDK, in turn, uses Commvault REST API to perform operations on a Commcell via WebConsole.
25 |
26 |
27 | Requirements
28 | ------------
29 |
30 | - Ansible
31 | - Python 3 or above
32 | - `CVPySDK `_
33 | - Commvault Software v11 SP16 or later release with WebConsole installed
34 |
35 | Installing CVPySDK
36 | ------------------
37 |
38 | CVPySDK can be installed directly from PyPI using pip:
39 |
40 | >>> pip install cvpysdk
41 |
42 |
43 | CVPySDK is available on GitHub `here `_
44 |
45 | It can also be installed from source.
46 |
47 | After downloading, from within the ``cvpysdk`` directory, execute:
48 |
49 | >>> python setup.py install
50 |
51 | Installing Ansible
52 | ------------------
53 |
54 | - `Installation guide | Ansible.com `_
55 |
56 |
57 | Using Ansible commvault module
58 | ------------------------------
59 |
60 | **Login to Commcell:**
61 | ::
62 |
63 | ---
64 | - name: Commvault Ansible
65 | gather_facts: no
66 | hosts: localhost
67 | connection: local
68 |
69 | vars:
70 | webconsole_hostname: 'webconsole_hostname'
71 | commcell_username: 'commcell_username'
72 | commcell_password: 'commcell_password'
73 |
74 | tasks:
75 | - name: Login
76 | commvault:
77 | operation: login
78 | entity: {
79 | webconsole_hostname: "{{ webconsole_hostname }}",
80 | commcell_username: "{{ commcell_username }}",
81 | commcell_password: "{{ commcell_password }}"
82 | }
83 | register: commcell
84 |
85 | **Force HTTPS login using self-signed certificate**
86 | ::
87 |
88 | - name: Login
89 | commvault:
90 | operation: login
91 | entity: {
92 | webconsole_hostname: "{{ webconsole_hostname }}",
93 | commcell_username: "{{ commcell_username }}",
94 | commcell_password: "{{ commcell_password }}",
95 | force_https: True,
96 | certificate_path: '/tmp/certificates'
97 | }
98 | register: commcell
99 |
100 |
101 | **Run backup for a subclient:**
102 | ::
103 |
104 | - name: Backup
105 | commvault:
106 | operation: "backup"
107 | entity_type: subclient
108 | commcell: "{{ commcell }}"
109 | entity: {
110 | client: "client name",
111 | agent: "file system",
112 | backupset: "defaultbackupset",
113 | subclient: "default"
114 | }
115 | register: backup_job
116 |
117 | **Run restore in place job for a subclient:**
118 | ::
119 |
120 | - name: Restore
121 | commvault:
122 | operation: "restore_in_place"
123 | entity_type: subclient
124 | commcell: "{{ commcell }}"
125 | entity: {
126 | client: "client name",
127 | agent: "file system",
128 | backupset: "defaultbackupset",
129 | subclient: "default"
130 | }
131 | args: {
132 | paths: ['path']
133 | }
134 | register: restore_job
135 |
136 | **Wait for the restore job to complete:**
137 | ::
138 |
139 | - name: wait for restore job to complete
140 | commvault:
141 | operation: "wait_for_completion"
142 | entity_type: "job"
143 | commcell: "{{ commcell }}"
144 | entity: {
145 | job_id: "{{ restore_job.output }}"
146 | }
147 | register: restore_status
148 |
149 | **Get storage pool properties:**
150 | ::
151 |
152 | - name: "get storage pool properties"
153 | commvault:
154 | operation: "storage_pool_properties"
155 | entity_type: storagepool
156 | commcell: "{{ commcell }}"
157 | entity: {
158 | "storage_pool": "dedicated cl2"
159 | }
160 | register: storage_pool_props
161 |
162 |
163 | Explanation:
164 | ------------
165 |
166 | **operation** corresponds to a method name in CVPySDK modules, example "restore_in_place" method is in subclient.py module
167 |
168 | **entity_type** corresponds to baisc CVPySDK class, available options are
169 |
170 | - Commcell
171 | - Clients
172 | - Client
173 | - Clientgroups
174 | - Clientgroup
175 | - Agents
176 | - Agent
177 | - Instances
178 | - Instance
179 | - Backupsets
180 | - Backupset
181 | - Subclients
182 | - Subclient
183 | - Job
184 | - MediaAgents
185 | - MediaAgent
186 | - StoragePools
187 | - StoragePool
188 | - DiskLibraries
189 | - DiskLibrary
190 |
191 | **commcell** is mandatory to perform any tasks, when performing login operation commcell is registered and can later be used in other tasks
192 |
193 | **entity** will contain basic CVPySDK inputs, available options are
194 |
195 | - client
196 | - clientgroup
197 | - agent
198 | - instance
199 | - backupset
200 | - subclient
201 | - job_id
202 | - media_agent
203 | - storage_pool
204 | - disk_library
205 |
206 | **args** contains the arguments to be passed to the method
207 |
208 | Contribution Guidelines
209 | -----------------------
210 |
211 | #. We welcome all the enhancements from everyone although we request the developer to follow some guidelines while interacting with the ``Ansible commvault module`` codebase.
212 |
213 | #. Before adding any enhancements/bug-fixes, we request you to open an Issue first.
214 |
215 | #. The core team will go over the Issue and notify if it is required or already been worked on.
216 |
217 | #. If the Issue is approved, the contributor can then make the changes to their fork and open a pull request.
218 |
219 | Coding Considerations
220 | *********************
221 |
222 | - All python code should be **PEP8** compliant.
223 | - All changes should be consistent with the design of the SDK.
224 | - The code should be formatted using **autopep8** with line-length set to **119** instead of default **79**.
225 | - All changes and any new methods/classes should be properly documented.
226 | - The docstrings should be of the same format as existing docs.
227 |
228 | Questions/Comments/Suggestions
229 | --------------
230 | If you have any questions or comments, please contact us `here `_.
231 | Also Check out our community for `Automation `_ incase of queries.
232 |
233 | Code of Conduct
234 | ***************
235 |
236 | Everyone interacting in the **Ansible commvault module** project's codebases, issue trackers,
237 | chat rooms, and mailing lists is expected to follow the
238 | `PyPA Code of Conduct`_.
239 |
240 | .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/
241 |
242 | License
243 | -------
244 | **CVPySDK** and **Commvault ansible module** are licensed under `Apache 2.0 `_
245 |
246 | About Commvault
247 | ---------------
248 | .. image:: https://commvault.github.io/cvpysdk/logo.png
249 | :align: center
250 |
251 | |
252 |
253 | `Commvault `_
254 | (NASDAQ: CVLT) is a publicly-traded data protection and information management software company headquartered in Tinton Falls, New Jersey.
255 |
256 | It was formed in 1988 as a development group in Bell Labs, and later became a business unit of AT&T Network Systems. It was incorporated in 1996.
257 |
258 | Commvault software assists organizations with data backup and recovery, cloud and infrastructure management, and retention and compliance.
259 |
--------------------------------------------------------------------------------
/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 |
--------------------------------------------------------------------------------
/backup.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Commvault Ansible
3 | gather_facts: no
4 | hosts: localhost
5 | connection: local
6 |
7 | vars:
8 | webconsole_hostname: 'hostname'
9 | commcell_username: 'username'
10 | commcell_password: 'password'
11 | client: 'sample client'
12 |
13 | tasks:
14 | - name: Commvault commcell initialization
15 | block:
16 | - name: Login
17 | commvault:
18 | operation: LOGIN
19 | entity: {
20 | webconsole_hostname: "{{ webconsole_hostname }}",
21 | commcell_username: "{{ commcell_username }}",
22 | commcell_password: "{{ commcell_password }}"
23 | }
24 | register: commcell
25 | - debug:
26 | msg: "Login is done successfully"
27 | rescue:
28 | - debug:
29 | msg: 'Login failed'
30 |
31 | - name: performing backup
32 | commvault:
33 | operation: "backup"
34 | entity_type: subclient
35 | commcell: "{{ commcell }}"
36 | entity: {
37 | client: "{{ client }}",
38 | agent: "file system",
39 | backupset: "defaultbackupset",
40 | subclient: "default"
41 | }
42 | register: backup_job
43 |
44 | - debug:
45 | msg: "Successfully started backup job: {{ backup_job.output }}"
46 |
47 | ...
--------------------------------------------------------------------------------
/backup_and_restore.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Commvault Ansible
3 | gather_facts: no
4 | hosts: localhost
5 | connection: local
6 |
7 | vars:
8 | webconsole_hostname: 'hostname'
9 | commcell_username: 'username'
10 | commcell_password: 'password'
11 | client: 'sample client'
12 |
13 | tasks:
14 | - name: Commvault commcell initialization
15 | block:
16 | - name: Login
17 | commvault:
18 | operation: LOGIN
19 | entity: {
20 | webconsole_hostname: "{{ webconsole_hostname }}",
21 | commcell_username: "{{ commcell_username }}",
22 | commcell_password: "{{ commcell_password }}"
23 | }
24 | register: commcell
25 | - debug:
26 | msg: "Login is done successfully"
27 | rescue:
28 | - debug:
29 | msg: 'Login failed'
30 |
31 | - name: Backup
32 | block:
33 | - name: performing backup
34 | commvault:
35 | operation: "backup"
36 | entity_type: subclient
37 | commcell: "{{ commcell }}"
38 | entity: {
39 | client: "{{ client }}",
40 | agent: "file system",
41 | backupset: "defaultbackupset",
42 | subclient: "default"
43 | }
44 | register: backup_job
45 | - debug:
46 | msg: "Successfully started backup job: {{ backup_job.output }}"
47 | - name: wait for backup job to complete
48 | commvault:
49 | operation: "wait_for_completion"
50 | entity_type: "job"
51 | commcell: "{{ commcell }}"
52 | entity: {
53 | job_id: "{{ backup_job.output }}"
54 | }
55 | register: backup_status
56 | - name: Backup job failure reason
57 | when: backup_status.output == false
58 | commvault:
59 | operation: "delay_reason"
60 | entity_type: "job"
61 | commcell: "{{ commcell }}"
62 | entity: {
63 | job_id: "{{ backup_job.output }}"
64 | }
65 | register: failure_reason
66 | - debug:
67 | msg: "{{ failure_reason.output }}"
68 | when: backup_status.output == false
69 | ignore_errors: yes
70 | - debug:
71 | msg: "Backup job completed successfully"
72 | when: backup_status.output == true
73 | ignore_errors: yes
74 | rescue:
75 | - debug:
76 | msg: 'Backup failed'
77 |
78 | - name: Restore
79 | when: backup_status.output == true
80 | commvault:
81 | operation: "restore_in_place"
82 | entity_type: subclient
83 | commcell: "{{ commcell }}"
84 | entity: {
85 | client: "{{ client }}",
86 | agent: "file system",
87 | backupset: "defaultbackupset",
88 | subclient: "default"
89 | }
90 | args: {
91 | paths: ['C:\testing']
92 | }
93 | register: restore_job
94 |
95 | - debug:
96 | msg: "Successfully started Restore job: {{ restore_job.output }}"
97 |
98 | - name: wait for restore job to complete
99 | when: restore_job is succeeded
100 | commvault:
101 | operation: "wait_for_completion"
102 | entity_type: "job"
103 | commcell: "{{ commcell }}"
104 | entity: {
105 | job_id: "{{ restore_job.output }}"
106 | }
107 | register: restore_status
108 |
109 | - name: Backup job failure reason
110 | when: restore_status.output == false
111 | commvault:
112 | operation: "delay_reason"
113 | entity_type: "job"
114 | commcell: "{{ commcell }}"
115 | entity: {
116 | job_id: "{{ restore_job.output }}"
117 | }
118 | register: failure_reason
119 |
120 | - debug:
121 | msg: "{{ failure_reason.output }}"
122 | when: restore_status.output == false
123 | ignore_errors: yes
124 |
125 | - debug:
126 | msg: "{{ Restore job completed successfully }}"
127 | when: restore_status.output == true
128 | ignore_errors: yes
129 |
130 | ...
--------------------------------------------------------------------------------
/file_system_deployment.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Commvault Ansible
3 | gather_facts: no
4 | hosts: localhost
5 | connection: local
6 |
7 | vars:
8 | webconsole_hostname: 'webconsole_hostname'
9 | commcell_username: 'commcell_username'
10 | commcell_password: 'commcell_password'
11 |
12 | tasks:
13 | - name: Commvault commcell initialization
14 | block:
15 | - name: Login
16 | commvault:
17 | operation: LOGIN
18 | entity: {
19 | webconsole_hostname: "{{ webconsole_hostname }}",
20 | commcell_username: "{{ commcell_username }}",
21 | commcell_password: "{{ commcell_password }}"
22 | }
23 | register: commcell
24 | - debug:
25 | msg: "Login is done successfully"
26 | rescue:
27 | - debug:
28 | msg: 'Login failed'
29 |
30 |
31 | # Either Unix or Windows clients_computers should be chosen and not both
32 | # windows packages - https://github.com/CommvaultEngg/cvpysdk/blob/master/cvpysdk/deployment/deploymentconstants.py#L79
33 | # Unix packages - https://github.com/CommvaultEngg/cvpysdk/blob/master/cvpysdk/deployment/deploymentconstants.py#L59
34 | # Install software method is available on commcell.py module in cvpysdk - https://github.com/CommvaultEngg/cvpysdk/blob/master/cvpysdk/commcell.py#L1684
35 | - name: Windows FS package installation
36 | commvault:
37 | operation: install_software
38 | entity_type: commcell
39 | commcell: "{{ commcell }}"
40 | args: {
41 | client_computers: ["client_name"],
42 | windows_features: [702], # 702 is File System
43 | username: "username",
44 | password: "password"
45 | }
46 |
47 | register: install_job
48 |
49 | - debug:
50 | msg: "Successfully started install job: {{ install_job.output }}"
51 |
52 | - name: wait for install job to complete
53 | when: install_job is succeeded
54 | commvault:
55 | operation: "wait_for_completion"
56 | entity_type: "job"
57 | commcell: "{{ commcell }}"
58 | entity: {
59 | job_id: "{{ install_job.output }}"
60 | }
61 | register: status
62 |
63 | - name: install job failure reason
64 | when: status.output == false
65 | commvault:
66 | operation: "delay_reason"
67 | entity_type: "job"
68 | commcell: "{{ commcell }}"
69 | entity: {
70 | job_id: "{{ install_job.output }}"
71 | }
72 | register: failure_reason
73 |
74 | - debug:
75 | msg: "{{ failure_reason.output }}"
76 | when: status.output == false
77 | ignore_errors: yes
78 |
79 | - debug:
80 | msg: "{{ install job completed successfully }}"
81 | when: status.output == true
82 | ignore_errors: yes
83 |
84 | ...
--------------------------------------------------------------------------------
/library/commvault.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # --------------------------------------------------------------------------
4 | # Copyright Commvault Systems, Inc.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | # --------------------------------------------------------------------------
18 |
19 |
20 | ANSIBLE_METADATA = {
21 | 'metadata_version': '11.28.0'
22 | }
23 |
24 | DOCUMENTATION = '''
25 |
26 | module: commvault
27 |
28 | short_description: To perform commvault operations
29 |
30 | description:
31 |
32 | - Ansible Commvault module can be used in playbooks to perform commvault operations
33 |
34 | - Commvault module uses CVPySDK to perform operations
35 |
36 | - CVPySDK, in turn, uses Commvault REST API to perform operations on a Commcell via WebConsole.
37 |
38 | author: "Commvault Systems, Inc."
39 |
40 | options:
41 |
42 | operation:
43 | description:
44 | - operation to be performed
45 | - corresponds to method name in CVPySDK modules
46 | - example "restore_in_place" method is in subclient module
47 |
48 | required: true
49 |
50 | choices:
51 | - Login
52 | - CVPySDK methods like backup, restore_in_place
53 |
54 | type: str
55 |
56 | entity:
57 | description:
58 | - contain basic CVPySDK inputs
59 |
60 | required: false
61 |
62 | default: {}
63 |
64 | choices:
65 | - client
66 | - clientgroup
67 | - agent
68 | - instance
69 | - backupset
70 | - subclient
71 | - job_id
72 | - media_agent
73 | - storage_pool
74 | - disk_library
75 |
76 | type: dict
77 |
78 | commcell:
79 | description:
80 | - mandatory to perform any tasks, when performing login operation commcell is registered
81 |
82 | required: true
83 |
84 | entity_type:
85 | description:
86 | - corresponds to basic CVPySDK class
87 |
88 | required: false
89 |
90 | default: ''
91 |
92 | choices:
93 | - Commcell
94 | - Clients
95 | - Client
96 | - Clientgroups
97 | - Clientgroup
98 | - Agents
99 | - Agent
100 | - Instances
101 | - Instance
102 | - Backupsets
103 | - Backupset
104 | - Subclients
105 | - Subclient
106 | - Job
107 | - MediaAgents
108 | - MediaAgent
109 | - StoragePools
110 | - StoragePool
111 | - DiskLibraries
112 | - DiskLibrary
113 |
114 | type: str
115 |
116 | args:
117 | description:
118 | - arguments to be passed to the CVPySDK methods
119 |
120 | required: false
121 |
122 | default: {}
123 |
124 | type: dict
125 |
126 | requirements:
127 |
128 | - Ansible
129 |
130 | - Python 2.7 or above
131 |
132 | - CVPySDK
133 |
134 | - Commvault Software v11 SP16 or later release with WebConsole installed
135 |
136 | '''
137 |
138 | EXAMPLES = '''
139 | **Login to Commcell:**
140 |
141 | - name: Login
142 | commvault:
143 | operation: login
144 | entity: {
145 | webconsole_hostname: "{{ webconsole_hostname }}",
146 | commcell_username: "{{ commcell_username }}",
147 | commcell_password: "{{ commcell_password }}"
148 | }
149 | register: commcell
150 |
151 | **Force HTTPS login using self-signed certificate**
152 |
153 | - name: Login
154 | commvault:
155 | operation: login
156 | entity: {
157 | webconsole_hostname: "{{ webconsole_hostname }}",
158 | commcell_username: "{{ commcell_username }}",
159 | commcell_password: "{{ commcell_password }}",
160 | force_https: True,
161 | certificate_path: '/tmp/certificates'
162 | }
163 | register: commcell
164 |
165 | **Run backup for a subclient:**
166 |
167 | - name: Backup
168 | commvault:
169 | operation: "backup"
170 | entity_type: subclient
171 | commcell: "{{ commcell }}"
172 | entity: {
173 | client: "client name",
174 | agent: "file system",
175 | backupset: "defaultbackupset",
176 | subclient: "default"
177 | }
178 | register: backup_job
179 |
180 | **Run restore in place job for a subclient:**
181 |
182 | - name: Restore
183 | commvault:
184 | operation: "restore_in_place"
185 | entity_type: subclient
186 | commcell: "{{ commcell }}"
187 | entity: {
188 | client: "client name",
189 | agent: "file system",
190 | backupset: "defaultbackupset",
191 | subclient: "default"
192 | }
193 | args: {
194 | paths: ['path']
195 | }
196 | register: restore_job
197 |
198 | **Wait for the restore job to complete:**
199 |
200 | - name: wait for restore job to complete
201 | commvault:
202 | operation: "wait_for_completion"
203 | entity_type: "job"
204 | commcell: "{{ commcell }}"
205 | entity: {
206 | job_id: "{{ restore_job.output }}"
207 | }
208 | register: restore_status
209 |
210 | **Get storage pool properties:**
211 |
212 | - name: "get storage pool properties"
213 | commvault:
214 | operation: "storage_pool_properties"
215 | entity_type: storagepool
216 | commcell: "{{ commcell }}"
217 | entity: {
218 | "storage_pool": "dedicated cl2"
219 | }
220 | register: storage_pool_props
221 |
222 | '''
223 |
224 | RETURN = '''
225 |
226 | return name: output
227 |
228 | returned: always
229 |
230 | sample: {
231 | output: "output of operation"
232 | }
233 |
234 | '''
235 |
236 | from ansible.module_utils.basic import AnsibleModule
237 | from cvpysdk.commcell import Commcell
238 | from cvpysdk.job import Job
239 |
240 |
241 | commcell = client = clients = agent = agents = instance = instances = backupset = backupsets = subclient = subclients = None
242 |
243 | clientgroups = clientgroup = job = jobs = None
244 |
245 | mediaagents = mediaagent = storagepools = storagepool = disklibraries = disklibrary = None
246 |
247 | result = {}
248 |
249 |
250 | def login(module):
251 | """
252 | sign in the user to the commcell with the credentials provided
253 |
254 | Args:
255 | module (dict) -- webconsole and authentication details
256 |
257 | """
258 | global commcell_object
259 |
260 | if module.get('authtoken'):
261 | commcell_object = Commcell(
262 | module['webconsole_hostname'],
263 | authtoken=module['authtoken'],
264 | force_https=module.get('force_https', False),
265 | certificate_path=module.get('certificate_path')
266 | )
267 |
268 | else:
269 | commcell_object = Commcell(
270 | webconsole_hostname=module['webconsole_hostname'],
271 | commcell_username=module['commcell_username'],
272 | commcell_password=module['commcell_password'],
273 | force_https=module.get('force_https', False),
274 | certificate_path=module.get('certificate_path')
275 | )
276 |
277 |
278 | def create_object(entity):
279 | """
280 | To create the basic commvault objects
281 |
282 | entity (dict) -- basic commvault object names
283 |
284 | Example:
285 | {
286 | client: "",
287 | agent: "",
288 | instance: ""
289 | backupset: "",
290 | subclient: ""
291 | }
292 |
293 | """
294 | global commcell, client, clients, agent, agents, instance, instances, backupset, backupsets, subclient, subclients, result, clientgroup, clientgroups
295 | global job, jobs
296 | global mediaagents, mediaagent, storagepools, storagepool, disklibraries, disklibrary
297 |
298 | commcell = commcell_object
299 | clients = commcell_object.clients
300 | clientgroups = commcell_object.client_groups
301 | jobs = commcell_object.job_controller
302 | mediaagents = commcell_object.media_agents
303 | storagepools = commcell_object.storage_pools
304 | disklibraries = commcell_object.disk_libraries
305 |
306 | if 'client' in entity:
307 |
308 | client = clients.get(entity['client'])
309 | agents = client.agents
310 |
311 | if 'agent' in entity:
312 | agent = agents.get(entity['agent'])
313 | instances = agent.instances
314 | backupsets = agent.backupsets
315 |
316 | if 'instance' in entity:
317 | instance = instances.get(entity['instance'])
318 | subclients = instance.subclients
319 |
320 | if 'backupset' in entity:
321 | backupset = backupsets.get(entity['backupset'])
322 | subclients = backupset.subclients
323 |
324 | if subclients and 'subclient' in entity:
325 | subclient = subclients.get(entity['subclient'])
326 |
327 | if 'job_id' in entity:
328 | job = jobs.get(entity['job_id'])
329 |
330 | if 'clientgroup' in entity:
331 | clientgroup = clientgroups.get(entity['clientgroup'])
332 |
333 | if 'media_agent' in entity:
334 | mediaagent = mediaagents.get(entity['media_agent'])
335 |
336 | if 'storage_pool' in entity:
337 | storagepool = storagepools.get(entity['storage_pool'])
338 |
339 | if 'disk_library' in entity:
340 | disklibrary = disklibraries.get(entity['disk_library'])
341 |
342 |
343 | def main():
344 | """Main method for this module"""
345 | module_args = dict(
346 | operation=dict(type='str', required=True),
347 | entity=dict(type="dict", default={}),
348 | entity_type=dict(type='str', default=''),
349 | commcell=dict(type='dict', default={}),
350 | args=dict(type='dict', default={})
351 | )
352 |
353 | module = AnsibleModule(
354 | argument_spec=module_args,
355 | supports_check_mode=True
356 | )
357 |
358 | global result
359 | result = dict()
360 | if module.params['operation'].lower() == 'login':
361 | login(module.params['entity'])
362 | result['changed'] = True
363 | result['authtoken'] = commcell_object.auth_token
364 | result['webconsole_hostname'] = commcell_object.webconsole_hostname
365 | else:
366 | login(module.params['commcell'])
367 | create_object(module.params['entity'])
368 | # module.exit_json(**module.params['entity'])
369 |
370 | obj_name = module.params["entity_type"]
371 | obj = eval(obj_name)
372 | method = module.params["operation"]
373 |
374 | if not hasattr(obj, method):
375 | obj_name = '{}s'.format(module.params["entity_type"])
376 | obj = eval(obj_name)
377 |
378 | statement = '{0}.{1}'.format(obj_name, method)
379 | attr = getattr(obj, method)
380 |
381 | if callable(attr):
382 | if module.params.get('args'):
383 | args = module.params["args"]
384 | statement = '{0}(**{1})'.format(statement, args)
385 | else:
386 | statement = '{0}()'.format(statement)
387 |
388 | else:
389 | if module.params.get('args'):
390 | statement = '{0} = list(module.params["args"].values())[0]'.format(statement)
391 | exec(statement)
392 | result['output'] = "Property set successfully"
393 | module.exit_json(**result)
394 |
395 | output = eval(statement)
396 |
397 | if type(output).__module__ in ['builtins', '__builtin__']:
398 | result['output'] = output
399 | elif isinstance(output, Job):
400 | result['output'] = output.job_id
401 | else:
402 | result['output'] = str(output)
403 |
404 | module.exit_json(**result)
405 |
406 |
407 | if __name__ == '__main__':
408 | main()
409 |
--------------------------------------------------------------------------------
/update_subclient_description.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Commvault Ansible
3 | gather_facts: no
4 | hosts: localhost
5 | connection: local
6 |
7 | vars:
8 | webconsole_hostname: 'hostname'
9 | commcell_username: 'username'
10 | commcell_password: 'password'
11 | client: 'sample client'
12 |
13 | tasks:
14 | - name: Commvault commcell initialization
15 | block:
16 | - name: Login
17 | commvault:
18 | operation: LOGIN
19 | entity: {
20 | webconsole_hostname: "{{ webconsole_hostname }}",
21 | commcell_username: "{{ commcell_username }}",
22 | commcell_password: "{{ commcell_password }}"
23 | }
24 | register: commcell
25 | - debug:
26 | msg: "Login is done successfully"
27 | rescue:
28 | - debug:
29 | msg: 'Login failed'
30 |
31 | - name: changing subclient description
32 | commvault:
33 | operation: "description"
34 | entity_type: subclient
35 | commcell: "{{ commcell }}"
36 | entity: {
37 | client: "{{ client }}",
38 | agent: "file system",
39 | backupset: "defaultbackupset",
40 | subclient: "default"
41 | }
42 | args: {
43 | "value": "setting subclient description"
44 | }
45 | register: output
46 |
47 | - debug:
48 | msg: "Successful {{ output.output }}"
49 |
50 | ...
--------------------------------------------------------------------------------