diff --git a/provisioning.yaml b/provisioning.yaml index db9a075..4cf0cbc 100755 --- a/provisioning.yaml +++ b/provisioning.yaml @@ -2,13 +2,13 @@ zones: - name: internet settings: configuration: + network: 192.168.0.0/24 host: - network: 192.168.1.0/24 - start: 192.168.1.10 - stop: 192.168.1.100 - dns: [192.168.1.2] - vlan_id: 192 - gateway: 192.168.1.254 + start: 192.168.0.150 + stop: 192.168.0.200 + dns: [192.168.0.1] + vlan_id: 0 + gateway: 192.168.0.1 clusters: - name: hapy.ac-test.fr @@ -33,27 +33,12 @@ servermodels: unbound_allowed_client_cidr: 192.168.1.0/24 reseau: unbound_route_address: 192.168.1.254 - unbound: - unbound_zone_cadoles_com: - hostname_cadoles_com: - hostname_cadoles_com: - - toto - - titi - ip_cadoles_com: - - index: 0 - value: 192.168.1.25 - type_cadoles_com: - - index: 1 - value: CNAME - cname_cadoles_com: - - index: 1 - value: toto.cadoles.com - name: aca applicationservices: [openssh-server] settings: configuration: - serveur_ssh: - ssh_allow_networks: admin.cadoles.com + ssh_server: + ssh_allow_cidr: 192.168.0.0/24 children: - name: etb1 children: @@ -61,8 +46,21 @@ servermodels: other_parents: [unbound] settings: configuration: - reseau: - unbound_domain_name: dns.cadoles.com + unbound: + unbound_zone_cadoles_com: + hostname_cadoles_com: + hostname_cadoles_com: + - toto + - titi + ip_cadoles_com: + - index: 0 + value: 192.168.1.25 + type_cadoles_com: + - index: 1 + value: CNAME + cname_cadoles_com: + - index: 1 + value: toto.cadoles.com organizations: - name: cadoles.com @@ -75,12 +73,9 @@ organizations: zones: [internet] servermodel: unbound_etab1 settings: - configuration: - reseau: - unbound_ip_address_cidr: 192.168.1.2/24 opennebula: cpu: 0.2 vcpu: 2 - memory: 2 + memory: 2048 - name: etab2 zones: [internet] diff --git a/provisioning_example.sh b/provisioning_example.sh index 646f305..938675f 100755 --- a/provisioning_example.sh +++ b/provisioning_example.sh @@ -34,12 +34,12 @@ cucchiaiata-cli v1.user.role.create --user_login gnunux \ cucchiaiata-cli v1.infra.zone.create --zone_name internet # zone configuration S=$(get_id "cucchiaiata-cli v1.setting.session.zone.start --zone_name internet") -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.host.network "192.168.1.0/24" \ - --configuration.host.start "192.168.1.10" \ - --configuration.host.stop "192.168.1.100" \ - --configuration.dns 192.168.1.2 \ - --configuration.vlan_id 192 \ - --configuration.gateway 192.168.1.254 +cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.network "192.168.0.0/24" \ + --configuration.host.start "192.168.0.150" \ + --configuration.host.stop "192.168.0.200" \ + --configuration.dns 192.168.0.1 \ + --configuration.vlan_id 0 \ + --configuration.gateway 192.168.0.1 cucchiaiata-cli v1.setting.session.validate --session_id $S cucchiaiata-cli v1.setting.session.stop --session_id "$S" --save @@ -59,7 +59,7 @@ cucchiaiata-cli v1.infra.cluster.node.create --node_name node1.cadoles.com \ # configuration S=$(get_id "cucchiaiata-cli v1.setting.session.cluster.start --cluster_name hapy.ac-test.fr") -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.virtual_ip "192.168.1.1" +cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.virtual_ip "192.168.0.115" # FIXME endpoint == https:///RPC2 cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.opennebula.one_user "eoleone" cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.opennebula.one_password "eole" @@ -101,24 +101,23 @@ cucchiaiata-cli v1.setting.servermodel.create --servermodel_name unbound_etab1 - # Servermodel ACA S=$(get_id "cucchiaiata-cli v1.setting.session.servermodel.start --servermodel_name aca") -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.serveur_ssh.ssh_allow_networks admin.cadoles.com +cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.ssh_server.ssh_allow_cidr 192.168.0.0/24 cucchiaiata-cli v1.setting.session.stop --session_id "$S" --save # Servermodel unbound S=$(get_id "cucchiaiata-cli v1.setting.session.servermodel.start --servermodel_name unbound") -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.serveur_dns.unbound_local_zones cadoles.com \ - --configuration.reseau.unbound_route_address 192.168.1.254 \ - --configuration.serveur_dns.unbound_allowed_client_cidr 192.168.1.0/24 -cucchiaiata-cli v1.setting.session.filter --session_id "$S" --namespace unbound -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.hostname_cadoles_com toto titi \ - --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.ip_cadoles_com 0 192.168.1.25 \ - --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.type_cadoles_com 1 CNAME \ - --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.cname_cadoles_com 1 toto.cadoles.com +cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.dns_server.unbound_role autorité \ + --configuration.dns_server.unbound_allowed_client_cidr 192.168.0.0/24 \ + --configuration.dns_zone.unbound_local_zones cadoles.com cucchiaiata-cli v1.setting.session.stop --session_id "$S" --save # Servermodel unbound_etab1 S=$(get_id "cucchiaiata-cli v1.setting.session.servermodel.start --servermodel_name unbound_etab1") -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.reseau.unbound_domain_name dns.cadoles.com +cucchiaiata-cli v1.setting.session.filter --session_id "$S" --namespace unbound +cucchiaiata-cli v1.setting.session.configure --session_id "$S" --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.hostname_cadoles_com toto titi \ + --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.ip_cadoles_com 0 192.168.0.25 \ + --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.type_cadoles_com 1 CNAME \ + --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.cname_cadoles_com 1 toto.cadoles.com cucchiaiata-cli v1.setting.session.stop --session_id "$S" --save # Server @@ -138,11 +137,10 @@ cucchiaiata-cli v1.infra.server.create --server_name dns.cadoles.com \ # configuration sleep 1 S=$(get_id "cucchiaiata-cli v1.setting.session.server.start --server dns.cadoles.com") -cucchiaiata-cli v1.setting.session.configure --session_id "$S" --configuration.reseau.unbound_ip_address_cidr 192.168.1.2/24 cucchiaiata-cli v1.setting.session.filter --session_id "$S" --namespace opennebula cucchiaiata-cli v1.setting.session.configure --session_id "$S" --opennebula.cpu 0.2 \ --opennebula.vcpu 2 \ - --opennebula.memory 2 + --opennebula.memory 2048 cucchiaiata-cli v1.setting.session.validate --session_id $S cucchiaiata-cli v1.setting.session.stop --session_id "$S" --save diff --git a/scripts/cucchiaiata-cli b/scripts/cucchiaiata-cli index 810eeaf..f09a1d8 100755 --- a/scripts/cucchiaiata-cli +++ b/scripts/cucchiaiata-cli @@ -1,22 +1,35 @@ #!/usr/bin/python3 """Zephir-cmd-input script """ +from os import environ from sys import exit, argv -from json import dumps from traceback import print_exc +from json import dumps from cucchiaiata import Parser, config, Configuration, JsonError from cucchiaiata.i18n import _ +from cucchiaiata.output.interactive import get as interactive_get +from cucchiaiata.output.json import get as json_get def main(): + dico = {'interactive': interactive_get, + 'json': json_get, + } + default_outputs = ','.join(dico.keys()) + outputs = [dico[output] for output in environ.get('RISOTTO_OUTPUT', default_outputs).split(',')] try: if len(argv) > 2 and argv[1] == 'v1.setting.session.configure': Configuration().get() else: parser = Parser() - print(dumps(parser.get(), - indent=config.indent), - ) + message = parser.remote_config.option('message').value.get() + for output in outputs: + func = output(message) + if func: + func(parser.get(), + config, + ) + break except KeyboardInterrupt: pass except JsonError as err: diff --git a/src/cucchiaiata/common.py b/src/cucchiaiata/common.py index d4eeeee..03166d2 100644 --- a/src/cucchiaiata/common.py +++ b/src/cucchiaiata/common.py @@ -1,3 +1,4 @@ +from os import environ from os.path import isfile from requests import get, post from json import dumps @@ -23,11 +24,6 @@ class Common: def __init__(self): self.cucchiaiata_config = config - def get_token(self): - if isfile(self.cucchiaiata_config.token_file): - return open(self.cucchiaiata_config.token_file).read() - return '' - def get_error_from_http(self, req): try: @@ -42,8 +38,7 @@ class Common: config_type=Config, ): "retrieves the remote config from the distant api description" - token = self.get_token() - headers = {'Authorization':'Bearer {}'.format(token)} + headers = get_headers() req = get(url, headers=headers, verify=config.allow_insecure_https, @@ -91,6 +86,17 @@ class Common: raise err from err +def get_headers(): + headers = {} + if isfile(config.token_file): + with open(config.token_file) as token_file: + token = token_file.read() + headers['Authorization'] = f'Bearer {token}' + if 'FORCE_RISOTTO_USER' in environ: + headers['username'] = environ['FORCE_RISOTTO_USER'] + return headers + + def send_data(uri: str, payload: Dict, ): @@ -101,6 +107,7 @@ def send_data(uri: str, ) ret = post(final_url, data=dumps(payload), + headers=get_headers(), verify=config.allow_insecure_https) try: response = ret.json() diff --git a/src/cucchiaiata/output/__init__.py b/src/cucchiaiata/output/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/cucchiaiata/output/interactive.py b/src/cucchiaiata/output/interactive.py new file mode 100644 index 0000000..2518979 --- /dev/null +++ b/src/cucchiaiata/output/interactive.py @@ -0,0 +1,86 @@ +from paramiko.config import SSHConfig +from os.path import expandvars, isdir, isfile, join +from os import open as os_open, write, close, truncate, makedirs, O_WRONLY, O_CREAT + + +def setting_pki_openssh_client(dico, config): + config_dir = expandvars('$HOME/.ssh') + config_file = join(config_dir, 'config') + identityfile = join(expandvars('$HOME/.ssh'), f'risotto_{dico["organization_name"]}') + known_hosts = expandvars('$HOME/.ssh/known_hosts') + hostname = f'*.{dico["organization_name"]}' + new_data = {'identityfile': [identityfile], + 'stricthostkeychecking': 'yes', + 'hostname': hostname, + 'user': dico['cn'], + } + ssh = SSHConfig() + if isfile(config_file): + ssh.parse(open(config_file)) + if hostname not in ssh.get_hostnames(): + print(f'\n\nIl faudrait ajouter dans le fichier "{config_file}" :') + print(f'Host {hostname}') + for key, value in new_data.items(): + if key == 'hostname': + continue + print(f' {key} {value}') + print('\n') + else: + current_data = dict(ssh.lookup(hostname)) + if current_data != new_data: + current = set(current_data) + new = set(new_data) + add = new - current + modify = [key for key in new if key in current and current_data[key] != new_data[key]] + if add or modify: + print(f'\n\nModifications suggérées de la section "Host {hostname}"du fichier "{config_file}" :') + for line in add: + value = new_data[line] + if isinstance(value, list): + value = ','.join(value) + print(f' - ajouter "{line} {value}"') + for line in modify: + value = new_data[line] + if isinstance(value, list): + value = ','.join(value) + print(f' - modifier "{line} {value}"') + print('\n') + else: + print(f'\n\nIl faudrait créer le fichier "{config_file}" :') + print(f'Host {hostname}') + for key, value in new_data.items(): + if key == 'hostname': + continue + print(f' {key} {value}') + if not isdir(config_dir): + makedirs(config_dir, 0o700) + fh = os_open(f'{identityfile}.pub', O_WRONLY | O_CREAT, 0o400) + truncate(fh, 0) + write(fh, dico['certificate'].encode()) + write(fh, b'\n') + close(fh) + if 'private_key' in dico: + fh = os_open(identityfile, O_WRONLY | O_CREAT, 0o400) + truncate(fh, 0) + write(fh, dico['private_key'].encode()) + write(fh, b'\n') + close(fh, ) + content = [f'@cert-authority *.cadoles.com {dico["chain"]}'] + if isfile(known_hosts): + with open(known_hosts) as fh: + old = fh.read().strip() + for line in old.split('\n'): + if line.startswith(f'@cert-authority {hostname} '): + continue + content.append(line) + fh = os_open(known_hosts, O_WRONLY | O_CREAT, 0o400) + truncate(fh, 0) + for line in content: + write(fh, f'{line}\n'.encode()) + close(fh) + print('Certificat mise à jour') + + +def get(message): + if message == 'v1.setting.pki.openssh.client.get': + return setting_pki_openssh_client diff --git a/src/cucchiaiata/output/json.py b/src/cucchiaiata/output/json.py new file mode 100644 index 0000000..6a8485e --- /dev/null +++ b/src/cucchiaiata/output/json.py @@ -0,0 +1,10 @@ +from json import dumps + + +def print_json(dico, config): + indent = config.indent + print(dumps(dico, indent = indent)) + + +def get(message): + return print_json