1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4# (c) 2017, Ansible by Red Hat, inc 5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 7from __future__ import absolute_import, division, print_function 8 9__metaclass__ = type 10 11 12DOCUMENTATION = """ 13module: junos_system 14author: Ganesh Nalawade (@ganeshrn) 15short_description: Manage the system attributes on Juniper JUNOS devices 16description: 17- This module provides declarative management of node system attributes on Juniper 18 JUNOS devices. It provides an option to configure host system parameters or remove 19 those parameters from the device active configuration. 20version_added: 1.0.0 21options: 22 hostname: 23 description: 24 - Configure the device hostname parameter. This option takes an ASCII string value. 25 type: str 26 domain_name: 27 description: 28 - Configure the IP domain name on the remote device to the provided value. Value 29 should be in the dotted name form and will be appended to the C(hostname) to 30 create a fully-qualified domain name. 31 type: str 32 domain_search: 33 description: 34 - Provides the list of domain suffixes to append to the hostname for the purpose 35 of doing name resolution. This argument accepts a list of names and will be 36 reconciled with the current active configuration on the running node. 37 type: list 38 elements: str 39 name_servers: 40 description: 41 - List of DNS name servers by IP address to use to perform name resolution lookups. This 42 argument accepts either a list of DNS servers See examples. 43 type: list 44 elements: str 45 state: 46 description: 47 - State of the configuration values in the device's current active configuration. When 48 set to I(present), the values should be configured in the device active configuration 49 and when set to I(absent) the values should not be in the device active configuration 50 type: str 51 default: present 52 choices: 53 - present 54 - absent 55 active: 56 description: 57 - Specifies whether or not the configuration is active or deactivated 58 default: true 59 type: bool 60requirements: 61- ncclient (>=v0.5.2) 62notes: 63- This module requires the netconf system service be enabled on the remote device 64 being managed. 65- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. 66- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). 67- This module also works with C(local) connections for legacy playbooks. 68extends_documentation_fragment: 69- junipernetworks.junos.junos 70""" 71 72EXAMPLES = """ 73- name: configure hostname and domain name 74 junipernetworks.junos.junos_system: 75 hostname: junos01 76 domain_name: test.example.com 77 domain-search: 78 - ansible.com 79 - redhat.com 80 - juniper.net 81 82- name: remove configuration 83 junipernetworks.junos.junos_system: 84 state: absent 85 86- name: configure name servers 87 junipernetworks.junos.junos_system: 88 name_servers: 89 - 8.8.8.8 90 - 8.8.4.4 91""" 92 93RETURN = """ 94diff.prepared: 95 description: Configuration difference before and after applying change. 96 returned: when configuration is changed and diff option is enabled. 97 type: str 98 sample: > 99 [edit system] 100 + host-name test; 101 + domain-name ansible.com; 102 + domain-search redhat.com; 103 [edit system name-server] 104 172.26.1.1 { ... } 105 + 8.8.8.8; 106""" 107import collections 108 109from ansible.module_utils.basic import AnsibleModule 110from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos import ( 111 junos_argument_spec, 112 tostring, 113) 114from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos import ( 115 load_config, 116 map_params_to_obj, 117 map_obj_to_ele, 118) 119from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos import ( 120 commit_configuration, 121 discard_changes, 122 locked_config, 123) 124 125USE_PERSISTENT_CONNECTION = True 126 127 128def validate_param_values(module, obj): 129 for key in obj: 130 # validate the param value (if validator func exists) 131 validator = globals().get("validate_%s" % key) 132 if callable(validator): 133 validator(module.params.get(key), module) 134 135 136def main(): 137 """ main entry point for module execution 138 """ 139 argument_spec = dict( 140 hostname=dict(), 141 domain_name=dict(), 142 domain_search=dict(type="list", elements="str"), 143 name_servers=dict(type="list", elements="str"), 144 state=dict(choices=["present", "absent"], default="present"), 145 active=dict(default=True, type="bool"), 146 ) 147 148 argument_spec.update(junos_argument_spec) 149 150 params = ["hostname", "domain_name", "domain_search", "name_servers"] 151 required_if = [ 152 ("state", "present", params, True), 153 ("state", "absent", params, True), 154 ("state", "active", params, True), 155 ("state", "suspend", params, True), 156 ] 157 158 module = AnsibleModule( 159 argument_spec=argument_spec, 160 required_if=required_if, 161 supports_check_mode=True, 162 ) 163 164 warnings = list() 165 result = {"changed": False} 166 167 if warnings: 168 result["warnings"] = warnings 169 170 top = "system" 171 172 param_to_xpath_map = collections.OrderedDict() 173 param_to_xpath_map.update( 174 [ 175 ("hostname", {"xpath": "host-name", "leaf_only": True}), 176 ("domain_name", {"xpath": "domain-name", "leaf_only": True}), 177 ( 178 "domain_search", 179 { 180 "xpath": "domain-search", 181 "leaf_only": True, 182 "value_req": True, 183 }, 184 ), 185 ("name_servers", {"xpath": "name-server/name", "is_key": True}), 186 ] 187 ) 188 189 validate_param_values(module, param_to_xpath_map) 190 191 want = map_params_to_obj(module, param_to_xpath_map) 192 ele = map_obj_to_ele(module, want, top) 193 194 with locked_config(module): 195 diff = load_config(module, tostring(ele), warnings, action="merge") 196 197 commit = not module.check_mode 198 if diff: 199 if commit: 200 commit_configuration(module) 201 else: 202 discard_changes(module) 203 result["changed"] = True 204 205 if module._diff: 206 result["diff"] = {"prepared": diff} 207 208 module.exit_json(**result) 209 210 211if __name__ == "__main__": 212 main() 213