forked from ktbyers/ansible-junos-stdlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
junos_install_os
237 lines (202 loc) · 7.87 KB
/
junos_install_os
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/env python2.7
# Copyright (c) 1999-2014, Juniper Networks Inc.
# 2014, Jeremy Schulman
#
# All rights reserved.
#
# License: Apache 2.0
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the Juniper Networks nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
DOCUMENTATION = '''
---
module: junos_install_os
author: Jeremy Schulman, Juniper Networks
version_added: "1.6.0"
short_description: Install Junos OS image
description:
- Install a Junos OS image on one or more routing-engine (RE) components.
This module supports single CPU devices, EX virtual-chassis
(not-mixed mode), and MX dual-RE products.
Check-Mode is supported to report whether or not the current version
matched the desired version.
If the existing version matches, no action is performed, and the
"changed" attribute reports False. If the existing version does not
match, then the following actions are performed
(1) Compuste the MD5 checksum of the package located on the server
(2) Copy the package image to the Junos device
(3) Compute the MD5 checksum on the Junos device and compare the two
(4) Install the Junos package
(5) Reboot the device (default)
requirements:
- py-junos-eznc >= 0.0.5
options:
host:
description:
- should be {{ inventory_hostname }}
required: true
user:
description:
- login user-name
required: false
default: $USER
passwd:
description:
- login password
required: false
default: assumes ssh-key active
reboot:
description:
- determines if a reboot is performed after the OS is loaded
required: false
default: yes
choices: ['yes','no']
reboot_pause:
description:
- amount of time in seconds to wait after the reboot is issued
required: false
default: "10"
version:
description:
- Junos version string as it would be reported by the 'show version'
command
required: true
package:
description:
- complete path on the local server to the Junos image package file
required: true
logfile:
description:
- path on the local server where progress status is logged
for debugging purposes
required: false
default: None
'''
EXAMPLES = '''
- junos_install_os:
host={{ inventory_hostname }}
version=12.1X46-D10.2
package=/usr/local/junos/images/junos-vsrx-12.1X46-D10.2-domestic.tgz
logfile=/usr/local/junos/log/software.log
'''
import logging
from jnpr.junos import Device
def junos_install_os(module, dev):
args = module.params
### -------------------------------------------------------------------------
### logging
### -------------------------------------------------------------------------
logfile = args['logfile']
if logfile is not None:
logging.basicConfig(filename=logfile, level=logging.INFO,
format='%(asctime)s:%(name)s:%(message)s')
logging.getLogger().name = args['host']
def do_log(msg, level='info'):
getattr(logging,level)(msg)
else:
def do_log(msg): pass
### -------------------------------------------------------------------------
### check installed version against desired version
### -------------------------------------------------------------------------
if args['version'] is None:
# extract version string from package file
m = re.search('-([^\\-]*)-domestic.*',args['package'])
args['version'] = m.group(1)
has_ver = dev.facts['version']
should_ver = args['version']
need_upgrade = bool(has_ver != should_ver)
results = dict(changed=need_upgrade, ver=dict(has=has_ver,should=should_ver))
if need_upgrade is False:
do_log("No need to perform upgrade: {}".format( has_ver ))
return results
if module.check_mode is True:
do_log("upgrade REQUIRED has: {}, shoud: {}".format( has_ver, should_ver ))
return results
### -------------------------------------------------------------------------
### proceeed with software install
### -------------------------------------------------------------------------
from jnpr.junos.utils.sw import SW
sw = SW(dev)
package = args['package']
do_log("Starting the software upgrade process: {}".format(package))
def update_my_progress(dev, report):
# log the progress of the installing process
do_log(report)
sw_args = dict(progress=update_my_progress)
sw_args['no_copy'] = module.boolean(args['no_copy'])
ok = sw.install(package, **sw_args)
if ok is not True:
results['failed'] = True
# ok will have the logs for installation failure
results['msg'] = "Unable to install the software: " + ok
do_log(results['msg'], level='error')
return results
### -------------------------------------------------------------------------
### reboot the box if desired
### -------------------------------------------------------------------------
if module.boolean(args['reboot']) is True:
do_log("<REBOOT>")
rsp = sw.reboot()
### -------------------------------------------------------------------------
### all done.
### -------------------------------------------------------------------------
do_log("upgrade pending reboot cycle, please be patient.")
return results
def main():
module = AnsibleModule(
argument_spec = dict(
host=dict(required=True),
package=dict(required=True),
user=dict(required=False, default=os.getenv('USER')),
passwd=dict(required=False, default=None),
version=dict(required=False, default=None),
logfile=dict(required=False, default=None),
no_copy=dict(required=False, choices=BOOLEANS, default=False),
reboot=dict(required=False, choices=BOOLEANS, default=True),
reboot_pause=dict(required=False, type='int', default=10)
),
supports_check_mode = True
)
args = module.params
### @@@ need to verify that the package file actually exists
### @@@ before proceeding.
dev = Device(args['host'], user=args['user'], password=args['passwd'])
try:
dev.open()
except Exception as err:
msg = 'unable to connect to {}: {}'.format(args['host'], str(err))
module.fail_json(msg=msg)
return
results = junos_install_os(module, dev)
results['check_mode'] = module.check_mode
dev.close()
if not module.check_mode and results['changed'] is True:
logging.info('pausing: {}'.format(args['reboot_pause']))
import time
time.sleep( args['reboot_pause'])
logging.info('process completed OK.')
module.exit_json(**results)
from ansible.module_utils.basic import *
main()