summaryrefslogtreecommitdiff
path: root/magnum/drivers/k8s_coreos_v1/templates/fragments/make-cert.yaml
blob: 630ddaa9f1712998ccab26a6266d941cdbeaf497 (plain)
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
#cloud-config
write_files:
  - path: /etc/systemd/system/make-cert.service
    owner: "root:root"
    permissions: "0644"
    content: |
      [Unit]
      Description=Make TLS certificates

      [Service]
      Type=oneshot
      EnvironmentFile=/etc/sysconfig/heat-params
      ExecStart=/etc/sysconfig/make-cert.sh

      [Install]
      WantedBy=multi-user.target

  - path: /etc/sysconfig/make-cert.sh
    owner: "root:root"
    permissions: "0755"
    content: |
      #!/bin/bash

      # Parse the JSON response that contains the TLS certificate, and print
      # out the certificate content.
      function parse_json_response {
        json_response=$1
        # {..,"pem": "ABCD",..} -> ABCD
        key=$(echo "$json_response" | sed 's/^.*"pem": "\([^"]*\)".*$/\1/')
        # decode newline characters
        key=$(echo "$key" | sed 's/\\n/\n/g')
        echo "$key"
      }

      set -o errexit
      set -o nounset
      set -o pipefail

      if [ "$TLS_DISABLED" == "True" ]; then
        exit 0
      fi

      if [[ -z "${KUBE_NODE_PUBLIC_IP}" ]]; then
        KUBE_NODE_PUBLIC_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)
      fi
      if [[ -z "${KUBE_NODE_IP}" ]]; then
        KUBE_NODE_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)
      fi

      sans="IP:${KUBE_NODE_PUBLIC_IP},IP:${KUBE_NODE_IP}"
      if [ "${KUBE_NODE_PUBLIC_IP}" != "${KUBE_API_PUBLIC_ADDRESS}" ] \
        && [ -n "${KUBE_API_PUBLIC_ADDRESS}" ]; then

        sans="${sans},IP:${KUBE_API_PUBLIC_ADDRESS}"
      fi
      if [ "${KUBE_NODE_IP}" != "${KUBE_API_PRIVATE_ADDRESS}" ] \
        && [ -n "${KUBE_API_PRIVATE_ADDRESS}" ]; then
        sans="${sans},IP:${KUBE_API_PRIVATE_ADDRESS}"
      fi
      MASTER_HOSTNAME=${MASTER_HOSTNAME:-}
      if [[ -n "${MASTER_HOSTNAME}" ]]; then
        sans="${sans},DNS:${MASTER_HOSTNAME}"
      fi
      sans="${sans},IP:127.0.0.1"

      KUBE_SERVICE_IP=$(echo $PORTAL_NETWORK_CIDR | awk 'BEGIN{FS="[./]"; OFS="."}{print $1,$2,$3,$4 + 1}')

      sans="${sans},IP:${KUBE_SERVICE_IP}"

      cert_conf_dir=${KUBE_CERTS_PATH}/conf

      mkdir -p ${cert_conf_dir}

      CA_CERT=${KUBE_CERTS_PATH}/ca.pem
      SERVER_CERT=${KUBE_CERTS_PATH}/apiserver.pem
      SERVER_CSR=${KUBE_CERTS_PATH}/apiserver.pem
      SERVER_KEY=${KUBE_CERTS_PATH}/apiserver-key.pem

      #Get a token by user credentials and trust
      cat > auth.json << EOF
      {
          "auth": {
              "identity": {
                  "methods": [
                      "password"
                  ],
                  "password": {
                      "user": {
                          "id": "$TRUSTEE_USER_ID",
                          "password": "$TRUSTEE_PASSWORD"
                      }
                  }
              }
          }
      }
      EOF

      USER_TOKEN=`curl -k -s -i -X POST -H "Content-Type: application/json" -d @auth.json \
                       $AUTH_URL/auth/tokens | grep X-Subject-Token | awk '{print $2}' | tr -d '\r'`

      rm -rf auth.json

      # Get CA certificate for this cluster
      ca_cert_json=$(curl -k -X GET \
        -H "X-Auth-Token: $USER_TOKEN" \
        -H "OpenStack-API-Version: container-infra latest" \
        $MAGNUM_URL/certificates/$CLUSTER_UUID)
      parse_json_response "${ca_cert_json}" > ${CA_CERT}

      # Create config for server's csr
      cat > ${cert_conf_dir}/openssl.cnf <<EOF
      [req]
      distinguished_name = req_distinguished_name
      req_extensions     = req_ext
      prompt = no
      [req_distinguished_name]
      CN = kube-apiserver
      [req_ext]
      subjectAltName = ${sans}
      extendedKeyUsage = clientAuth,serverAuth
      EOF

      # Generate server's private key and csr
      openssl genrsa -out "${SERVER_KEY}" 4096
      chmod 400 "${SERVER_KEY}"
      openssl req -new -days 10000 \
              -key "${SERVER_KEY}" \
              -out "${SERVER_CSR}" \
              -reqexts req_ext \
              -config "${cert_conf_dir}/openssl.cnf"

      # encode newline (\n) characters
      csr=$(cat $SERVER_CSR | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g')
      csr_req="{\"cluster_uuid\": \"$CLUSTER_UUID\", \"csr\": \"$csr\"}"
      # Send csr to Magnum to have it signed
      server_cert_json=$(curl -k -X POST \
          -H "X-Auth-Token: $USER_TOKEN" \
          -H "OpenStack-API-Version: container-infra latest" \
          -H "Content-Type: application/json" \
          -d "$csr_req" \
          $MAGNUM_URL/certificates)
      parse_json_response "${server_cert_json}" > ${SERVER_CERT}

      chmod 600 ${KUBE_CERTS_PATH}/*-key.pem
      # Certs will also be used by etcd service
      chown -R etcd:etcd ${KUBE_CERTS_PATH}