diff --git a/README.md b/README.md index 171d599..5182858 100644 --- a/README.md +++ b/README.md @@ -336,7 +336,7 @@ consumers: upstreams: - name: "mockbinUpstream" ensure: "present" - targets: + targets: - target: "server1.mockbin:3001" attributes: weight: 50 @@ -347,6 +347,36 @@ upstreams: slots: 100 ``` +### Certificates & SNIs + +*A certificate object represents a public certificate/private key pair for an SSL certificate. These objects are used by Kong to handle SSL/TLS termination for encrypted requests. Certificates are optionally associated with SNI objects to tie a cert/key pair to one or more hostnames.* + +[Kong Certificate Object Reference](https://getkong.org/docs/0.11.x/admin-api/#certificate-object) + +*An SNI object represents a many-to-one mapping of hostnames to a certificate. That is, a certificate object can have many hostnames associated with it; when Kong receives an SSL request, it uses the SNI field in the Client Hello to lookup the certificate object based on the SNI associated with the certificate.* + +[Kong SNI Objects Reference](https://getkong.org/docs/0.11.x/admin-api/#sni-objects) + +```yaml +certificates: + - ensure: present + cert: >- + -----BEGIN CERTIFICATE----- + MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV + .... + key: >- + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX + .... + snis: + - name: example.com + ensure: present + - name: www.example.com + ensure: present +``` + +> Notice that SNIs are an list of object e.g. `{ name: example.com, ensure: present }` different Kong api itself where it is a list of hostnames + ## Migrating from Kong <=0.9 to >=0.10 diff --git a/examples/certificates.example.md b/examples/certificates.example.md new file mode 100644 index 0000000..b86224f --- /dev/null +++ b/examples/certificates.example.md @@ -0,0 +1,129 @@ +certificates example +-------------------- + +## Config file + +```yaml +certificates: + - ensure: present + cert: '-----BEGIN CERTIFICATE----- + MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV + BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx + MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB + 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC + RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH + gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA + a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 + zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O + BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS + Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz + nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn + R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm + CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV + tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A + RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b + gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl + L5mKwXjd + -----END CERTIFICATE-----' + + key: '-----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX + d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk + dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 + gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO + a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t + H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi + AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk + Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx + f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi + 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D + 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y + 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 + iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud + WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 + QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT + nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw + Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf + OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR + 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx + UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 + akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl + 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 + ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH + rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 + vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== + -----END RSA PRIVATE KEY-----' + snis: + - ensure: present + name: example.com + - ensure: present + name: www.example.com + +``` + +## Using curl + +For illustrative purpose a cURL calls would be the following + +### create certificate + +```sh +$ curl -i -X POST -H "Content-Type: application/json" \ + --url http://localhost:8001/certificates \ + --data '{"key":"-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== -----END RSA PRIVATE KEY-----","cert":"-----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl L5mKwXjd -----END CERTIFICATE-----"}' +``` + +``` +HTTP 201 Created +``` + +``` +{ + "created_at": "___created_at___", + "cert": "-----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl L5mKwXjd -----END CERTIFICATE-----", + "id": "2b47ba9b-761a-492d-9a0c-000000000001", + "key": "-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== -----END RSA PRIVATE KEY-----", + "snis": [] +} +``` + +### add certificate sni + +```sh +$ curl -i -X POST -H "Content-Type: application/json" \ + --url http://localhost:8001/snis/ \ + --data '{"name":"example.com","ssl_certificate_id":"2b47ba9b-761a-492d-9a0c-000000000001"}' +``` + +``` +HTTP 201 Created +``` + +``` +{ + "name": "example.com", + "created_at": "___created_at___", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001" +} +``` + +### add certificate sni + +```sh +$ curl -i -X POST -H "Content-Type: application/json" \ + --url http://localhost:8001/snis/ \ + --data '{"name":"www.example.com","ssl_certificate_id":"2b47ba9b-761a-492d-9a0c-000000000001"}' +``` + +``` +HTTP 201 Created +``` + +``` +{ + "name": "www.example.com", + "created_at": "___created_at___", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001" +} +``` \ No newline at end of file diff --git a/src/actions/certificates.js b/src/actions/certificates.js new file mode 100644 index 0000000..52bea19 --- /dev/null +++ b/src/actions/certificates.js @@ -0,0 +1,25 @@ +export const addCertificate = ({ key, cert }) => ({ + type: 'create-certificate', + endpoint: { name: 'certificates' }, + method: 'POST', + body: { key, cert }, +}); + +export const removeCertificate = certificateId => ({ + type: 'remove-certificate', + endpoint: { name: 'certificate', params: { certificateId } }, + method: 'DELETE', +}); + +export const addCertificateSNI = (ssl_certificate_id, name) => ({ + type: 'add-certificate-sni', + endpoint: { name: 'certificate-snis' }, + method: 'POST', + body: { name, ssl_certificate_id }, +}); + +export const removeCertificateSNI = sniName => ({ + type: 'remove-certificate-sni', + endpoint: { name: 'certificate-sni', params: { sniName } }, + method: 'DELETE', +}); diff --git a/src/adminApi.js b/src/adminApi.js index 77d758a..830352e 100644 --- a/src/adminApi.js +++ b/src/adminApi.js @@ -28,6 +28,7 @@ function createApi({ router, getPaginatedJson, ignoreConsumers }) { fetchUpstreams: () => getPaginatedJson(router({name: 'upstreams'})), fetchTargets: (upstreamId) => getPaginatedJson(router({name: 'upstream-targets', params: {upstreamId}})), fetchTargetsV11Active: (upstreamId) => getPaginatedJson(router({name: 'upstream-targets-active', params: {upstreamId}})), + fetchCertificates: () => getPaginatedJson(router({name: 'certificates'})), // this is very chatty call and doesn't change so its cached fetchPluginSchemas: () => { diff --git a/src/core.js b/src/core.js index 013df1f..50d04de 100644 --- a/src/core.js +++ b/src/core.js @@ -40,6 +40,13 @@ import { updateUpstreamTarget } from './actions/upstreams' +import { + addCertificate, + removeCertificate, + addCertificateSNI, + removeCertificateSNI, +} from './actions/certificates'; + export const consumerAclSchema = { id: 'group' }; @@ -92,6 +99,7 @@ export default async function execute(config, adminApi, logger = () => {}) { ...upstreams(config.upstreams), ...apis(config.apis), ...globalPlugins(config.plugins), + ...certificates(config.certificates), ...consumers(splitConsumersConfig.removed), ]; @@ -139,6 +147,18 @@ export function targets(upstreamName, targets) { return targets.reduce((actions, target) => [...actions, _target(upstreamName, target)], []); } +export function certificates(certificates = []) { + return certificates.reduce((actions, cert) => [...actions, _certificate(cert), ...certificatesSNIs(cert, cert.snis)], []); +} + +export function certificatesSNIs(certificate, snis) { + if (certificate.ensure === 'removed') { + return []; + } + + return snis.reduce((actions, sni) => [...actions, _sni(certificate, sni)], []); +} + function parseResponseContent(content) { try { return JSON.parse(content); @@ -193,7 +213,7 @@ function _bindWorldState(adminApi) { } } -function _createWorld({apis, consumers, plugins, upstreams, _info: { version }}) { +function _createWorld({apis, consumers, plugins, upstreams, certificates, _info: { version }}) { const world = { getVersion: () => version, @@ -411,7 +431,34 @@ function _createWorld({apis, consumers, plugins, upstreams, _info: { version }}) return targets[0]; } - } + }, + getCertificate: ({ key }) => { + const certificate = certificates.find(x => x.key === key); + + invariant(certificate, `Unable to find certificate for ${key.substr(1, 50)}`); + + return certificate; + }, + + getCertificateId: certificate => { + return world.getCertificate(certificate)._info.id; + }, + + hasCertificate: ({ key }) => { + return certificates.some(x => x.key === key); + }, + + isCertificateUpToDate: certificate => { + const { key, cert } = world.getCertificate(certificate); + + return certificate.key == key && certificate.cert == cert; + }, + + getCertificateSNIs: certificate => { + const { snis } = world.getCertificate(certificate); + + return snis; + }, }; return world; @@ -763,3 +810,53 @@ function validateUpstreamRequiredAttributes(upstream) { throw Error(`Upstream name is required: ${JSON.stringify(upstream, null, ' ')}`); } } + +const _certificate = certificate => { + validateEnsure(certificate.ensure); + + return world => { + const identityClue = certificate.key.substr(1, 50); + + if (certificate.ensure == 'removed') { + if (world.hasCertificate(certificate)) { + return removeCertificate(world.getCertificateId(certificate)); + } + + return noop({type: 'noop-certificate', identityClue}); + } + + if (world.hasCertificate(certificate)) { + if (world.isCertificateUpToDate(certificate)) { + return noop({type: 'noop-certificate', identityClue}); + } + + return updateCertificate(world.getCertificateId(certificate), certificate); + } + + return addCertificate(certificate); + } +} + +const _sni = (certificate, sni) => { + validateEnsure(sni.ensure); + invariant(sni.name, 'sni must have a name'); + + return world => { + const currentSNIs = world.getCertificateSNIs(certificate).map(x => x.name); + const hasSNI = currentSNIs.indexOf(sni.name) !== -1; + + if (sni.ensure == 'removed') { + if (hasSNI) { + return removeCertificateSNI(sni.name); + } + + return noop({type: 'noop-certificate-sni-removed', sni}); + } + + if (hasSNI) { + return noop({type: 'noop-certificate-sni', sni}); + } + + return addCertificateSNI(world.getCertificateId(certificate), sni.name); + }; +} diff --git a/src/kongState.js b/src/kongState.js index b497867..d02e743 100644 --- a/src/kongState.js +++ b/src/kongState.js @@ -17,7 +17,15 @@ const fetchUpstreamsWithTargets = async ({ version, fetchUpstreams, fetchTargets ); }; -export default async ({fetchApis, fetchPlugins, fetchGlobalPlugins, fetchConsumers, fetchConsumerCredentials, fetchConsumerAcls, fetchUpstreams, fetchTargets, fetchTargetsV11Active, fetchKongVersion}) => { +const fetchCertificatesForVersion = async ({ version, fetchCertificates }) => { + if (semVer.lte(version, '0.10.0')) { + return Promise.resolve([]); + } + + return await fetchCertificates(); +}; + +export default async ({fetchApis, fetchPlugins, fetchGlobalPlugins, fetchConsumers, fetchConsumerCredentials, fetchConsumerAcls, fetchUpstreams, fetchTargets, fetchTargetsV11Active, fetchCertificates, fetchKongVersion}) => { const version = await fetchKongVersion(); const apis = await fetchApis(); const apisWithPlugins = await Promise.all(apis.map(async item => { @@ -63,12 +71,14 @@ export default async ({fetchApis, fetchPlugins, fetchGlobalPlugins, fetchConsume }); const upstreamsWithTargets = await fetchUpstreamsWithTargets({ version, fetchUpstreams, fetchTargets: semVer.gte(version, '0.12.0') ? fetchTargets : fetchTargetsV11Active }); + const certificates = await fetchCertificatesForVersion({ version, fetchCertificates }); return { apis: apisWithPlugins, consumers: consumersWithCredentialsAndAcls, plugins: globalPlugins, upstreams: upstreamsWithTargets, + certificates, version, }; }; diff --git a/src/logger.js b/src/logger.js index 7c57f27..e3a5059 100644 --- a/src/logger.js +++ b/src/logger.js @@ -15,6 +15,9 @@ export const screenLogger = createLogHandler({ 'noop-credential': ({ credential, credentialIdName }) => console.log(`- credential ${credential.name.bold} with ${credentialIdName.bold}: ${credential.attributes[credentialIdName].bold} ${'is up to date'.bold.green}`), 'noop-upstream': ({ upstream }) => console.log(`upstream ${upstream.name.bold} ${'is up to date'.bold.green}`), 'noop-target': ({ target }) => console.log(`target ${target.target.bold} ${'is up to date'.bold.green}`), + 'noop-certificate': ({ identityClue }) => console.log(`certificate ${identityClue}... ${'is up to date'.bold.green}`), + 'noop-certificate-sni': ({ sni }) => console.log(`certificate sni ${sni.name} ${'is up to date'.bold.green}`), + 'noop-certificate-sni-removed': ({ sni }) => console.log(`certificate sni ${sni.name} ${'is NOT present'.bold.green}`), unknown: action => console.log('unknown action', action), })(message.params), diff --git a/src/parsers/certificates.js b/src/parsers/certificates.js new file mode 100644 index 0000000..d7a6c6f --- /dev/null +++ b/src/parsers/certificates.js @@ -0,0 +1,6 @@ +export const parseCertificates = certs => certs.map(({ cert, key, snis, ..._info }) => ({ + cert, + key, + snis: (snis || []).map(name => ({ name })), + _info, +})); diff --git a/src/readKongApi.js b/src/readKongApi.js index e043111..8ddd4b0 100644 --- a/src/readKongApi.js +++ b/src/readKongApi.js @@ -1,6 +1,7 @@ import semVer from 'semver'; import kongState from './kongState'; import { parseUpstreams } from './parsers/upstreams'; +import { parseCertificates } from './parsers/certificates'; import getCurrentStateSelector from './stateSelector'; export default async (adminApi) => { @@ -12,6 +13,7 @@ export default async (adminApi) => { consumers: parseConsumers(state.consumers), plugins: parseGlobalPlugins(state.plugins), upstreams: semVer.gte(version, '0.10.0') ? parseUpstreams(state.upstreams) : undefined, + certificates: semVer.gte(version, '0.10.0') ? parseCertificates(state.certificates) : undefined, }); }) }; diff --git a/src/reducers/certificates.js b/src/reducers/certificates.js new file mode 100644 index 0000000..7903d0c --- /dev/null +++ b/src/reducers/certificates.js @@ -0,0 +1,33 @@ +import { parseCertificates } from '../parsers/certificates'; + +const sni = (state, log) => { + const { params: { type, endpoint: { params, body } }, content } = log; + + if (state._info.id != content.ssl_certificate_id) { + return state; + } + + switch (type) { + case 'remove-certificate-sni': return { ...state, snis: state.snis.filter(x => x.name !== content.name) }; + case 'add-certificate-sni': return { ...state, snis: [...state.snis, { name: content.name }] }; + default: state; + } + + return state; +} + +export default (state = [], log) => { + if (log.type !== 'response') { + return state; + } + + const { params: { type, endpoint: { params, body } }, content } = log; + + switch (type) { + case 'create-certificate': return [...state, ...parseCertificates([content])]; + + case 'remove-certificate-sni': + case 'add-certificate-sni': return state.map(state => sni(state, log)); + default: return state; + } +}; diff --git a/src/reducers/index.js b/src/reducers/index.js index 0e22588..04b77ec 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -2,6 +2,7 @@ import apis from './apis'; import plugins from './plugins'; import consumers from './consumers'; import upstreams from './upstreams'; +import certificates from './certificates'; const combine = reducers => (state = {}, log) => { return Object.keys(reducers).reduce((nextState, key) => { @@ -26,5 +27,6 @@ export default combine({ apis, plugins, consumers, - upstreams + upstreams, + certificates, }); diff --git a/src/router.js b/src/router.js index d7525a5..4bb3f6c 100644 --- a/src/router.js +++ b/src/router.js @@ -25,6 +25,11 @@ export default function createRouter(host, https) { // Note: this uri must end with a slash for kong version 11 case 'upstream-targets-active': return `${adminApiRoot}/upstreams/${params.upstreamId}/targets/active/`; + case 'certificates': return `${adminApiRoot}/certificates`; + case 'certificate': return `${adminApiRoot}/certificates/${params.certificateId}`; + case 'certificate-snis': return `${adminApiRoot}/snis/`; + case 'certificate-sni': return `${adminApiRoot}/snis/${params.sniName}`; + case 'root': return `${adminApiRoot}`; default: diff --git a/test-integration/__snapshots__/api.test.js.snap b/test-integration/__snapshots__/api.test.js.snap index 2ce9b24..103d74c 100644 --- a/test-integration/__snapshots__/api.test.js.snap +++ b/test-integration/__snapshots__/api.test.js.snap @@ -159,6 +159,7 @@ exports[`API plugins should add mockbin API with a plugins 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -379,6 +380,7 @@ exports[`API plugins should remove mockbin api plugin 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -640,6 +642,7 @@ exports[`API plugins should update mockbin api plugin 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -727,6 +730,7 @@ exports[`API should add the API 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -835,6 +839,7 @@ exports[`API should not update if already up to date 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -944,6 +949,7 @@ exports[`API should remove the api 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -1097,5 +1103,6 @@ exports[`API should update the api 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; diff --git a/test-integration/__snapshots__/bugs.test.js.snap b/test-integration/__snapshots__/bugs.test.js.snap index d472124..7583663 100644 --- a/test-integration/__snapshots__/bugs.test.js.snap +++ b/test-integration/__snapshots__/bugs.test.js.snap @@ -86,5 +86,6 @@ plugins: credentials: false preflight_continue: false upstreams: [] +certificates: [] " `; diff --git a/test-integration/__snapshots__/config.test.js.snap b/test-integration/__snapshots__/config.test.js.snap index c384448..eb78893 100644 --- a/test-integration/__snapshots__/config.test.js.snap +++ b/test-integration/__snapshots__/config.test.js.snap @@ -1,5 +1,224 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should apply certificates.example.yml 1`] = ` +Array [ + Object { + "type": "kong-info", + "version": "___version___", + }, + Object { + "params": Object { + "body": Object { + "cert": "-----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl L5mKwXjd -----END CERTIFICATE-----", + "key": "-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== -----END RSA PRIVATE KEY-----", + }, + "endpoint": Object { + "name": "certificates", + }, + "method": "POST", + "type": "create-certificate", + }, + "type": "request", + "uri": "http://localhost:8001/certificates", + }, + Object { + "content": Object { + "cert": "-----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl L5mKwXjd -----END CERTIFICATE-----", + "created_at": "___created_at___", + "id": "2b47ba9b-761a-492d-9a0c-000000000001", + "key": "-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== -----END RSA PRIVATE KEY-----", + "snis": Array [], + }, + "ok": true, + "params": Object { + "body": Object { + "cert": "-----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl L5mKwXjd -----END CERTIFICATE-----", + "key": "-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== -----END RSA PRIVATE KEY-----", + }, + "endpoint": Object { + "name": "certificates", + }, + "method": "POST", + "type": "create-certificate", + }, + "status": 201, + "statusText": "Created", + "type": "response", + "uri": "http://localhost:8001/certificates", + }, + Object { + "params": Object { + "body": Object { + "name": "example.com", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001", + }, + "endpoint": Object { + "name": "certificate-snis", + }, + "method": "POST", + "type": "add-certificate-sni", + }, + "type": "request", + "uri": "http://localhost:8001/snis/", + }, + Object { + "content": Object { + "created_at": "___created_at___", + "name": "example.com", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001", + }, + "ok": true, + "params": Object { + "body": Object { + "name": "example.com", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001", + }, + "endpoint": Object { + "name": "certificate-snis", + }, + "method": "POST", + "type": "add-certificate-sni", + }, + "status": 201, + "statusText": "Created", + "type": "response", + "uri": "http://localhost:8001/snis/", + }, + Object { + "params": Object { + "body": Object { + "name": "www.example.com", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001", + }, + "endpoint": Object { + "name": "certificate-snis", + }, + "method": "POST", + "type": "add-certificate-sni", + }, + "type": "request", + "uri": "http://localhost:8001/snis/", + }, + Object { + "content": Object { + "created_at": "___created_at___", + "name": "www.example.com", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001", + }, + "ok": true, + "params": Object { + "body": Object { + "name": "www.example.com", + "ssl_certificate_id": "2b47ba9b-761a-492d-9a0c-000000000001", + }, + "endpoint": Object { + "name": "certificate-snis", + }, + "method": "POST", + "type": "add-certificate-sni", + }, + "status": 201, + "statusText": "Created", + "type": "response", + "uri": "http://localhost:8001/snis/", + }, + Object { + "type": "kong-info", + "version": "___version___", + }, + Object { + "params": Object { + "identityClue": "----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAo5B", + "noop": true, + "type": "noop-certificate", + }, + "type": "noop", + }, + Object { + "params": Object { + "noop": true, + "sni": Object { + "ensure": "present", + "name": "example.com", + }, + "type": "noop-certificate-sni", + }, + "type": "noop", + }, + Object { + "params": Object { + "noop": true, + "sni": Object { + "ensure": "present", + "name": "www.example.com", + }, + "type": "noop-certificate-sni", + }, + "type": "noop", + }, +] +`; + +exports[`should apply certificates.example.yml 2`] = ` +"apis: [] +consumers: [] +plugins: [] +upstreams: [] +certificates: + - cert: >- + -----BEGIN CERTIFICATE----- + MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV + BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx + MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB + 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC + RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH + gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA + a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 + zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O + BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS + Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz + nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn + R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm + CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV + tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A + RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b + gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl L5mKwXjd + -----END CERTIFICATE----- + key: >- + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX + d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk + dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 + gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO + a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t + H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi + AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk + Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx + f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi + 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D + 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y + 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 + iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud + WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 + QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT + nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw + Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf + OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR + 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx + UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 + akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl + 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 + ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH + rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 + vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== -----END RSA + PRIVATE KEY----- + snis: + - name: example.com + - name: www.example.com +" +`; + exports[`should apply consumer.example.yml 1`] = ` Array [ Object { @@ -201,6 +420,7 @@ consumers: key: very-secret-key plugins: [] upstreams: [] +certificates: [] " `; @@ -304,6 +524,7 @@ plugins: max_age: 7000 preflight_continue: false upstreams: [] +certificates: [] " `; @@ -638,6 +859,7 @@ consumers: key: very-secret-key plugins: [] upstreams: [] +certificates: [] " `; @@ -1026,6 +1248,7 @@ consumers: key: very-secret-key plugins: [] upstreams: [] +certificates: [] " `; @@ -1558,6 +1781,7 @@ plugins: limit_by: consumer fault_tolerant: true upstreams: [] +certificates: [] " `; @@ -1666,6 +1890,7 @@ exports[`should apply simple-api.example.yml 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -1955,5 +2180,6 @@ upstreams: weight: 50 attributes: slots: 10 +certificates: [] " `; diff --git a/test-integration/__snapshots__/customers.test.js.snap b/test-integration/__snapshots__/customers.test.js.snap index eb76cba..ce64311 100644 --- a/test-integration/__snapshots__/customers.test.js.snap +++ b/test-integration/__snapshots__/customers.test.js.snap @@ -97,6 +97,7 @@ consumers: credentials: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -251,6 +252,7 @@ consumers: credentials: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -355,6 +357,7 @@ consumers: key: very-secret-key plugins: [] upstreams: [] +certificates: [] " `; @@ -516,6 +519,7 @@ consumers: credentials: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -699,6 +703,7 @@ consumers: username: my-user plugins: [] upstreams: [] +certificates: [] " `; @@ -755,6 +760,7 @@ consumers: credentials: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -844,6 +850,7 @@ exports[`Integration consumers should remove the consumer 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -950,5 +957,6 @@ consumers: credentials: [] plugins: [] upstreams: [] +certificates: [] " `; diff --git a/test-integration/__snapshots__/plugin-per-consumer.test.js.snap b/test-integration/__snapshots__/plugin-per-consumer.test.js.snap index 8f9f272..9f4362f 100644 --- a/test-integration/__snapshots__/plugin-per-consumer.test.js.snap +++ b/test-integration/__snapshots__/plugin-per-consumer.test.js.snap @@ -201,6 +201,7 @@ consumers: credentials: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -332,6 +333,7 @@ plugins: limit_by: consumer fault_tolerant: true upstreams: [] +certificates: [] " `; @@ -577,6 +579,7 @@ plugins: limit_by: consumer fault_tolerant: true upstreams: [] +certificates: [] " `; @@ -901,6 +904,7 @@ plugins: limit_by: consumer fault_tolerant: true upstreams: [] +certificates: [] " `; @@ -1248,5 +1252,6 @@ plugins: limit_by: consumer fault_tolerant: true upstreams: [] +certificates: [] " `; diff --git a/test-integration/__snapshots__/plugin.test.js.snap b/test-integration/__snapshots__/plugin.test.js.snap index fcef7f3..90893e5 100644 --- a/test-integration/__snapshots__/plugin.test.js.snap +++ b/test-integration/__snapshots__/plugin.test.js.snap @@ -79,6 +79,7 @@ plugins: max_age: 7000 preflight_continue: false upstreams: [] +certificates: [] " `; @@ -182,6 +183,7 @@ plugins: max_age: 7000 preflight_continue: false upstreams: [] +certificates: [] " `; @@ -293,6 +295,7 @@ exports[`Integration global plugin should remove the global plugin 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -437,5 +440,6 @@ plugins: max_age: 7000 preflight_continue: false upstreams: [] +certificates: [] " `; diff --git a/test-integration/__snapshots__/upstream.test.js.snap b/test-integration/__snapshots__/upstream.test.js.snap index 765a87f..487a205 100644 --- a/test-integration/__snapshots__/upstream.test.js.snap +++ b/test-integration/__snapshots__/upstream.test.js.snap @@ -177,6 +177,7 @@ upstreams: weight: 50 attributes: slots: 10 +certificates: [] " `; @@ -429,6 +430,7 @@ upstreams: targets: [] attributes: slots: 10 +certificates: [] " `; @@ -684,6 +686,7 @@ upstreams: weight: 100 attributes: slots: 10 +certificates: [] " `; @@ -813,6 +816,7 @@ upstreams: targets: [] attributes: slots: 10 +certificates: [] " `; @@ -960,6 +964,7 @@ upstreams: targets: [] attributes: slots: 10 +certificates: [] " `; @@ -991,6 +996,7 @@ exports[`Upstream should remove the upstream 2`] = ` consumers: [] plugins: [] upstreams: [] +certificates: [] " `; @@ -1236,5 +1242,6 @@ upstreams: targets: [] attributes: slots: 20 +certificates: [] " `; diff --git a/test-integration/config/certificates.example.yml b/test-integration/config/certificates.example.yml new file mode 100644 index 0000000..0674f64 --- /dev/null +++ b/test-integration/config/certificates.example.yml @@ -0,0 +1,55 @@ +certificates: + - ensure: present + cert: '-----BEGIN CERTIFICATE----- + MIIDMjCCAhqgAwIBAgIJAPgRdnOdnX/SMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV + BAMTD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMTkxODUxMDlaFw0yNzExMTcxODUx + MDlaMBoxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAKOQaTkGNgFf9S9kBHUoqe+ax4dyobNpJzbTCyKz9ujB + 8onbV3e8HO5TEQVpIwob3bQ59ZmNkhZxI6jp4ykmXN8gtPOXvWGiSILBcY4p6ttC + RyyVJHSGCKDS5+oUsQA2+ql0ce+ZYl7ePD2kFgzodKCspQaKUe4jvdcEDwsHLmAH + gnFf9oFCCk2McKVH4Vt/YSD6NriTpV0KBCOG260E3vtYWto+djK1AswJCbiTFfnA + a1Vojmu9uX66jfQ/ivZrBFZKHqGtxpBaBa9HV+LaEqehjy2LwQX4fVT4uawDnEM5 + zyy+rR+b0h9lTntI7J7pbAm3zywBzaMtQp0boW20C0UCAwEAAaN7MHkwHQYDVR0O + BBYEFJ8KvTYTyM64g0ISOl/HmbM9Y7o/MEoGA1UdIwRDMEGAFJ8KvTYTyM64g0IS + Ol/HmbM9Y7o/oR6kHDAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb22CCQD4EXZz + nZ1/0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCO9jaWppfOI4Qn + R5/NHp1TYxsWei7Xjr0X7wLVgRZGqzhzPKG4eZR7zfXQfg+ufBx1M3/H5DCTv0cm + CgIjatSRxypV9xOzbakAgcSKw/iqjeDZYN/09iVTICONW507X35ONmw6No3tbVLV + tnuGhtcVOyYBtRUpFc9lCWPYpFVMRMMKXnbdXahlt3IPMPx2QY7nWjAo/oC9oZ2A + RMdp9Sav8eCYf8bLR/A+p5DodwvYgOn5sEUXQeYB/w+VsjmYU01NfMR9NxwsDA5b + gXYz44Dl4jhoi/tz/zIOOGA4DlmuJBpMeYtp9SvJ8qhpx3ul/3C2KFOI+/BzdVSl + L5mKwXjd + -----END CERTIFICATE-----' + + key: '-----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAo5BpOQY2AV/1L2QEdSip75rHh3Khs2knNtMLIrP26MHyidtX + d7wc7lMRBWkjChvdtDn1mY2SFnEjqOnjKSZc3yC085e9YaJIgsFxjinq20JHLJUk + dIYIoNLn6hSxADb6qXRx75liXt48PaQWDOh0oKylBopR7iO91wQPCwcuYAeCcV/2 + gUIKTYxwpUfhW39hIPo2uJOlXQoEI4bbrQTe+1ha2j52MrUCzAkJuJMV+cBrVWiO + a725frqN9D+K9msEVkoeoa3GkFoFr0dX4toSp6GPLYvBBfh9VPi5rAOcQznPLL6t + H5vSH2VOe0jsnulsCbfPLAHNoy1CnRuhbbQLRQIDAQABAoIBAAjbgCc7Y99NL/zi + AK/LhPBZxGZcWc9aaWo5oYe+kSdnoVe/zgvI3xQ04V4WpHQesDHbVaZ8GSYn+FNk + Xw3SawMWRVZPqEzKOf0CtsCJGpPHEg2jAfdhbsQux6pQdolZcNeOW8Eq4D3c8Qwx + f5QxXmd5EfK5uNgZjWVAbgQd3nAKwd/a6AHjppTp6ikNJFU4WU3oi/2N7czpOKFi + 4tq0Img8VqcKekL4LYUYk8RXi6uk+c5ookB1Q2wh/Fpf9oeLN4kBsxXMt8bEg95D + 2Ks5Ekw4yOWnQ8OwfXMWDk46NKMcR7ZYoqfhCk6sc5v6ZFQerJQUBGi2o1Jq2u7Y + 5TIl+4ECgYEA1ybYXpGQIIElHbV90RKc6McoF+yeost1ZWyv/646vwWr+pmkgA32 + iZnAOvaoAaRJbD5d6gIFdG49lmv36wPvBbzmWBkS9sWujTaEIFHSd9H1R8UxGuud + WqnxrY0cYf6fl4Jrguro6PwAv4gsdCt1HA6d9E85+bHP1lr+R823G2ECgYEAwp44 + QdMCvYpLQkbCiLh/UlF2zqZPOQpm2T4NKHxfuH6HKdYyI+ptyx6oP94r/4u7/sYT + nHjCKR7QLGE7qFmnH9Yb2jCd3zFwNBsCoHFhzj6MYzgoV42tpUJl8jRcq351g7hw + Fw2yZG8mW/4lwOhhuVAaUyCngoAs7Jq004bM/mUCgYA/y/PyrsUG7mR8F7n0Ccnf + OFbKKU6sxRnNdloFvbsLs3nYeECP/BPzn1Sh50vQGM/wudmNLwZBDQNUHDXKSUNR + 9z5yNxUpeVqV4ulwz/JRtz89BdrWubDSFnxkUuhsolzeRzzr+A4SL89k+9L6q3wx + UqBBtlBhmvke/aJS1kwKYQKBgQCyn7N0vu5Z9u9CQl3UTLoXXMvVuZEnAmQJakl7 + akQUupTmEkFs84KYFmhITmtFngQLP9PKHo/eW/incwrlZnvc3ZAsv8h2jRK10ECl + 78rcGE6T1nw4d8Hz1zBokCSqBmRnZEYE8r5ULiwf7PDL0L2470tqFqOIRIp3Ezt6 + ldPafQKBgQCS2FyQjk6ccJDYQSaERZeVZ7aw/WYU6CMt64WqIcA2sZsHACPg1JuH + rvANyaCjA5QV2cxhZgw9YmwUkP5I6XftplGB81CjmTguGjJ/k5SS8sA2DCHZUna6 + vxTZvHMdrkoTodEYmy67Kno3NZotwhRUIdgdQhDN+aG+wjOCxKMTRQ== + -----END RSA PRIVATE KEY-----' + snis: + - ensure: present + name: example.com + - ensure: present + name: www.example.com diff --git a/test-integration/util.js b/test-integration/util.js index a047843..23a5779 100644 --- a/test-integration/util.js +++ b/test-integration/util.js @@ -86,7 +86,8 @@ const cleanupKong = async () => { apis: results.apis.map(api => ({ ...api, ensure: 'removed' })), consumers: results.consumers.map(consumer => ({ ...consumer, ensure: 'removed' })), plugins: results.plugins.map(plugin => ({ ...plugin, ensure: 'removed' })), - upstreams: results.upstreams.map(upstream => ({ ...upstream, ensure: 'removed' })) + upstreams: results.upstreams.map(upstream => ({ ...upstream, ensure: 'removed' })), + certificates: results.certificates.map(certificate => ({ ...certificate, ensure: 'removed' })), }, testAdminApi); };