コード例 #1
0
def update_dns_record(dns_provider,
                      sub_domain,
                      root_domain,
                      load_balancer_ip_or_hostname,
                      cloudflare_email=None,
                      cloudflare_auth_key=None):
    logs.info('updating DNS record',
              dns_provider=dns_provider,
              sub_domain=sub_domain,
              root_domain=root_domain,
              load_balancer_ip_or_hostname=load_balancer_ip_or_hostname,
              cloudflare_email=cloudflare_email,
              cloudflare_auth_key_len=len(cloudflare_auth_key)
              if cloudflare_auth_key else 0)
    if dns_provider == 'cloudflare':
        from ckan_cloud_operator import cloudflare
        cloudflare.update_a_record(cloudflare_email, cloudflare_auth_key,
                                   root_domain, f'{sub_domain}.{root_domain}',
                                   load_balancer_ip_or_hostname)
    elif dns_provider == 'route53':
        from ckan_cloud_operator.providers.cluster.aws import manager as aws_manager
        aws_manager.update_dns_record(sub_domain, root_domain,
                                      load_balancer_ip_or_hostname)
    else:
        raise NotImplementedError()
コード例 #2
0
def create_management_server(interactive, values):
    if values:
        assert not interactive
        values = json.loads(values)
        for k, d in (
            ('apiServer', 'https://cloudcli.cloudwm.com'),
            ('apiClientid', None),
            ('apiSecret', None),
            ('RootDomainName', None),
            ('rancher_sub_domain', None),
            ('CloudflareEmail', None),
            ('CloudflareApiKey', None),
            ('PrivateNetworkName', None),
            ('Datacenter', None),
            ('RAM', '4096'),
            ('CPU', '2B'),
            ('DiskSizeGB', '30'),
            ('management_server_name', None),
            ('rancher_version', 'v2.3.3'),
        ):
            if not values.get(k):
                if d:
                    values[k] = d
                else:
                    raise Exception('missing value for ' + k)
        print('--values:')
        print(values)
    else:
        assert interactive
    subprocess.check_call(['which', 'cloudcli'])
    rundata = _rundata_init('create_management_server')
    if not rundata.get('entered_credentials'):
        if interactive:
            print('Enter the Kamatera connection details, press Enter to keep existing / default values')
            print('You can get Kamatera client ID and secret from the Kamatera Console: https://console.kamatera.com')
            for param in ['apiServer', 'apiClientid', 'apiSecret']:
                value = rundata[param] if param in rundata else ''
                if param == 'apiServer' and not value:
                    value = 'https://cloudcli.cloudwm.com'
                new_value = input('{}{}: '.format(param, (' ('+value+')') if value else ''))
                if new_value:
                    value = new_value
                rundata[param] = value
        else:
            rundata['apiServer'] = values['apiServer']
            rundata['apiClientid'] = values['apiClientid']
            rundata['apiSecret'] = values['apiSecret']
        assert rundata['apiServer'] and rundata['apiClientid'] and rundata['apiSecret']
        rundata['entered_credentials'] = True
        print(_rundata_save(rundata))
    if not rundata.get('entered_domain_name'):
        if interactive:
            print('Enter domain settings')
            print('You must have a domain name connected to a Cloudflare account')
            print('You should provide API keys to cloudflare which have permissions to modify DNS records for this domain')
            for param, default in [
                ('RootDomainName', ''),
                ('CloudflareEmail', ''),
                ('CloudflareApiKey', ''),
            ]:
                value = rundata[param] if param in rundata else default
                new_value = input('{}{}: '.format(param, (' ('+value+')') if value else ''))
                if new_value:
                    value = new_value
                rundata[param] = value
        else:
            rundata['RootDomainName'] = values['RootDomainName']
            rundata['CloudflareEmail'] = values['CloudflareEmail']
            rundata['CloudflareApiKey'] = values['CloudflareApiKey']
        rundata['entered_domain_name'] = True
        print(_rundata_save(rundata))
    datacenter_param_label = 'Datacenter (must match private network datacenter)'
    if not rundata.get('entered_server_args'):
        if interactive:
            print('Enter server settings')
            print('You can accept defaults, or check Kamatera Web UI / docs for available values')
            print('Make sure the selected Datacenter matches the datacenter of the private network you created')
            for param, default in [
                ('PrivateNetworkName', ''),
                (datacenter_param_label, 'EU'),
                ('RAM', '4096'),
                ('CPU', '2B'),
                ('DiskSizeGB', '30')
            ]:
                value = rundata[param] if param in rundata else default
                new_value = input('{}{}: '.format(param, (' ('+value+')') if value else ''))
                if new_value:
                    value = new_value
                rundata[param] = value
        else:
            rundata['PrivateNetworkName'] = values['PrivateNetworkName']
            rundata[datacenter_param_label] = values['Datacenter']
            rundata['RAM'] = values['RAM']
            rundata['CPU'] = values['CPU']
            rundata['DiskSizeGB'] = values['DiskSizeGB']
        rundata['entered_server_args'] = True
        print(_rundata_save(rundata))
    if not rundata.get('entered_server_name'):
        if interactive:
            print('Enter the management server name')
            print('E.g. my-cluster-management')
            rundata['entered_server_name'] = input('server name: ')
        else:
            rundata['entered_server_name'] = values['management_server_name']
        print(_rundata_save(rundata))
    if not rundata.get('generated_password'):
        rundata['generated_password'] = '******'+binascii.hexlify(os.urandom(6)).decode() + '!'
        print(_rundata_save(rundata))
    cloudcli_connection_args = '--api-clientid {clientid} --api-secret {secret} --api-server {server}'.format(
        clientid=rundata['apiClientid'], secret=rundata['apiSecret'], server=rundata['apiServer'], )
    if not rundata.get('server_created'):
        print('Creating server...')
        subprocess.check_call('cloudcli init {cloudcli_connection_args} && cloudcli server create --wait {cloudcli_connection_args} --name {name} --datacenter {datacenter} --image {image} --cpu {cpu} --ram {ram} --disk {disk} --network name=wan --network name={networkname} --password {password}'.format(
            cloudcli_connection_args=cloudcli_connection_args,
            name=rundata['entered_server_name'],
            datacenter=rundata[datacenter_param_label],
            image='ubuntu_server_18.04_64-bit',
            cpu=rundata['CPU'],
            ram=rundata['RAM'],
            disk='size=' + str(rundata['DiskSizeGB']),
            networkname=rundata['PrivateNetworkName'],
            password=rundata['generated_password']
        ), shell=True)
        rundata['server_created'] = True
        print(_rundata_save(rundata))
    if not rundata.get('server_public_ip'):
        rundata['server_info'] = json.loads(subprocess.check_output('cloudcli server info {cloudcli_connection_args} --name {name} --format json'.format(
            cloudcli_connection_args=cloudcli_connection_args,
            name=rundata['entered_server_name']
        ), shell=True))
        for network in rundata['server_info'][0]['networks']:
            if network['network'].startswith('wan'):
                rundata['server_public_ip'] = network['ips'][0]
                break
        assert rundata.get('server_public_ip')
        print(_rundata_save(rundata))
    print('management server public IP: {}'.format(rundata.get('server_public_ip')))
    if not rundata.get('ssh_key'):
        subprocess.check_call('ssh-keygen -t rsa -b 4096 -C "{}" -f .rundata/management_server_id_rsa -N ""'.format(rundata['entered_server_name']), shell=True)
        rundata['ssh_key'] = '.rundata/management_server_id_rsa'
        print(_rundata_save(rundata))
    if not rundata.get('set_ssh_key_on_server'):
        subprocess.check_call('cloudcli server sshkey {cloudcli_connection_args} --name {name} --password {password} --public-key {public_key}'.format(
            cloudcli_connection_args=cloudcli_connection_args,
            name=rundata['entered_server_name'],
            public_key='.rundata/management_server_id_rsa.pub',
            password=rundata['generated_password']
        ), shell=True)
        rundata['set_ssh_key_on_server'] = True
        print(_rundata_save(rundata))

    def ssh_check_call(cmd):
        cmd = 'chmod 400 .rundata/management_server_id_rsa && ssh -i .rundata/management_server_id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@{} \'{}\''.format(rundata['server_public_ip'], cmd)
        subprocess.check_call(cmd, shell=True)

    def ssh_getstatusoutput(cmd):
        cmd = 'chmod 400 .rundata/management_server_id_rsa && ssh -i .rundata/management_server_id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@{} \'{}\''.format(rundata['server_public_ip'], cmd)
        return subprocess.getstatusoutput(cmd)

    def ssh_copy_to_server(local_file, remote_file):
        cmd = 'chmod 400 .rundata/management_server_id_rsa && scp -i .rundata/management_server_id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no {} root@{}:{} '.format(
            local_file,
            rundata['server_public_ip'],
            remote_file
        )
        subprocess.check_call(cmd, shell=True)

    exit_code, machine_rundata = ssh_getstatusoutput('cat .rundata')
    if exit_code != 0:
        machine_rundata = 'CREATED:{}'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        ssh_check_call('echo "{}" > .rundata'.format(machine_rundata))
    print(machine_rundata)

    if 'INSTALLED_NGINX_SSL' not in machine_rundata:
        installation_script = """
        apt-get update &&\
        apt-get install -y nginx software-properties-common &&\
        add-apt-repository ppa:certbot/certbot &&\
        apt-get update &&\
        apt-get install -y python-certbot-nginx &&\
        if [ -e /etc/ssl/certs/dhparam.pem ]; then warning Ephemeral Diffie-Hellman key already exists at /etc/ssl/certs/dhparam.pem - delete to recreate
        else info Generating Ephemeral Diffie-Hellman key && openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048; fi &&\
        mkdir -p /var/lib/letsencrypt/.well-known &&\
        chgrp www-data /var/lib/letsencrypt &&\
        chmod g+s /var/lib/letsencrypt
        """
        ssh_check_call(installation_script)
        ssh_check_call('echo "INSTALLED_NGINX_SSL:{}" >> .rundata'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

    if 'CREATED_NGINX_CONFIGS' not in machine_rundata:
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}""")
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/snippets/letsencrypt.conf')
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# recommended cipher suite for modern browsers
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
# cipher suite for backwards compatibility (IE6/windows XP)
# ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;""")
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/snippets/ssl.conf')
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 900s;""")
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/snippets/http2_proxy.conf')
        ssh_check_call('rm -f /etc/nginx/sites-enabled/*')
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""
map $http_upgrade $connection_upgrade {
    default Upgrade;
    ""      close;
}
server {
  listen 80;
  server_name _;
  include snippets/letsencrypt.conf;
  location / {
      return 200 "it works!";
      add_header Content-Type text/plain;
  }
}""")
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/sites-enabled/default')
        ssh_check_call('echo "CREATED_NGINX_CONFIGS:{}" >> .rundata'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

    if 'FINALIZED_NGINX_SSL_SETUP' not in machine_rundata:
        ssh_check_call("""
        systemctl list-timers | grep certbot &&\
        cat /lib/systemd/system/certbot.timer &&\
        if ! cat /lib/systemd/system/certbot.service | grep "service nginx reload"; then
            sed -i "s/-q renew/-q renew --deploy-hook \\"service nginx reload\\"/" /lib/systemd/system/certbot.service
        fi && systemctl restart nginx
        """)
        ssh_check_call('echo "FINALIZED_NGINX_SSL_SETUP:{}" >> .rundata'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

    exit_code, output = ssh_getstatusoutput('curl -s http://{}'.format(rundata['server_public_ip']))
    assert exit_code == 0 and 'it works!' in output, {'exit_code': exit_code, 'output': output}

    if 'registered_dns_and_ssl' not in rundata:
        if interactive:
            rundata['rancher_sub_domain'] = input('Enter a new sub-domain to use for Rancher under the root domain ' + rundata['RootDomainName'] + ': ')
        else:
            rundata['rancher_sub_domain'] = values['rancher_sub_domain']
        rundata['rancher_domain'] = '{rancher_sub_domain}.{RootDomainName}'.format(**rundata)
        cloudflare.update_a_record(rundata['CloudflareEmail'], rundata['CloudflareApiKey'], rundata['RootDomainName'], rundata['rancher_sub_domain'] + '.' + rundata['RootDomainName'], rundata['server_public_ip'])
        print('Sleeping 5 minutes to let DNS records to propagate')
        time.sleep(60*5)
        ssh_check_call('certbot certonly --agree-tos --email {CloudflareEmail} --webroot -w /var/lib/letsencrypt/ -d {rancher_sub_domain}.{RootDomainName}'.format(**rundata))
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""ssl_certificate /etc/letsencrypt/live/{rancher_sub_domain}.{RootDomainName}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{rancher_sub_domain}.{RootDomainName}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/{rancher_sub_domain}.{RootDomainName}/chain.pem;""".format(**rundata))
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/snippets/letsencrypt_certs.conf')
        ssh_check_call('systemctl restart nginx')
        ssh_check_call('echo "CONFIGURED_MAIN_DOMAIN:{}" >> .rundata'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
        rundata['registered_dns_and_ssl'] = True
        print(_rundata_save(rundata))

    if 'docker_installed' not in rundata:
        ssh_check_call('apt-get update')
        ssh_check_call('DEBIAN_FRONTEND=noninteractive apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common')
        ssh_check_call('curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -')
        if interactive:
            ssh_check_call('apt-key fingerprint 0EBFCD88')
            print('Verify that the fingerprint matches "9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88"')
            input('Press <Enter> to continue...')
        else:
            exit_code, output = ssh_getstatusoutput('apt-key fingerprint 0EBFCD88')
            assert exit_code == 0
            assert '9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88' in output, output
        ssh_check_call('add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"')
        ssh_check_call('apt-get update -y && apt-get install -y docker-ce docker-ce-cli containerd.io')
        rundata['docker_installed'] = True
        print(_rundata_save(rundata))

    if 'rancher_installed' not in rundata:
        exit_code, output = ssh_getstatusoutput('docker ps | grep rancher')
        if exit_code == 0:
            print('Rancher already running, aborting')
            exit(1)
        if interactive:
            rundata['rancher_version'] = input('rancher version (default=v2.3.3): ')
        else:
            rundata['rancher_version'] = values['rancher_version']
        if not rundata['rancher_version']:
            rundata['rancher_version'] = 'v2.3.3'
        rundata['rancher_image'] = "rancher/rancher:{rancher_version}".format(**rundata)
        ssh_check_call('mkdir -p /var/lib/rancher')
        ssh_check_call('docker run -d --name rancher --restart unless-stopped -p 8000:80 \
                        -v "/var/lib/rancher:/var/lib/rancher" "{rancher_image}"'.format(**rundata))
        rundata['rancher_installed'] = True
        print(_rundata_save(rundata))

    ssh_check_call('docker ps')

    if 'rancher_site_registered' not in rundata:
        rundata['rancher_route_host'] = 'localhost'
        rundata['rancher_route_port'] = '8000'
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""location / {{
  proxy_pass http://{rancher_route_host}:{rancher_route_port};
  include snippets/http2_proxy.conf;
}}""".format(**rundata))
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/snippets/rancher.conf')
        with open('.rundata/tmp_nginx_config', 'w') as f:
            f.write("""
map $http_upgrade $connection_upgrade {{
    default Upgrade;
    ""      close;
}}
server {{
  listen 80;
  listen    [::]:80;
  server_name {rancher_domain};
  include snippets/letsencrypt.conf;
  return 301 https://$host$request_uri;
}}
server {{
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name {rancher_domain};
  include snippets/letsencrypt_certs.conf;
  include snippets/ssl.conf;
  include snippets/letsencrypt.conf;
  include snippets/rancher.conf;
}}""".format(**rundata))
        ssh_copy_to_server('.rundata/tmp_nginx_config', '/etc/nginx/sites-enabled/rancher')
        ssh_check_call('systemctl restart nginx')
        rundata['rancher_site_registered'] = True
        print(_rundata_save(rundata))

    if not rundata.get('entered_token'):
        print('Perform the initial setup of Rancher online at https://{rancher_domain}'.format(**rundata))
        input('Press <Return> to continue... ')
        print('As the Rancher admin user - click on the profile image > api keys')
        print('Generate a non scoped API key and paste the bearer token')
        rundata['rancher_endpoint'] = input('Rancher Endpoint: ')
        rundata['rancher_access_key'] = input('Rancher Access Key: ')
        rundata['rancher_secret_key'] = input('Rancher Secret Key: ')
        rundata['rancher_bearer_token'] = input('Rancher Bearer Token: ')
        rundata['entered_token'] = True
        print(_rundata_save(rundata))

    if not rundata.get('rancher_cli_version'):
        print('Enter the rancher CLI version, you can check this via the Rancher Web UI')
        print('If you used a Rancher Version v2.3.x you can leave the default')
        rundata['rancher_cli_version'] = input('rancher CLI version (v2.3.2): ')
        if not rundata['rancher_cli_version']:
            rundata['rancher_cli_version'] = 'v2.3.2'
        subprocess.check_call('curl https://releases.rancher.com/cli2/{rancher_cli_version}/rancher-linux-amd64-{rancher_cli_version}.tar.gz -o rancher-linux-amd64-{rancher_cli_version}.tar.gz'.format(**rundata), shell=True)
        subprocess.check_call('tar -xzvf rancher-linux-amd64-{rancher_cli_version}.tar.gz'.format(**rundata), shell=True)
        subprocess.check_call('./rancher-{rancher_cli_version}/rancher --version'.format(**rundata), shell=True)
        print(_rundata_save(rundata))

    def rancher_check_call(args):
        subprocess.check_call('./rancher-{rancher_cli_version}/rancher {args}'.format(args=args, **rundata), shell=True)

    if not rundata.get('created_cluster'):
        print('The next steps should be performed manually in the Rancher Web UI')
        print("""Add the Kamatera Docker Machine driver

* Tools > Drivers > Node Drivers > Add Node Driver >
* Set Downlad URL: https://github.com/OriHoch/docker-machine-driver-kamatera/releases/download/v1.0.4/docker-machine-driver-kamatera_v1.0.4_linux_amd64.tar.gz
* Create Driver
* Wait for Kamatera driver to be active
""")
        input('Press <Return> to continue...')
        print("""Create the cluster

* Clusters > Add cluster >
* Infrastructure provider: Kamatera
* Cluster name: my-cluster
* add the controlplane node pool
  * Name Prefix: controlplane-worker
  * Count: 1
  * Template: create new template:
    * apiClientId: {apiClientid}
    * apiSecret: {apiSecret}
    * Set options according to your requirements, see Kamatera server options for the available options (must be logged-in to Kamatera console)
    * CPU must be at least: 2B
    * RAM must be at least: 2048, recommended: 4096
    * Disk size must be at least: 30, recommended: 60
    * Private Network Name: {PrivateNetworkName}
    * Name: kamatera-node
    * Engine options > Storage Driver: overlay2
    * Create template
  * set checkboxes: etcd, Control Plane, Workers
* Create cluster
""".format(**rundata))
        print('Wait for cluster to be in ready state (it might take 5-10 minutes)')
        input('Press <Return> to continue...')
        rundata['created_cluster'] = True
        print(_rundata_save(rundata))

    print('login --token {rancher_bearer_token} {rancher_endpoint}'.format(**rundata))
    rancher_check_call('login --token {rancher_bearer_token} {rancher_endpoint}'.format(**rundata))
    rancher_check_call('context switch System')

    def kubectl_check_call(*args):
        subprocess.check_call([
            './rancher-{rancher_cli_version}/rancher'.format(**rundata),
            'kubectl', '--insecure-skip-tls-verify',
            *args
        ])

    def kubectl_check_output(*args):
        return subprocess.check_output([
            './rancher-{rancher_cli_version}/rancher'.format(**rundata),
            'kubectl', '--insecure-skip-tls-verify',
            *args
        ])

    secret_args = []
    secret_args += ['--from-literal=id_rsa='+subprocess.check_output('cat .rundata/management_server_id_rsa', shell=True).decode()]
    secret_args += ['--from-literal=id_rsa.pub='+subprocess.check_output('cat .rundata/management_server_id_rsa.pub', shell=True).decode()]
    machine_data = {}
    for k, v in rundata.items():
        if v is True or k in ['id', 'server_info', 'ssh_key']:
            continue
        if k.startswith('Datacenter '):
            k = 'Datacenter'
        secret_args += ['--from-literal={}={}'.format(k, v)]
        machine_data[k] = v
    try:
        kubectl_check_call('get', 'namespace', 'ckan-cloud-operator')
    except Exception:
        kubectl_check_call('create', 'namespace', 'ckan-cloud-operator')
    try:
        kubectl_check_call('get', 'secret', '-n', 'ckan-cloud-operator', 'cco-kamatera-management-server')
    except Exception:
        kubectl_check_call('create', 'secret', '-n', 'ckan-cloud-operator', 'generic', 'cco-kamatera-management-server', *secret_args)
    kubeconfig_filename = '.{entered_server_name}.kubeconfig'.format(**rundata)
    new_value = input('Enter path to kubeconfig filename (.{entered_server_name}.kubeconfig): '.format(**rundata))
    if new_value:
       kubeconfig_filename = new_value
    kubeconfig = yaml.load(kubectl_check_output('config', 'view', '--raw'))
    for cluster in kubeconfig['clusters']:
        del cluster['cluster']['certificate-authority-data']
    with open(kubeconfig_filename, 'w') as f:
        yaml.dump(kubeconfig, f)
    print()
    print()
    with open(kubeconfig_filename) as f:
        print(f.read())
    print()
    print()
    for k, v in machine_data.items():
        yaml.dump({k: v}, sys.stdout)
    print()
    print('You should copy and paste the kubeconfig file above and the secret values and keep in a safe place')
    input('Press <Enter> to continue...')
コード例 #3
0
def _update(router_name, spec, annotations, routes):
    resource_name = _get_resource_name(router_name)
    router_type = spec['type']
    cloudflare_email, cloudflare_auth_key = get_cloudflare_credentials()
    external_domains = spec.get('external-domains')
    kubectl.apply(
        kubectl.get_configmap(
            resource_name, get_labels(router_name, router_type), {
                'traefik.toml':
                toml.dumps(
                    traefik_router_config.get(
                        routes,
                        cloudflare_email,
                        enable_access_log=bool(spec.get('enable-access-log')),
                        wildcard_ssl_domain=spec.get('wildcard-ssl-domain'),
                        external_domains=external_domains))
            }))
    domains = {}
    httpauth_secrets = []
    for route in routes:
        root_domain, sub_domain = routes_manager.get_domain_parts(route)
        domains.setdefault(root_domain, []).append(sub_domain)
        routes_manager.pre_deployment_hook(
            route, get_labels(router_name, router_type))
        if route['spec'].get('httpauth-secret') and route['spec'][
                'httpauth-secret'] not in httpauth_secrets:
            httpauth_secrets.append(route['spec']['httpauth-secret'])
    load_balancer = kubectl.get_resource('v1', 'Service',
                                         f'loadbalancer-{resource_name}',
                                         get_labels(router_name, router_type))
    load_balancer['spec'] = {
        'ports': [
            {
                'name': '80',
                'port': 80
            },
            {
                'name': '443',
                'port': 443
            },
        ],
        'selector': {
            'app': get_labels(router_name, router_type,
                              for_deployment=True)['app']
        },
        'type': 'LoadBalancer'
    }
    kubectl.apply(load_balancer)
    load_balancer_ip = get_load_balancer_ip(router_name)
    print(f'load balancer ip: {load_balancer_ip}')
    if external_domains:
        from ckan_cloud_operator.providers.routers import manager as routers_manager
        external_domains_router_root_domain = routers_manager.get_default_root_domain(
        )
        env_id = routers_manager.get_env_id()
        assert router_name.startswith(
            'prod-'), f'invalid external domains router name: {router_name}'
        external_domains_router_sub_domain = f'cc-{env_id}-{router_name}'
        cloudflare.update_a_record(
            cloudflare_email, cloudflare_auth_key,
            external_domains_router_root_domain,
            f'{external_domains_router_sub_domain}.{external_domains_router_root_domain}',
            load_balancer_ip)
    else:
        for root_domain, sub_domains in domains.items():
            for sub_domain in sub_domains:
                cloudflare.update_a_record(cloudflare_email,
                                           cloudflare_auth_key, root_domain,
                                           f'{sub_domain}.{root_domain}',
                                           load_balancer_ip)
    kubectl.apply(
        kubectl.get_deployment(
            resource_name,
            get_labels(router_name, router_type, for_deployment=True),
            _get_deployment_spec(
                router_name,
                router_type,
                annotations,
                image=('traefik:1.7' if
                       (external_domains
                        or len(httpauth_secrets) > 0) else None),
                httpauth_secrets=httpauth_secrets)))