diff options
author | UnicronNL <kim.sidney@gmail.com> | 2019-08-16 14:08:14 +0200 |
---|---|---|
committer | UnicronNL <kim.sidney@gmail.com> | 2019-08-16 14:09:44 +0200 |
commit | 664a6f63e8f36c520be16072d349b39d58f09e31 (patch) | |
tree | 00aa6bad1a8c81dfd69cdd54850f53b3babf9303 | |
parent | 1a5e9cc15f53e035f6fcff9518425bda8a96d12d (diff) | |
download | vyos-cloud-init-664a6f63e8f36c520be16072d349b39d58f09e31.tar.gz vyos-cloud-init-664a6f63e8f36c520be16072d349b39d58f09e31.zip |
update vyos config module to include network config
-rw-r--r-- | cloudinit/config/cc_vyos.py | 156 |
1 files changed, 124 insertions, 32 deletions
diff --git a/cloudinit/config/cc_vyos.py b/cloudinit/config/cc_vyos.py index d01f1fc1..9a1d1809 100644 --- a/cloudinit/config/cc_vyos.py +++ b/cloudinit/config/cc_vyos.py @@ -21,10 +21,13 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os +import re import sys import ast +import subprocess from ipaddress import IPv4Network +from cloudinit import stages from cloudinit import util from cloudinit.distros import ug_util @@ -56,6 +59,7 @@ def set_ssh_login(config, log, user, key_string, key_x): key_name = None if key_string == '': + log.debug("No keys found.") return key_parts = key_string.split(None) @@ -90,15 +94,6 @@ def set_ssh_login(config, log, user, key_string, key_x): config.set(['system', 'login', 'user', user, 'level'], value='admin', replace=True) -def set_config_cloud(config, hostname): - config.set(['service', 'ssh'], replace=True) - config.set(['service', 'ssh', 'port'], value='22', replace=True) - config.set(['service', 'ssh', 'client-keepalive-interval'], value='180', replace=True) - config.set(['interfaces', 'ethernet', 'eth0', 'address'], value='dhcp', replace=True) - config.set_tag(['interfaces', 'ethernet']) - config.set(['system', 'host-name'], value=hostname, replace=True) - - def set_config_ovf(config, hostname, metadata): ip_0 = metadata['ip0'] mask_0 = metadata['netmask0'] @@ -137,14 +132,92 @@ def set_config_ovf(config, hostname, metadata): config.set(['system', 'host-name'], value=hostname, replace=True) +def set_config_interfaces(config, interface): + for item in interface['subnets']: + if item['type'] == 'static': + if 'address' in item and runcommand("/usr/bin/ipaddrcheck --is-ipv4 " + item['address']) == 0: + cidr = str(IPv4Network('0.0.0.0/' + item['netmask']).prefixlen) + ipcidr = item['address'] + '/' + cidr + config.set(['interfaces', 'ethernet', interface['name'], 'address'], value=ipcidr, replace=True) + config.set_tag(['interfaces', 'ethernet']) + if item['gateway']: + config.set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'], value=item['gateway'], replace=True) + config.set_tag(['protocols', 'static', 'route']) + config.set_tag(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop']) + + if 'address' in item and runcommand("/usr/bin/ipaddrcheck --is-ipv6 " + item['address']) == 0: + config.set(['interfaces', 'ethernet', interface['name'], 'address'], value=item['address'], replace=False) + config.set_tag(['interfaces', 'ethernet']) + if item['gateway']: + config.set(['protocols', 'static', 'route6', '::/0', 'next-hop'], value=item['gateway'], replace=True) + config.set_tag(['protocols', 'static', 'route6']) + config.set_tag(['protocols', 'static', 'route6', '::/0', 'next-hop']) + else: + config.set(['interfaces', 'ethernet', interface['name'], 'address'], value='dhcp', replace=True) + config.set_tag(['interfaces', 'ethernet']) + + +def set_config_nameserver(config, log, interface): + if 'address' in interface: + for server in interface['address']: + config.set(['system', 'name-server'], value=server, replace=False) + else: + log.debug("No name-servers found.") + if 'search' in interface: + for server in interface['search']: + config.set(['system', 'domain-search'], value=server, replace=False) + else: + log.debug("No search-domains found.") + + +def set_config_dhcp(config): + config.set(['interfaces', 'ethernet', 'eth0', 'address'], value='dhcp', replace=True) + config.set_tag(['interfaces', 'ethernet']) + + +def set_config_ssh(config): + config.set(['service', 'ssh'], replace=True) + config.set(['service', 'ssh', 'port'], value='22', replace=True) + config.set(['service', 'ssh', 'client-keepalive-interval'], value='180', replace=True) + + +def set_config_hostname(config, hostname): + config.set(['system', 'host-name'], value=hostname, replace=True) + + +def set_config_cloud(config, hostname): + config.set(['service', 'ssh'], replace=True) + config.set(['service', 'ssh', 'port'], value='22', replace=True) + config.set(['service', 'ssh', 'client-keepalive-interval'], value='180', replace=True) + config.set(['interfaces', 'ethernet', 'eth0', 'address'], value='dhcp', replace=True) + config.set_tag(['interfaces', 'ethernet']) + config.set(['system', 'host-name'], value=hostname, replace=True) + + +def runcommand(cmd): + proc = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, + universal_newlines=True) + std_out, std_err = proc.communicate() + return proc.returncode + + def handle(name, cfg, cloud, log, _args): + init = stages.Init() + dc = init.fetch() cfg_file_name = '/opt/vyatta/etc/config/config.boot' bak_file_name = '/opt/vyatta/etc/config.boot.default' metadata = cloud.datasource.metadata - (users, groups) = ug_util.normalize_users_groups(cfg, cloud.distro) - (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) - encrypted_pass = False + (netcfg, _) = init._find_networking_config() + (users, _) = ug_util.normalize_users_groups(cfg, cloud.distro) + (hostname, _) = util.get_hostname_fqdn(cfg, cloud) key_x = 1 + key_y = 0 + + # look at data that can be used for configuration + #print(dir(dc)) if not os.path.exists(cfg_file_name): file_name = bak_file_name @@ -155,23 +228,37 @@ def handle(name, cfg, cloud, log, _args): config_file = f.read() config = ConfigTree(config_file) - if 'Azure' in str(cloud.datasource): + if 'Azure' in dc.dsname: encrypted_pass = True for key, val in users.items(): user = key + if 'passwd' in val: password = val.get('passwd') set_pass_login(config, user, password, encrypted_pass) vyos_keys = metadata['public-keys'] + for ssh_key in vyos_keys: set_ssh_login(config, log, user, ssh_key, key_x) key_x = key_x + 1 - set_config_cloud(config, hostname) - elif 'OVF' in str(cloud.datasource): + else: for user in users: - password = util.get_cfg_option_str(cfg, 'password', None) + password = util.get_cfg_option_str(cfg, 'passwd', None) + + if not password: + password = util.get_cfg_option_str(cfg, 'password', None) + if password and password != '': + hash = re.match("(^\$.\$)", password) + hash_count = password.count('$') + if hash and hash_count >= 3: + base64 = password.split('$')[3] + base_64_len = len(base64) + if ((hash.group(1) == '$1$' and base_64_len == 22) or + (hash.group(1) == '$5$' and base_64_len == 43) or + (hash.group(1) == '$6$' and base_64_len == 86)): + encrypted_pass = True set_pass_login(config, user, password, encrypted_pass) vyos_keys = cloud.get_public_ssh_keys() or [] @@ -182,25 +269,30 @@ def handle(name, cfg, cloud, log, _args): for ssh_key in vyos_keys: set_ssh_login(config, log, user, ssh_key, key_x) key_x = key_x + 1 - set_config_ovf(config, hostname, metadata) - else: - for user in users: - password = util.get_cfg_option_str(cfg, 'passwd', None) - if password: - set_pass_login(config, user, password, encrypted_pass) - vyos_keys = cloud.get_public_ssh_keys() or [] - if 'ssh_authorized_keys' in cfg: - cfgkeys = cfg['ssh_authorized_keys'] - vyos_keys.extend(cfgkeys) + if 'OVF' in dc.dsname: + set_config_ovf(config, hostname, metadata) + elif netcfg: + for interface in netcfg['config']: + if interface['type'] == 'physical': + key_y = 1 + set_config_interfaces(config, interface) + + if interface['type'] == 'nameserver': + set_config_nameserver(config, log, interface) + + set_config_ssh(config) + set_config_hostname(config, hostname) + else: + set_config_dhcp(config) + set_config_ssh(config) + set_config_hostname(config, hostname) - for ssh_key in vyos_keys: - set_ssh_login(config, log, user, ssh_key, key_x) - key_x = key_x + 1 - set_config_cloud(config, hostname) + if key_y == 0: + set_config_dhcp(config) try: with open(cfg_file_name, 'w') as f: f.write(config.to_string()) - except: - util.logexc(log, "Failed to write configs into file %s", file_name) + except Exception as e: + util.logexc(log, "Failed to write configs into file %s error %s", file_name, e) |