From 012d95b1157820de8d081426a1b17b0844335442 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sara=20Ryfczy=C5=84ska?=
Date: Thu, 5 May 2022 12:57:24 +0200
Subject: [PATCH 001/175] Update README.md
---
README.md | 52 +++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index 6a5c713..34d3ad6 100644
--- a/README.md
+++ b/README.md
@@ -22,11 +22,17 @@ Building process generates an docker image that can be loaded at target machine.
1. Download the source code
2. Vendor dependencies
- `$ go mod vendor`
+ ```
+ $ go mod vendor
+ ```
4. Create an image
- `$ make docker_build_img`
+ ```
+ $ make docker_build_img
+ ```
6. Save the image
- `$ make save`
+ ```
+ $ make save
+ ```
The image of NCM Issuer will be saved in ./builds/ncm-issuer-images/ directory.
@@ -34,17 +40,27 @@ The image of NCM Issuer will be saved in ./builds/ncm-issuer-images/ directory.
NCM Issuer uses Helm chart in installation process. You can read more about Helm [here](https://helm.sh/).
1. Load an image with NCM Issuer
- ```$ docker load -i IMAGE_NAME```
+ ```
+ $ docker load -i IMAGE_NAME
+ ```
2. Create a namespace for NCM Issuer resources
- ```$ kubectl create namespace ncm-issuer```
+ ```
+ $ kubectl create namespace ncm-issuer
+ ```
3. Install package using Helm
- ```$ helm install -n ncm-issuer ncm-issuer /helm/.```
+ ```
+ $ helm install -n ncm-issuer ncm-issuer /helm/.
+ ```
To check if the package has been installed properly type:
-```$ helm list -A | grep -i ncm-issuer```
+```
+$ helm list -A | grep -i ncm-issuer
+```
Output of this command should look like this:
-```ncm-issuer ncm-issuer 1 2022-04-12 17:36:12.120909878 +0200 CEST deployed ncm-issuer-1.0.0 1.0.1```
+```
+ncm-issuer ncm-issuer 1 2022-04-12 17:36:12.120909878 +0200 CEST deployed ncm-issuer-1.0.0 1.0.1
+```
Great! Everything is working right now!
@@ -52,17 +68,25 @@ Great! Everything is working right now!
NCM Issuer requires to create some k8s secrets with credentials to NCM REST API and TLS client configuration.
### NCM REST API credentials
-```$ kubectl create secret generic SECRET_NAME -n NAMESPACE --from-literal=username=USERNAME --from-literal=usrPassword=PASSWORD```
+```
+$ kubectl create secret generic SECRET_NAME -n NAMESPACE --from-literal=username=USERNAME --from-literal=usrPassword=PASSWORD
+```
### TLS without client auth
-```$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem```
+```
+$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem
+```
### TLS with client auth
-```$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem --from-file=key=CLIENT_AUTH_PKEY.pem --from-file=cert=CLIENT_AUTH_CERT.pem ```
+```
+$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem --from-file=key=CLIENT_AUTH_PKEY.pem --from-file=cert=CLIENT_AUTH_CERT.pem
+```
You can check if the secret has been properly created by running this command:
-```$ kubectl -n NAMESPACE describe secrets SECRET_NAME```
+```
+$ kubectl -n NAMESPACE describe secrets SECRET_NAME
+```
## Usage
NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.
@@ -110,7 +134,9 @@ Setting the **reenrollmentOnRenew** field to “true” will force new enrollmen
The **noRoot** field is responsible for controlling the value of ca.crt secret. By default (when this field is not included or set to “false”) Root CA of the certificate is saved to the ca.crt. If noRoot field is set to “true” then issuer of the certificate is saved there.
To create an issuer from created .yaml file type:
-```$ kubectl apply -f issuer.yaml```
+```
+$ kubectl apply -f issuer.yaml
+```
### Enroll a certificate
To enroll a certificate just follow instructions from [cert-manager site](https://cert-manager.io/docs/usage/). The enroll process is exactly the same!
From 825d333da707810ace91c0d0228fb22aad18d18c Mon Sep 17 00:00:00 2001
From: LissaGreense
Date: Mon, 23 May 2022 16:53:04 +0200
Subject: [PATCH 002/175] Changed module name to github package
---
go.mod | 4 +-
go.sum | 121 +-----------------
main.go | 4 +-
.../certificaterequest_controller.go | 12 +-
pkg/controllers/issuer_controller.go | 4 +-
pkg/controllers/issuer_controller_test.go | 2 +-
pkg/pkiutil/util.go | 3 +-
7 files changed, 19 insertions(+), 131 deletions(-)
diff --git a/go.mod b/go.mod
index 87e4cd9..fa7463c 100644
--- a/go.mod
+++ b/go.mod
@@ -1,11 +1,11 @@
-module cm
+module github.com/nokia/ncm-issuer
go 1.16
require (
github.com/go-logr/logr v0.4.0
github.com/jetstack/cert-manager v1.6.3
- github.com/stretchr/testify v1.7.0 // indirect
+ github.com/stretchr/testify v1.7.0
k8s.io/api v0.22.2
k8s.io/apimachinery v0.22.2
k8s.io/client-go v0.22.2
diff --git a/go.sum b/go.sum
index c712c9b..3973d70 100644
--- a/go.sum
+++ b/go.sum
@@ -44,7 +44,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v56.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
@@ -67,9 +66,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxB
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
-github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
-github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
@@ -120,7 +117,6 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
-github.com/Venafi/vcert v0.0.0-20200310111556-eba67a23943f/go.mod h1:9EegQjmRoMqVT/ydgd54mJj5rTd7ym0qMgEfhnPsce0=
github.com/Venafi/vcert/v4 v4.14.3/go.mod h1:IL+6LA8QRWZbmcMzIr/vRhf9Aa6XDM2cQO50caWevjA=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/ahmetb/gen-crd-api-reference-docs v0.2.1-0.20201224172655-df869c1245d4/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8=
@@ -144,12 +140,12 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
-github.com/aws/aws-sdk-go v1.24.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.40.21/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
+github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -193,7 +189,6 @@ github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/cloudflare-go v0.8.5/go.mod h1:8KhU6K+zHUEWOSU++mEQYf7D9UZOcQcibUoSm6vCUz4=
github.com/cloudflare/cloudflare-go v0.20.0/go.mod h1:sPWL/lIC6biLEdyGZwBQ1rGQKF1FhM7N60fuNiFdYTI=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -310,7 +305,6 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpu/goacmedns v0.0.0-20180701200144-565ecf2a84df/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobeGqugQ=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
@@ -334,7 +328,6 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8l
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/digitalocean/godo v1.29.0/go.mod h1:iJnN9rVu6K5LioLxLimlq0uRI+y/eAQjROUmeU/r0hY=
github.com/digitalocean/godo v1.65.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3/go.mod h1:gt38b7cvVKazi5XkHvINNytZXgTEntyhtyM3HQz46Nk=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
@@ -408,7 +401,6 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8=
github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -419,8 +411,6 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
-github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU=
github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM=
github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
@@ -473,11 +463,9 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
-github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
@@ -506,7 +494,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -520,7 +507,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -541,8 +527,6 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
-github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -558,13 +542,11 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -583,16 +565,13 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
@@ -601,17 +580,14 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
-github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@@ -636,7 +612,6 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
-github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
@@ -650,7 +625,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
-github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY=
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@@ -668,21 +642,17 @@ github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
-github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
-github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE=
github.com/hashicorp/vault/api v1.1.1/go.mod h1:29UXcn/1cLOPHQNMWA7bCz2By4PSd0VKPAydKXS5yN0=
-github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/vault/sdk v0.1.14-0.20200519221530-14615acda45f/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
github.com/hashicorp/vault/sdk v0.2.1/go.mod h1:WfUiO1vYzfBkz1TmoE4ZGU7HD0T0Cl/rZwaxjBkgN4U=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
-github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@@ -690,7 +660,6 @@ github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
@@ -699,8 +668,6 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jetstack/cert-manager v0.15.0 h1:r9gz5ISjnyiFQbGeiFAvlJQBCezM1RU1T0x0gnXxzHY=
-github.com/jetstack/cert-manager v0.15.0/go.mod h1:7V2UW1EzgIWVUWi4uVATMIWXqinFOEqpggdvFdNMhlk=
github.com/jetstack/cert-manager v1.6.3 h1:t5Ldacaed2qmDEXsuzkfsa1uE5rpzdDM1vMzheUbbHI=
github.com/jetstack/cert-manager v1.6.3/go.mod h1:1nXjnzzsYcIFvl4eLTkVqpvh9NQogkCq4FaCmgvNDDY=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
@@ -743,6 +710,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
@@ -769,9 +737,7 @@ github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHh
github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
-github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -791,7 +757,6 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/miekg/dns v0.0.0-20170721150254-0f3adef2e220/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.34/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
@@ -820,7 +785,6 @@ github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
-github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -839,7 +803,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
@@ -851,7 +814,6 @@ github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FW
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -859,28 +821,18 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
-github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc=
-github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
-github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
-github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
-github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
-github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -909,7 +861,6 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
-github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible/go.mod h1:xlUlxe/2ItGlQyMTstqeDv9r3U4obH7xYd26TbDQutY=
github.com/pavel-v-chernykh/keystore-go/v4 v4.1.0/go.mod h1:2ejgys4qY+iNVW1IittZhyRYA6MNv8TgM6VHqojbB9g=
github.com/pavel-v-chernykh/keystore-go/v4 v4.2.0/go.mod h1:VxOBKEAW8/EJjil9qwfvVDSljDW0DCoZMD4ezsq9n8U=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
@@ -974,6 +925,7 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -1077,7 +1029,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -1141,7 +1092,6 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
-go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
@@ -1155,7 +1105,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -1197,9 +1146,9 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@@ -1214,7 +1163,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1270,7 +1218,6 @@ golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -1278,14 +1225,10 @@ golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@@ -1311,7 +1254,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1329,7 +1271,6 @@ golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190425045458-9f0b1ff7b46a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1410,7 +1351,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1419,28 +1359,20 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1449,8 +1381,6 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 h1:Vv0JUPWTyeqUq42B2WJ1FeIDjjvGKoA2Ss+Ts0lAVbs=
-golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1518,7 +1448,6 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@@ -1531,7 +1460,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
@@ -1574,7 +1502,6 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -1672,19 +1599,17 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
@@ -1694,10 +1619,8 @@ gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
@@ -1707,7 +1630,6 @@ gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
-gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1717,7 +1639,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
@@ -1739,9 +1660,6 @@ k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU=
-k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU=
-k8s.io/api v0.21.3 h1:cblWILbLO8ar+Fj6xdDGr603HRsf8Wu9E9rngJeprZQ=
-k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
k8s.io/api v0.22.0/go.mod h1:0AoXXqst47OI/L0oGKq9DG61dvGRPXs7X4/B7KyjBCU=
k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY=
k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw=
@@ -1749,8 +1667,6 @@ k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo=
k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs=
-k8s.io/apiextensions-apiserver v0.21.2 h1:+exKMRep4pDrphEafRvpEi79wTnCFMqKf8LBtlA3yrE=
-k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA=
k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c=
k8s.io/apiextensions-apiserver v0.22.2 h1:zK7qI8Ery7j2CaN23UCFaC1hj7dMiI87n01+nKuewd4=
k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA=
@@ -1760,9 +1676,6 @@ k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
-k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM=
-k8s.io/apimachinery v0.21.3 h1:3Ju4nvjCngxxMYby0BimUk+pQHPOQp3eCGChk5kfVII=
-k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI=
k8s.io/apimachinery v0.22.0/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk=
@@ -1772,11 +1685,9 @@ k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
-k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw=
k8s.io/apiserver v0.22.0/go.mod h1:04kaIEzIQrTGJ5syLppQWvpkLJXQtJECHmae+ZGc/nc=
k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400=
k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI=
-k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ=
k8s.io/cli-runtime v0.22.1/go.mod h1:YqwGrlXeEk15Yn3em2xzr435UGwbrCw5x+COQoTYfoo=
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
@@ -1784,9 +1695,6 @@ k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE=
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA=
-k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA=
-k8s.io/client-go v0.21.3 h1:J9nxZTOmvkInRDCzcSNQmPJbDYN/PjlxXT9Mos3HcLg=
-k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU=
k8s.io/client-go v0.22.0/go.mod h1:GUjIuXR5PiEv/RVK5OODUsm6eZk7wtSWZSaSJbpFdGg=
k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk=
k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc=
@@ -1795,7 +1703,6 @@ k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRV
k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/code-generator v0.21.0/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
-k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U=
k8s.io/code-generator v0.22.0/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
@@ -1804,8 +1711,6 @@ k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeY
k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0=
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
-k8s.io/component-base v0.21.2 h1:EsnmFFoJ86cEywC0DoIkAUiEV6fjgauNugiw1lmIjs4=
-k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc=
k8s.io/component-base v0.22.0/go.mod h1:SXj6Z+V6P6GsBhHZVbWCw9hFjUdUYnJerlhhPnYCBCg=
k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo=
k8s.io/component-base v0.22.2 h1:vNIvE0AIrLhjX8drH0BgCNJcR4QZxMXcJzBsDplDx9M=
@@ -1829,33 +1734,25 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
-k8s.io/kube-aggregator v0.18.0/go.mod h1:ateewQ5QbjMZF/dihEFXwaEwoA4v/mayRvzfmvb6eqI=
k8s.io/kube-aggregator v0.22.0 h1:he3plI8vlaPJxR9vsy/lL5ga1V8CoA8M8x1Bn8eTCeM=
k8s.io/kube-aggregator v0.22.0/go.mod h1:zHTepg0Q4tKzru7Pwg1QYHWrU/wrvIXM8hUdDAH66qg=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
-k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0=
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d h1:lUK8GPtuJy8ClWZhuvKoaLdKGPLq9H1PxWp7VPBZBkU=
k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
-k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU=
k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
-k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4=
k8s.io/metrics v0.22.1/go.mod h1:i/ZNap89UkV1gLa26dn7fhKAdheJaKy+moOqJbiif7E=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210802155522-efc7438f0176 h1:Mx0aa+SUAcNRQbs5jUzV8lkDlGFU8laZsY9jrcVX5SY=
-k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
oras.land/oras-go v0.4.0/go.mod h1:VJcU+VE4rkclUbum5C0O7deEZbBYnsnpbGSACwTjOcg=
@@ -1866,19 +1763,13 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/controller-runtime v0.5.1-0.20200416234307-5377effd4043/go.mod h1:j4echH3Y/UPHRpXS65rxGXujda8iWOheMQvDh1uNgaY=
sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
-sigs.k8s.io/controller-runtime v0.9.2 h1:MnCAsopQno6+hI9SgJHKddzXpmv2wtouZz6931Eax+Q=
-sigs.k8s.io/controller-runtime v0.9.2/go.mod h1:TxzMCHyEUpaeuOiZx/bIdc2T81vfs/aKdvJt9wuu0zk=
sigs.k8s.io/controller-runtime v0.10.1 h1:+eLHgY/VrJWnfg6iXUqhCUqNXgPH1NZeP9drNAAgWlg=
sigs.k8s.io/controller-runtime v0.10.1/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY=
-sigs.k8s.io/controller-tools v0.2.9-0.20200414181213-645d44dca7c0/go.mod h1:YKE/iHvcKITCljdnlqHYe+kAt7ZldvtAwUzQff0k1T0=
sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUyp0jmnAM/I=
sigs.k8s.io/controller-tools v0.7.0/go.mod h1:bpBAo0VcSDDLuWt47evLhMLPxRPxMDInTEH/YbdeMK0=
sigs.k8s.io/gateway-api v0.3.0/go.mod h1:Wb8bx7QhGVZxOSEU3i9vw/JqTB5Nlai9MLMYVZeDmRQ=
-sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs=
sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go=
@@ -1890,10 +1781,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
-sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ=
software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78/go.mod h1:B7Wf0Ya4DHF9Yw+qfZuJijQYkWicqDa+79Ytmmq3Kjg=
-vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
diff --git a/main.go b/main.go
index 0a175a0..8aa6a98 100644
--- a/main.go
+++ b/main.go
@@ -31,8 +31,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
- certmanagerv1 "cm/api/v1"
- "cm/pkg/controllers"
+ certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/controllers"
//+kubebuilder:scaffold:imports
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
)
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 924e043..e3181b1 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -17,14 +17,14 @@ limitations under the License.
package controllers
import (
- certmanagerv1 "cm/api/v1"
- "cm/pkg/pkiutil"
"context"
"fmt"
"github.com/go-logr/logr"
apiutil "github.com/jetstack/cert-manager/pkg/api/util"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
+ certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/pkiutil"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -152,7 +152,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, SetStatusErrMsg)
}
- return ctrl.Result{}, nil
+ return ctrl.Result{}, err
}
// once CRD resource is ready, the config data should be ready
@@ -163,7 +163,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "Fail to set certificateRequest status")
}
- return ctrl.Result{}, nil
+ return ctrl.Result{}, err
}
if apiutil.CertificateRequestIsDenied(&cr) {
@@ -173,7 +173,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Error(err, SetStatusErrMsg)
}
- return ctrl.Result{}, nil
+ return ctrl.Result{}, err
}
if !apiutil.CertificateRequestIsApproved(&cr) {
@@ -540,7 +540,7 @@ func (r *CertificateRequestReconciler) waitCheckFindca(ctx context.Context, req
} else {
log.Info(inFuncStr, "time", nowTime.Time, "OK", "find the NCM external server ")
- // udpate new Certifier status change, which trigger new round of reconcile
+ // update new Certifier status change, which trigger new round of reconcile
// status is updated from CertificateRequestReasonPending to CertificateRequestReasonFailed
CertificateRequestPendingList[CrPendingKey] = nil
_ = r.setStatus(ctx, &newcr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now the external NCM server is OK to find.")
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index 40c3c8e..35c8051 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -17,12 +17,12 @@ limitations under the License.
package controllers
import (
- certmanagerv1 "cm/api/v1"
- "cm/pkg/pkiutil"
"context"
"errors"
"fmt"
"github.com/go-logr/logr"
+ certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/pkiutil"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 75693c5..410f07c 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -18,7 +18,7 @@ import (
"strings"
"testing"
- nokiaAPI "cm/api/v1"
+ nokiaAPI "github.com/nokia/ncm-issuer/api/v1"
)
const (
diff --git a/pkg/pkiutil/util.go b/pkg/pkiutil/util.go
index 38e15e9..a6ad0a6 100644
--- a/pkg/pkiutil/util.go
+++ b/pkg/pkiutil/util.go
@@ -1,8 +1,8 @@
package pkiutil
import (
- cmv1 "cm/api/v1"
"fmt"
+ cmv1 "github.com/nokia/ncm-issuer/api/v1"
"k8s.io/api/core/v1"
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
@@ -74,4 +74,3 @@ func MyCRDHasCondition(status cmv1.IssuerStatus, c cmv1.IssuerCondition) bool {
}
return false
}
-
From ec7edb1f17b536eb0297c7b0473442aff440ef21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sara=20Ryfczy=C5=84ska?=
Date: Mon, 23 May 2022 11:46:35 +0200
Subject: [PATCH 003/175] unittests github action added
---
.github/workflows/unit_test.yml | 24 ++++++++++++++++++++++++
README.md | 6 ++++++
2 files changed, 30 insertions(+)
create mode 100644 .github/workflows/unit_test.yml
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
new file mode 100644
index 0000000..dbc1ca9
--- /dev/null
+++ b/.github/workflows/unit_test.yml
@@ -0,0 +1,24 @@
+name: Go
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: 1.16
+
+ - name: Build
+ run: go build -v ./...
+
+ - name: Test
+ run: go test -v ./...
diff --git a/README.md b/README.md
index 34d3ad6..9baf7cf 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
+
+
+
+
+
+
# NCM Issuer
NCM Issuer allows to integrate cert-manager plugin with [Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/).
From e654d451ec9c49baa80b522817b60942c0f0919c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sara=20Ryfczy=C5=84ska?=
Date: Mon, 23 May 2022 12:00:31 +0200
Subject: [PATCH 004/175] Fixed status badge (#2)
* Update unit_test.yml
* Update README.md
---
.github/workflows/unit_test.yml | 2 +-
README.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
index dbc1ca9..89ab70c 100644
--- a/.github/workflows/unit_test.yml
+++ b/.github/workflows/unit_test.yml
@@ -1,4 +1,4 @@
-name: Go
+name: Tests
on:
push:
diff --git a/README.md b/README.md
index 9baf7cf..43e012b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
From 0aa2e8e68eeb72914de46cc87abf283487ba0125 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sara=20Ryfczy=C5=84ska?=
Date: Mon, 23 May 2022 17:28:47 +0200
Subject: [PATCH 005/175] Update README
Added go report and terminal video
---
README.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/README.md b/README.md
index 43e012b..3c75bf5 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,14 @@
+
+
+
+
+
+
+
+
# NCM Issuer
From 81142600ff90970d2dbd807886d4eeb465606782 Mon Sep 17 00:00:00 2001
From: misiektoja <55950820+misiektoja@users.noreply.github.com>
Date: Mon, 23 May 2022 17:21:36 +0200
Subject: [PATCH 006/175] Update of Helm values.yaml
To include image loaded to public repo + change of default replica to 1 only.
---
helm/values.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/helm/values.yaml b/helm/values.yaml
index 696b06b..4627993 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -1,5 +1,5 @@
-registry: k8s-registry:5000
-replicaCount: 2
+registry: docker.io/misiektoja
+replicaCount: 1
priorityClassName: ""
imagePullSecrets: []
imagePullPolicy: Always
From f5e61065b0c7441674ff683b4822ed861bd90569 Mon Sep 17 00:00:00 2001
From: misiektoja <55950820+misiektoja@users.noreply.github.com>
Date: Mon, 23 May 2022 17:33:33 +0200
Subject: [PATCH 007/175] Update of README.md
Just some small updates here and there ...
---
README.md | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index 3c75bf5..6edf07a 100644
--- a/README.md
+++ b/README.md
@@ -2,20 +2,12 @@
-
-
-
-
-
-
-
-
# NCM Issuer
-NCM Issuer allows to integrate cert-manager plugin with [Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/).
+NCM Issuer cert-manager plugin allows to integrate with [Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/) PKI system.
-Cert-manager is a native Kubernetes certificate management controller which allows CNFs to get their certificates from a variety of CAs (Certification Authorities). It ensures certificates are valid and up to date, it also attempts to renew certificates at a configured time before expiration.
+Cert-manager is a native Kubernetes certificate management controller which allows applications to get their certificates from a variety of CAs (Certification Authorities). It ensures certificates are valid and up to date, it also attempts to renew certificates at a configured time before expiration.
## Requirements
### To build:
@@ -29,10 +21,10 @@ Cert-manager is a native Kubernetes certificate management controller which allo
- **[NCM 21 release](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/)** (or higher)
- **[kubernetes](https://kubernetes.io/)** 1.18-1.21
- **[cert-manager](https://cert-manager.io/docs/installation/)** >= 1.0.0
-- **[Helm](https://helm.sh/docs/intro/install/)**
+- **[Helm](https://helm.sh/docs/intro/install/)** v3
## Build from source
-Building process generates an docker image that can be loaded at target machine.
+Building process generates a docker image that can be loaded at target machine.
1. Download the source code
2. Vendor dependencies
@@ -103,7 +95,7 @@ $ kubectl -n NAMESPACE describe secrets SECRET_NAME
```
## Usage
-NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.
+NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities, but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.
### Create an issuer
@@ -131,7 +123,7 @@ For **name** variable use some descriptive name of your choice for your issuing
For **namespace** use the one you have created before.
-For **secretName** use the secret name with rest credentials.
+For **secretName** use the secret name with NCM REST API endpoint credentials.
For **tlsSecretName** use the secret name with TLS certificate.
@@ -143,7 +135,7 @@ If the **profileId** field is defined, then the profile ID will be set in enroll
Setting the **useProfileIDForRenew** field to “true” is necessary to include the defined profileID value in the */update* request during the renewal process. Otherwise, certificate update operations won’t include it.
-Setting the **reenrollmentOnRenew** field to “true” will force new enrollment of the certificate when renewal process is executed. In this case NCM Issuer uses the NCM */requests* REST API endpoint to get a renewed certificate. By default (when this field is not included or set to “false”) the */update* REST API endpoint is used to renew the certificate (it is the default recommended setting).
+Setting the **reenrollmentOnRenew** field to “true” will force new enrollment of the certificate when renewal process is executed. In this case NCM Issuer uses the NCM */requests* REST API endpoint to get a renewed certificate. By default (when this field is not included or set to “false”) the */update* NCM REST API endpoint is used to renew the certificate (it is the default recommended setting).
The **noRoot** field is responsible for controlling the value of ca.crt secret. By default (when this field is not included or set to “false”) Root CA of the certificate is saved to the ca.crt. If noRoot field is set to “true” then issuer of the certificate is saved there.
From 7c09ed790cafcdc8732954cf7323fd9985a3c300 Mon Sep 17 00:00:00 2001
From: misiektoja <55950820+misiektoja@users.noreply.github.com>
Date: Mon, 23 May 2022 17:59:46 +0200
Subject: [PATCH 008/175] Update README.md
---
README.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/README.md b/README.md
index 6edf07a..2488606 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,14 @@
+
+
+
+
+
+
+
+
# NCM Issuer
From 497163bff5f63e4f463299a1674ccfceeb878c63 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 26 May 2022 10:43:20 +0200
Subject: [PATCH 009/175] markdown linting and linkchecks
---
.github/workflows/markdown_check.yml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 .github/workflows/markdown_check.yml
diff --git a/.github/workflows/markdown_check.yml b/.github/workflows/markdown_check.yml
new file mode 100644
index 0000000..505ffc5
--- /dev/null
+++ b/.github/workflows/markdown_check.yml
@@ -0,0 +1,22 @@
+# workflow to run the acme2certifier unittest suite
+
+name: Markdown Link check
+
+on:
+ push:
+ pull_request:
+ branches: [ devel ]
+ schedule:
+ - cron: '0 2 * * 6'
+
+jobs:
+ markdown-link-check:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - uses: gaurav-nelson/github-action-markdown-link-check@v1
+
+ - name: Lint changelog file root
+ uses: avto-dev/markdown-lint@v1
+ with:
+ args: '*.md'
From 440b6b25dfe462cf805c97350a9e118008776cfb Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 26 May 2022 16:25:51 +0200
Subject: [PATCH 010/175] Linting of README.md
---
README.md | 92 ++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 60 insertions(+), 32 deletions(-)
diff --git a/README.md b/README.md
index 2488606..8520c0f 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,11 @@
+
+# NCM Issuer
+
-
+
@@ -12,119 +15,142 @@
-# NCM Issuer
NCM Issuer cert-manager plugin allows to integrate with [Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/) PKI system.
Cert-manager is a native Kubernetes certificate management controller which allows applications to get their certificates from a variety of CAs (Certification Authorities). It ensures certificates are valid and up to date, it also attempts to renew certificates at a configured time before expiration.
## Requirements
-### To build:
+
+### To build
- **[Golang](https://go.dev/doc/install)** 1.16.15
- **[Make](https://www.gnu.org/software/make/)**
- **[Docker](https://docs.docker.com/engine/install/)** >= 20.10.0
+
> **IMPORTANT:** if you use CentOS/RedHat/Fedora do not use the default one, but install docker-ce
-### To use:
+### To use
+
- **[NCM 21 release](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/)** (or higher)
- **[kubernetes](https://kubernetes.io/)** 1.18-1.21
- **[cert-manager](https://cert-manager.io/docs/installation/)** >= 1.0.0
- **[Helm](https://helm.sh/docs/intro/install/)** v3
## Build from source
+
Building process generates a docker image that can be loaded at target machine.
1. Download the source code
2. Vendor dependencies
- ```
+
+ ```bash
$ go mod vendor
```
-4. Create an image
- ```
+
+3. Create an image
+
+ ```bash
$ make docker_build_img
```
-6. Save the image
- ```
+
+4. Save the image
+
+ ```bash
$ make save
```
The image of NCM Issuer will be saved in ./builds/ncm-issuer-images/ directory.
## Installation
+
NCM Issuer uses Helm chart in installation process. You can read more about Helm [here](https://helm.sh/).
1. Load an image with NCM Issuer
- ```
+
+ ```bash
$ docker load -i IMAGE_NAME
```
+
2. Create a namespace for NCM Issuer resources
- ```
+
+ ```bash
$ kubectl create namespace ncm-issuer
```
+
3. Install package using Helm
- ```
+
+ ```bash
$ helm install -n ncm-issuer ncm-issuer /helm/.
```
To check if the package has been installed properly type:
-```
+
+```bash
$ helm list -A | grep -i ncm-issuer
```
Output of this command should look like this:
-```
+
+```bash
ncm-issuer ncm-issuer 1 2022-04-12 17:36:12.120909878 +0200 CEST deployed ncm-issuer-1.0.0 1.0.1
```
Great! Everything is working right now!
## Configuration
+
NCM Issuer requires to create some k8s secrets with credentials to NCM REST API and TLS client configuration.
### NCM REST API credentials
-```
+
+```bash
$ kubectl create secret generic SECRET_NAME -n NAMESPACE --from-literal=username=USERNAME --from-literal=usrPassword=PASSWORD
```
### TLS without client auth
-```
+
+```bash
$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem
```
### TLS with client auth
-```
+
+```bash
$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem --from-file=key=CLIENT_AUTH_PKEY.pem --from-file=cert=CLIENT_AUTH_CERT.pem
```
-
You can check if the secret has been properly created by running this command:
-```
+
+```bash
$ kubectl -n NAMESPACE describe secrets SECRET_NAME
```
## Usage
+
NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities, but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.
### Create an issuer
Issuer .yaml file with all available options:
-```
+
+```yaml
apiVersion: certmanager.ncm.nokia.com/v1
kind: Issuer (or ClusterIssuer)
metadata:
- name: ISSUER_NAME
- namespace: NAMESPACE_NAME
+ name: ISSUER_NAME
+ namespace: NAMESPACE_NAME
spec:
- secretName: SECRET_NAME_WITH_REST_CREDS
- tlsSecretName: SECRET_NAME_WITH_TLS_CERT
- CASNAME: CERTIFICATE_NAME_FROM_NCM
- CASHREF: HREF_FROM_NCM
- ncmSERVER: ADDR_TO_NCM
- profileId: PROFILE_ID
- reenrollmentOnRenew: false (or true)
- useProfileIDForRenew: false (or true)
- noRoot: false (or true)
+ secretName: SECRET_NAME_WITH_REST_CREDS
+ tlsSecretName: SECRET_NAME_WITH_TLS_CERT
+ CASNAME: CERTIFICATE_NAME_FROM_NCM
+ CASHREF: HREF_FROM_NCM
+ ncmSERVER: ADDR_TO_NCM
+ profileId: PROFILE_ID
+ reenrollmentOnRenew: false (or true)
+ useProfileIDForRenew: false (or true)
+ noRoot: false (or true)
```
+
For **kind** variable use either Issuer for namespaced one or ClusterIssuer for cluster level issuer.
For **name** variable use some descriptive name of your choice for your issuing CA. This name will be used by your CNFs / applications.
@@ -148,9 +174,11 @@ Setting the **reenrollmentOnRenew** field to “true” will force new enrollmen
The **noRoot** field is responsible for controlling the value of ca.crt secret. By default (when this field is not included or set to “false”) Root CA of the certificate is saved to the ca.crt. If noRoot field is set to “true” then issuer of the certificate is saved there.
To create an issuer from created .yaml file type:
-```
+
+```bash
$ kubectl apply -f issuer.yaml
```
### Enroll a certificate
+
To enroll a certificate just follow instructions from [cert-manager site](https://cert-manager.io/docs/usage/). The enroll process is exactly the same!
From 5c7e78834b0e6a914860f8237da95454823b7701 Mon Sep 17 00:00:00 2001
From: Michal Szymanski <55950820+misiektoja@users.noreply.github.com>
Date: Thu, 26 May 2022 17:22:26 +0200
Subject: [PATCH 011/175] Copy & paste error of grindsa
---
.github/workflows/markdown_check.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/markdown_check.yml b/.github/workflows/markdown_check.yml
index 505ffc5..d623a32 100644
--- a/.github/workflows/markdown_check.yml
+++ b/.github/workflows/markdown_check.yml
@@ -1,4 +1,4 @@
-# workflow to run the acme2certifier unittest suite
+# workflow to run the ncm-issuer unittest suite
name: Markdown Link check
From 01bc42830e62da34f8b9ad6fb99575c7cfe722db Mon Sep 17 00:00:00 2001
From: Michal Szymanski <55950820+misiektoja@users.noreply.github.com>
Date: Mon, 30 May 2022 20:28:43 +0200
Subject: [PATCH 012/175] Updates in the README.md
To include some things that came up after late-evening breaking of stuff by Grindsa ;-)
---
README.md | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 8520c0f..eab21de 100644
--- a/README.md
+++ b/README.md
@@ -80,13 +80,13 @@ NCM Issuer uses Helm chart in installation process. You can read more about Helm
3. Install package using Helm
```bash
- $ helm install -n ncm-issuer ncm-issuer /helm/.
+ $ helm install -n ncm-issuer ncm-issuer ./helm/.
```
To check if the package has been installed properly type:
```bash
-$ helm list -A | grep -i ncm-issuer
+$ helm list -n ncm-issuer
```
Output of this command should look like this:
@@ -182,3 +182,34 @@ $ kubectl apply -f issuer.yaml
### Enroll a certificate
To enroll a certificate just follow instructions from [cert-manager site](https://cert-manager.io/docs/usage/). The enroll process is exactly the same!
+
+Sample .yaml file to enroll NCM issued certificate:
+
+```yaml
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+ name: NCM_CERTIFICATE_NAME
+ namespace: APPLICATION_NAMESPACE_NAME
+spec:
+ commonName: CERTIFICATE_COMMON_NAME
+ dnsNames:
+ - CERTIFICATE_SAN_DNS
+ issuerRef:
+ group: certmanager.ncm.nokia.com
+ kind: Issuer
+ name: ISSUER_NAME
+ secretName: SECRET_NAME_FOR_NCM_CERTIFICATE
+```
+
+```bash
+$ kubectl apply -f certificate.yaml
+```
+
+### Troubleshooting
+
+In case of issues despite checking status of created resources, you could also check ncm-issuer pod logs:
+
+```bash
+$ kubectl -n ncm-issuer logs -f `kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'`
+```
From 8153348f69b653fabb03ed97d04f604b90b3ec36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sara=20Ryfczy=C5=84ska?=
Date: Wed, 1 Jun 2022 13:52:07 +0200
Subject: [PATCH 013/175] Update Dockerfile
Fixed bug "cannot find package "."" that occurred after changing the module name
---
Dockerfile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 1cd3377..6e6d4d1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,8 +12,8 @@ COPY vendor/ vendor/
# Copy the go source
COPY main.go main.go
COPY api/ api/
-COPY pkg/pkiutil pkiutil/
-COPY pkg/controllers controllers/
+COPY pkg/pkiutil pkg/pkiutil/
+COPY pkg/controllers pkg/controllers/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go
From d4cef60547a866af07a9f4aef91cf489c3af295f Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 2 Jun 2022 00:38:13 +0300
Subject: [PATCH 014/175] build workflow
---
.github/workflows/build_test.yml | 50 ++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 .github/workflows/build_test.yml
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml
new file mode 100644
index 0000000..25be387
--- /dev/null
+++ b/.github/workflows/build_test.yml
@@ -0,0 +1,50 @@
+name: build ncm-issuer by using different go versions
+
+on:
+ push:
+ pull_request:
+ branches: [ main ]
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '0 2 * * 6'
+
+jobs:
+ build:
+ name: "Build"
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ goversion: ['1.16', '1.16.15', '1.17', '1.17.8']
+ steps:
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+
+ - uses: actions/setup-go@v3
+ with:
+ go-version: ${{ matrix.goversion }}
+ - run: go version
+
+ - name: "modify Dockerfile"
+ run: |
+ sudo sed -i "s/FROM golang:1.16.15/FROM golang:${{ matrix.goversion }}/g" Dockerfile
+ cat Dockerfile
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "[ * ] collecting logs"
+ if: ${{ failure() }}
+ run: |
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp * ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: issuer_build-${{ matrix.goversion }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
From eaeda1b9ffff63101b3372b6a51d9bc8c81fef50 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Mon, 6 Jun 2022 17:06:26 +0200
Subject: [PATCH 015/175] enrollment tests
---
.github/cert-ressource.yml | 20 +++
.github/ncm-issuer.yml | 20 +++
.../certmanager-application-test.yml | 124 ++++++++++++++++++
3 files changed, 164 insertions(+)
create mode 100644 .github/cert-ressource.yml
create mode 100644 .github/ncm-issuer.yml
create mode 100644 .github/workflows/certmanager-application-test.yml
diff --git a/.github/cert-ressource.yml b/.github/cert-ressource.yml
new file mode 100644
index 0000000..5abbb1f
--- /dev/null
+++ b/.github/cert-ressource.yml
@@ -0,0 +1,20 @@
+# apiVersion: v1
+# kind: Namespace
+#metadata:
+# name: ncm-cert
+# ---
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+ name: ncm-cert
+ namespace: ncm-issuer
+ # namespace: ncm-cert
+spec:
+ dnsNames:
+ - foo.bar.local
+ renewBefore: 120h
+ secretName: mysecret-secret
+ issuerRef:
+ group: certmanager.ncm.nokia.com
+ kind: Issuer
+ name: ncm
diff --git a/.github/ncm-issuer.yml b/.github/ncm-issuer.yml
new file mode 100644
index 0000000..11ecede
--- /dev/null
+++ b/.github/ncm-issuer.yml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: ncm-issuer
+---
+apiVersion: certmanager.ncm.nokia.com/v1
+kind: Issuer
+metadata:
+ name: ncm
+ namespace: ncm-issuer
+spec:
+ secretName: ncm-issuer
+ tlsSecretName: ncm-issuer-bundle
+ CASNAME: SubCA
+ # CASHREF: HREF_FROM_NCM
+ ncmSERVER: NCM_SRV
+ # profileId: PROFILE_ID
+ reenrollmentOnRenew: false
+ useProfileIDForRenew: false
+ noRoot: false
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
new file mode 100644
index 0000000..0e116eb
--- /dev/null
+++ b/.github/workflows/certmanager-application-test.yml
@@ -0,0 +1,124 @@
+name: enrollment tests
+
+on:
+ push:
+ pull_request:
+ branches: [ main ]
+
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '0 2 * * 6'
+
+jobs:
+ issuer_test:
+ name: "ncm-issuer test"
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ k8sversion: ['1.21', '1.22', '1.23', '1.24']
+ certmgrversion: ['1.6.1', '1.7', '1.8']
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgrversion }} --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate ressource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-ressource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate ressource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_screts.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgrversion }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
From 8a701d06b02c08c28e44e3f09e59a248013bf793 Mon Sep 17 00:00:00 2001
From: Michal Szymanski <55950820+misiektoja@users.noreply.github.com>
Date: Thu, 9 Jun 2022 14:45:28 +0200
Subject: [PATCH 016/175] Update certmanager-application-test.yml
Small typos corrected.
---
.github/workflows/certmanager-application-test.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 0e116eb..8e0eb5b 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -80,16 +80,16 @@ jobs:
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
- - name: "create certificate ressource"
+ - name: "create certificate resource"
run: |
- sudo microk8s.kubectl apply -f data/cert-ressource.yml
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
with:
time: 10s
- - name: "check certificate ressource"
+ - name: "check certificate resource"
run: |
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
@@ -104,7 +104,7 @@ jobs:
sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
sudo microk8s.kubectl get po -A > data/logs/get_pods.log
sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
- sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_screts.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
From ef6be45484b443eac9aff6c2115b9472ccea6abf Mon Sep 17 00:00:00 2001
From: Michal Szymanski <55950820+misiektoja@users.noreply.github.com>
Date: Thu, 9 Jun 2022 14:46:42 +0200
Subject: [PATCH 017/175] Rename cert-ressource.yml to cert-resource.yml
---
.github/{cert-ressource.yml => cert-resource.yml} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename .github/{cert-ressource.yml => cert-resource.yml} (100%)
diff --git a/.github/cert-ressource.yml b/.github/cert-resource.yml
similarity index 100%
rename from .github/cert-ressource.yml
rename to .github/cert-resource.yml
From c23754d5477f039e6d80bfec0ebc56f8fbf47df5 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 12 Jun 2022 18:14:35 +0200
Subject: [PATCH 018/175] workflow to test key algorithms and length
---
.github/workflows/pkey-tests.yml | 243 +++++++++++++++++++++++++++++++
1 file changed, 243 insertions(+)
create mode 100644 .github/workflows/pkey-tests.yml
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
new file mode 100644
index 0000000..b6109e6
--- /dev/null
+++ b/.github/workflows/pkey-tests.yml
@@ -0,0 +1,243 @@
+name: key algorithm tests
+
+on:
+ push:
+ pull_request:
+ branches: [ main ]
+
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '0 2 * * 6'
+
+jobs:
+ ecdsa_test:
+ name: "ecdsa tests"
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ keysize: [256, 384, 521]
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s/secretName: mysecret-secret/secretName: mysecret-secret\n privateKey:\n algorithm: ECDSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate resource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ openssl x509 -in /tmp/cert.der -text -noout | grep "Public Key Algorithm: id-ecPublicKey"
+ openssl x509 -in /tmp/cert.der -text -noout | grep "NIST CURVE: P-${{ matrix.keysize }}"
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-ecdsa${{ matrix.keysize }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
+
+ rsa_test:
+ name: "rsa tests"
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ keysize: [2048, 4096]
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s/secretName: mysecret-secret/secretName: mysecret-secret\n privateKey:\n algorithm: RSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate resource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ openssl x509 -in /tmp/cert.der -text -noout | grep "Public Key Algorithm: rsaEncryption"
+ openssl x509 -in /tmp/cert.der -text -noout | grep "RSA Public-Key: (${{ matrix.keysize }} bit)"
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-ecdsa${{ matrix.keysize }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
\ No newline at end of file
From 24b54f47165b4ca5c112a6bcb3f19f23e00bed4e Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 16 Jun 2022 07:09:32 +0200
Subject: [PATCH 019/175] enhanced workflow to test clusterissuer
---
.../certmanager-application-test.yml | 129 +++++++++++++++++-
1 file changed, 122 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 8e0eb5b..2b8121a 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -29,14 +29,12 @@ jobs:
go mod vendor
make docker_build_img
make save
-
- name: "install microk8s"
run: |
sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
sudo microk8s status --wait-ready
sudo microk8s enable helm3
sudo microk8s enable dns
-
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
@@ -64,12 +62,10 @@ jobs:
- name: "install plugin"
run: |
sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
-
- name: "create issuer"
run: |
sudo microk8s.kubectl apply -f data/ncm-issuer.yml
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
-
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
with:
@@ -79,11 +75,9 @@ jobs:
run: |
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
-
- name: "create certificate resource"
run: |
sudo microk8s.kubectl apply -f data/cert-resource.yml
-
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
with:
@@ -96,7 +90,6 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
-
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
@@ -115,6 +108,128 @@ jobs:
mkdir -p ${{ github.workspace }}/artifact/upload
sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgrversion }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
+
+ clusterissuer_test:
+ name: "ncm-clusterissuer test"
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ k8sversion: ['1.21', '1.22', '1.23', '1.24']
+ certmgrversion: ['1.6.1', '1.7', '1.8']
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgrversion }} --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s|kind: Issuer|kind: ClusterIssuer|g" data/ncm-issuer.yml
+ sed -i "s|secretName: ncm-issuer|authNameSpace: ncm-issuer-auth\n secretName: ncm-issuer|g" data/ncm-issuer.yml
+ sed -i "s|namespace: ncm-issuer|namespace: ncm-cert|g" data/cert-resource.yml
+ sed -i "s|kind: Issuer|kind: ClusterIssuer|g" data/cert-resource.yml
+ sudo microk8s.kubectl create namespace ncm-cert
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create namespace ncm-issuer-auth
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer-auth --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer-auth --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get clusterissuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get clusterissuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get clusterissuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate resource"
+ run: |
+ cat data/cert-resource.yml
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-cert
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-cert | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Issued"
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer-auth > data/logs/get_secrets_ncm-issuer-auth.log
+ sudo microk8s.kubectl get secrets -n ncm-cert > data/logs/get_secrets_ncm-issuer-cert.log
+ sudo microk8s.kubectl get clusterissuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe clusterissuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-cert > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-cert > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-cert > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
- name: "[ * ] uploading artificates"
uses: actions/upload-artifact@v2
From 0da9522540167bb9329fe2139a00fb95597d839d Mon Sep 17 00:00:00 2001
From: Michal Szymanski <55950820+misiektoja@users.noreply.github.com>
Date: Thu, 16 Jun 2022 14:02:39 +0200
Subject: [PATCH 020/175] Update certmanager-application-test.yml
---
.github/workflows/certmanager-application-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 2b8121a..7fb64b6 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -231,7 +231,7 @@ jobs:
sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
- - name: "[ * ] uploading artificates"
+ - name: "[ * ] uploading artifacts"
uses: actions/upload-artifact@v2
if: ${{ failure() }}
with:
From b68bf752bf57e95a7b3b01cbc94d81321fddf4f8 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Fri, 17 Jun 2022 18:30:26 +0200
Subject: [PATCH 021/175] Worflow to test SubAltName configuration
---
.github/workflows/san-tests.yml | 150 ++++++++++++++++++++++++++++++++
1 file changed, 150 insertions(+)
create mode 100644 .github/workflows/san-tests.yml
diff --git a/.github/workflows/san-tests.yml b/.github/workflows/san-tests.yml
new file mode 100644
index 0000000..73a546e
--- /dev/null
+++ b/.github/workflows/san-tests.yml
@@ -0,0 +1,150 @@
+name: san tests
+
+on:
+ push:
+ pull_request:
+ branches: [ main ]
+
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '0 2 * * 6'
+
+jobs:
+ san_test:
+ name: "san tests"
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "get runner ip"
+ run: |
+ echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV
+ echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV
+ - run: echo "runner IP is ${{ env.RUNNER_IP }}"
+
+ - name: "get runner name"
+ run: |
+ echo RUNNER_NAME=$(hostname) >> $GITHUB_ENV
+ - run: echo "runner NAMME is ${{ env.RUNNER_NAME }}"
+
+ - name: "get unix timestamp"
+ run: |
+ echo RUNNER_UTS=$(date +%s) >> $GITHUB_ENV
+ - run: echo "unix timestamp is ${{ env.RUNNER_UTS }}"
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s|- foo.bar.local|- foo.bar.local\n - ${{ env.RUNNER_NAME }}-${{ env.RUNNER_UTS }}.bar.local|g" data/cert-resource.yml
+ sed -i "s|renewBefore: 120h|ipAddresses:\n - 192.168.1.1\n - ${{ env.RUNNER_IP }}\n - fc00:bad:a55:3468::443\n renewBefore: 120h|g" data/cert-resource.yml
+ sed -i "s|renewBefore: 120h|uris:\n - spiffe://cluster.local/ns/spiffe/sa/example\n renewBefore: 120h|g" data/cert-resource.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate resource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ openssl x509 -in /tmp/cert.der -text -noout
+ openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "DNS:foo.bar.local"
+ openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "DNS:${{ env.RUNNER_NAME }}-${{ env.RUNNER_UTS }}.bar.local"
+ openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "IP Address:192.168.1.1"
+ openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "IP Address:${{ env.RUNNER_IP }}"
+ openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "IP Address:FC00:BAD:A55:3468:0:0:0:443"
+ openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "URI:spiffe://cluster.local/ns/spiffe/sa/example"
+
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-ecdsa${{ matrix.keysize }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
From d0c35b2e35a4c27dab7ef944079d9bedfa18b6d1 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sat, 18 Jun 2022 07:04:52 +0200
Subject: [PATCH 022/175] verify certificates via openssl
---
.github/workflows/certmanager-application-test.yml | 7 +++++++
.github/workflows/pkey-tests.yml | 4 ++++
.github/workflows/san-tests.yml | 3 ++-
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 7fb64b6..817dd00 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -90,6 +90,10 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
@@ -209,6 +213,9 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
- name: "[ * ] collecting test logs"
continue-on-error: true
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
index b6109e6..ad32f9e 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/pkey-tests.yml
@@ -97,8 +97,10 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
openssl x509 -in /tmp/cert.der -text -noout | grep "Public Key Algorithm: id-ecPublicKey"
openssl x509 -in /tmp/cert.der -text -noout | grep "NIST CURVE: P-${{ matrix.keysize }}"
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
- name: "[ * ] collecting test logs"
continue-on-error: true
@@ -213,8 +215,10 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
openssl x509 -in /tmp/cert.der -text -noout | grep "Public Key Algorithm: rsaEncryption"
openssl x509 -in /tmp/cert.der -text -noout | grep "RSA Public-Key: (${{ matrix.keysize }} bit)"
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
- name: "[ * ] collecting test logs"
continue-on-error: true
diff --git a/.github/workflows/san-tests.yml b/.github/workflows/san-tests.yml
index 73a546e..66ac543 100644
--- a/.github/workflows/san-tests.yml
+++ b/.github/workflows/san-tests.yml
@@ -114,6 +114,7 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
openssl x509 -in /tmp/cert.der -text -noout
openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "DNS:foo.bar.local"
openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "DNS:${{ env.RUNNER_NAME }}-${{ env.RUNNER_UTS }}.bar.local"
@@ -121,7 +122,7 @@ jobs:
openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "IP Address:${{ env.RUNNER_IP }}"
openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "IP Address:FC00:BAD:A55:3468:0:0:0:443"
openssl x509 -in /tmp/cert.der -noout -ext subjectAltName | grep -i "URI:spiffe://cluster.local/ns/spiffe/sa/example"
-
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
- name: "[ * ] collecting test logs"
continue-on-error: true
From dd158187aefb69c24294dccb3f4e7a99f20e9a8d Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sat, 18 Jun 2022 09:07:50 +0200
Subject: [PATCH 023/175] Worflow to test CAHREF parameter
---
.github/workflows/cahref-test.yml | 241 ++++++++++++++++++++++++++++++
1 file changed, 241 insertions(+)
create mode 100644 .github/workflows/cahref-test.yml
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
new file mode 100644
index 0000000..bc072fd
--- /dev/null
+++ b/.github/workflows/cahref-test.yml
@@ -0,0 +1,241 @@
+name: key algorithm tests
+
+on:
+ push:
+ pull_request:
+ branches: [ main ]
+
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '0 2 * * 6'
+
+jobs:
+ cahref_test:
+ name: "CAHREF Tests"
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+ NCM_CAHREF: ${{ secrets.NCM_CAHREF }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate resource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-cahref.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
+
+ caname_test:
+ name: "CANAME Test"
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+ env:
+ NCM_HOST: ${{ secrets.NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
+ - name: "create certificate resource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Certificate:" | awk '{print $2}' | base64 -d > /tmp/cert.der
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
+ openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-caname.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
From d31eea9b3da82a2bb2dc35ff3d9a0658b25da988 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 14 Jul 2022 18:59:06 +0200
Subject: [PATCH 024/175] exclude nokia.com from link checks
---
.github/.mlc_config.json | 7 +++++++
.github/workflows/markdown_check.yml | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 .github/.mlc_config.json
diff --git a/.github/.mlc_config.json b/.github/.mlc_config.json
new file mode 100644
index 0000000..f884edb
--- /dev/null
+++ b/.github/.mlc_config.json
@@ -0,0 +1,7 @@
+{
+ "ignorePatterns": [
+ {
+ "pattern": "https://www.nokia.com"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.github/workflows/markdown_check.yml b/.github/workflows/markdown_check.yml
index d623a32..0a6ad3b 100644
--- a/.github/workflows/markdown_check.yml
+++ b/.github/workflows/markdown_check.yml
@@ -15,7 +15,9 @@ jobs:
steps:
- uses: actions/checkout@master
- uses: gaurav-nelson/github-action-markdown-link-check@v1
-
+ with:
+ use-quiet-mode: 'yes'
+ config-file: ".github/.mlc_config.json"
- name: Lint changelog file root
uses: avto-dev/markdown-lint@v1
with:
From cff9f760bfb7de17674a23ebed81948f3372cf4e Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 14 Jul 2022 19:01:00 +0200
Subject: [PATCH 025/175] wf headline in lower cases
---
.github/workflows/markdown_check.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/markdown_check.yml b/.github/workflows/markdown_check.yml
index 0a6ad3b..1dc30e2 100644
--- a/.github/workflows/markdown_check.yml
+++ b/.github/workflows/markdown_check.yml
@@ -1,6 +1,6 @@
# workflow to run the ncm-issuer unittest suite
-name: Markdown Link check
+name: markdown link check
on:
push:
From d8cec645df228db512a273b34f60b6279795f74e Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 14 Jul 2022 20:13:09 +0200
Subject: [PATCH 026/175] clientauth workflow
---
.github/workflows/clientauth-test.yml | 122 ++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
create mode 100644 .github/workflows/clientauth-test.yml
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
new file mode 100644
index 0000000..596b4f2
--- /dev/null
+++ b/.github/workflows/clientauth-test.yml
@@ -0,0 +1,122 @@
+name: enrollment tests
+
+on:
+ push:
+ pull_request:
+ branches: [ main ]
+
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '0 2 * * 6'
+
+jobs:
+ clientauth_test:
+ name: "clientauth test"
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ k8sversion: ['1.21', '1.22', '1.23', '1.24']
+ certmgrversion: ['1.6.1', '1.7', '1.8']
+ steps:
+
+ - name: "checkout GIT"
+ uses: actions/checkout@v2
+ - uses: actions/setup-go@v3
+ - run: go version
+
+ - name: "build plugin"
+ run: |
+ go mod vendor
+ make docker_build_img
+ make save
+ - name: "install microk8s"
+ run: |
+ sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
+ sudo microk8s status --wait-ready
+ sudo microk8s enable helm3
+ sudo microk8s enable dns
+ - name: "install cert-manager charts"
+ run: |
+ sudo microk8s.kubectl create namespace cert-manager
+ sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
+ sudo microk8s.helm3 repo update
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgrversion }} --set installCRDs=true
+ echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
+ - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+
+ - name: "prepare environment / create namespace and secret"
+ run: |
+ mkdir -p data/logs
+ echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
+ echo "$CLIENTAUTH_CERT" > data/clientauth_cert.pem
+ echo "$CLIENTAUTH_KEY" > data/clientauth_key.pem
+ cp .github/*.yml data/
+ sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sudo microk8s.kubectl create namespace ncm-issuer
+ sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
+ sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem --from-file=key=data/clientauth_key.pem --from-file=cert=data/clientauth_cert.pem
+
+ env:
+ NCM_HOST: ${{ secrets.CLIENTAUTH_NCM_HOST }}
+ NCM_USER: ${{ secrets.NCM_USER }}
+ NCM_PASSWORD: ${{ secrets.NCM_PASSWORD }}
+ NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }}
+ CLIENTAUTH_CERT: ${{ secrets.CLIENTAUTH_CERT }}
+ CLIENTAUTH_KEY: ${{ secrets.CLIENTAUTH_KEY }}
+
+ - name: "install plugin"
+ run: |
+ sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+ - name: "create issuer"
+ run: |
+ sudo microk8s.kubectl apply -f data/ncm-issuer.yml
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check issuer status"
+ run: |
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+ - name: "create certificate resource"
+ run: |
+ sudo microk8s.kubectl apply -f data/cert-resource.yml
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ exit 1
+ - name: "[ * ] collecting test logs"
+ continue-on-error: true
+ if: ${{ failure() }}
+ run: |
+ sudo microk8s.kubectl get namespaces > data/logs/get_namespaces.log
+ sudo microk8s.kubectl get po -A > data/logs/get_pods.log
+ sudo microk8s.kubectl describe pods ncm-issuer -n ncm-issuer > data/logs/describe_ncm-issuer.log
+ sudo microk8s.kubectl get secrets -n ncm-issuer > data/logs/get_secrets.log
+ sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/get_issuers.log
+ sudo microk8s.kubectl describe issuer.certmanager.ncm.nokia.com -n ncm-issuer > data/logs/describe_issuer.log
+ sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'` > data/logs/ncm-issuer.log
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer > data/logs/get_csr.log
+ sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer > data/logs/describe_csr.log
+ sudo microk8s.kubectl get certificate -n ncm-issuer > data/logs/get_certificate.log
+ sudo microk8s.kubectl describe certificate ncm-cert -n ncm-issuer > data/logs/describe_certificate.log
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+ - name: "[ * ] uploading artificates"
+ uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgrversion }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
From 463cbabcacb47df01474f8b2375ceada99a3c30a Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 14 Jul 2022 20:20:38 +0200
Subject: [PATCH 027/175] rename workflow
---
.github/workflows/clientauth-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index 596b4f2..9284869 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -1,4 +1,4 @@
-name: enrollment tests
+name: clientauth tests
on:
push:
From 3390a58023442a240e93dda0925e99ac5e71313f Mon Sep 17 00:00:00 2001
From: grindsa
Date: Thu, 14 Jul 2022 20:25:25 +0200
Subject: [PATCH 028/175] removed exit command
---
.github/workflows/clientauth-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index 9284869..933b6a1 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -95,7 +95,7 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
- exit 1
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
From 15f35006ef9a9323cf52fc84e91c5b68b4f49b36 Mon Sep 17 00:00:00 2001
From: LissaGreense
Date: Wed, 10 Aug 2022 14:17:06 +0200
Subject: [PATCH 029/175] Updated go version to 1.17
---
Dockerfile | 2 +-
Makefile | 4 +-
go.mod | 52 +-
go.sum | 939 +---------------------
pkg/controllers/issuer_controller_test.go | 17 +-
release_notes.txt | 3 +
6 files changed, 68 insertions(+), 949 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 6e6d4d1..2affba7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Build the manager binary
-FROM golang:1.16.15 AS builder
+FROM golang:1.17 AS builder
WORKDIR /
# COPY . ./
diff --git a/Makefile b/Makefile
index 241f520..48f7d34 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
export GOFLAGS=-mod=vendor
export GO111MODULE=on
-BUILD_VERSION ?= 1.0.0
+BUILD_VERSION ?= 1.0.1
IMG_NAME ?= ncm-issuer
# Image URL to use all building/pushing image targets
@@ -11,7 +11,7 @@ IMG ?= ncm-issuer:${BUILD_VERSION}
CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false"
APP_NAME ?= ncm-issuer
-APP_VERSION ?= 1.0.1
+APP_VERSION ?= 1.0.2
# DevOPS Artifactory Repositories
ARTIFACTORY_URL ?= repo.lab.pl.alcatel-lucent.com
diff --git a/go.mod b/go.mod
index fa7463c..698b931 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/nokia/ncm-issuer
-go 1.16
+go 1.17
require (
github.com/go-logr/logr v0.4.0
@@ -12,3 +12,53 @@ require (
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a
sigs.k8s.io/controller-runtime v0.10.1
)
+
+require (
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.1.1 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/evanphx/json-patch v4.11.0+incompatible // indirect
+ github.com/fsnotify/fsnotify v1.4.9 // indirect
+ github.com/go-logr/zapr v0.4.0 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
+ github.com/google/go-cmp v0.5.6 // indirect
+ github.com/google/gofuzz v1.2.0 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ github.com/googleapis/gnostic v0.5.5 // indirect
+ github.com/imdario/mergo v0.3.12 // indirect
+ github.com/json-iterator/go v1.1.11 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.1 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/prometheus/client_golang v1.11.0 // indirect
+ github.com/prometheus/client_model v0.2.0 // indirect
+ github.com/prometheus/common v0.26.0 // indirect
+ github.com/prometheus/procfs v0.6.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ go.uber.org/atomic v1.7.0 // indirect
+ go.uber.org/multierr v1.6.0 // indirect
+ go.uber.org/zap v1.19.0 // indirect
+ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
+ golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 // indirect
+ golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect
+ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
+ golang.org/x/text v0.3.6 // indirect
+ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+ gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
+ google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/protobuf v1.27.1 // indirect
+ gopkg.in/inf.v0 v0.9.1 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+ k8s.io/apiextensions-apiserver v0.22.2 // indirect
+ k8s.io/component-base v0.22.2 // indirect
+ k8s.io/klog/v2 v2.9.0 // indirect
+ k8s.io/kube-aggregator v0.22.0 // indirect
+ k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
+ sigs.k8s.io/yaml v1.2.0 // indirect
+)
diff --git a/go.sum b/go.sum
index 3973d70..365a35d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,3 @@
-bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
-bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -15,15 +13,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
-cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
-cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
-cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
-cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
-cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
-cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
-cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -43,314 +32,73 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/azure-sdk-for-go v56.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
-github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
-github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
-github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
-github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
-github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
-github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
-github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
-github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
-github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
-github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
-github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
-github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
-github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
-github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
-github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
-github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
-github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
-github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
-github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
-github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
-github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
-github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
-github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
-github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
-github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
-github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
-github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
-github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
-github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
-github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
-github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
-github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
-github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
-github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
-github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
-github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
-github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
-github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
-github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
-github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
-github.com/Venafi/vcert/v4 v4.14.3/go.mod h1:IL+6LA8QRWZbmcMzIr/vRhf9Aa6XDM2cQO50caWevjA=
-github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
-github.com/ahmetb/gen-crd-api-reference-docs v0.2.1-0.20201224172655-df869c1245d4/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8=
-github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1/go.mod h1:kX6YddBkXqqywAe8c9LyvgTCyFuZCTMF4cRPQhc3Fy8=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
-github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
-github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
-github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
-github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
-github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
-github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
-github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
-github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
-github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
-github.com/aws/aws-sdk-go v1.40.21/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
-github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
-github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
-github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
-github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
-github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
-github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
-github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
-github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
-github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
-github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
-github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
-github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
-github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
-github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
-github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
-github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
-github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
-github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
-github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
-github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/cloudflare-go v0.20.0/go.mod h1:sPWL/lIC6biLEdyGZwBQ1rGQKF1FhM7N60fuNiFdYTI=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
-github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
-github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
-github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
-github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
-github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
-github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
-github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
-github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
-github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
-github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
-github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
-github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
-github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
-github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
-github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
-github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
-github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
-github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
-github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
-github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=
-github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
-github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
-github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
-github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
-github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
-github.com/containerd/containerd v1.5.4/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw=
-github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
-github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
-github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
-github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
-github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
-github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
-github.com/containerd/continuity v0.2.0/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg=
-github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
-github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
-github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
-github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
-github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
-github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
-github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU=
-github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
-github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
-github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
-github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
-github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
-github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
-github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
-github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
-github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
-github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
-github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
-github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
-github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
-github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
-github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
-github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
-github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
-github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
-github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
-github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
-github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
-github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
-github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
-github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
-github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
-github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
-github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
-github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
-github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
-github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
-github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
-github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
-github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
-github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
-github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
-github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobeGqugQ=
-github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
-github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
-github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
-github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
-github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
-github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
-github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
-github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
-github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/digitalocean/godo v1.65.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
-github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3/go.mod h1:gt38b7cvVKazi5XkHvINNytZXgTEntyhtyM3HQz46Nk=
-github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
-github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
-github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v17.12.1-ce+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
-github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
-github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
-github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
-github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
-github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
-github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
-github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
@@ -358,139 +106,51 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
-github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
-github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
-github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
-github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
-github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
-github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
-github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
-github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
-github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
-github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
-github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8=
-github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU=
github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM=
github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
-github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
-github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
-github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
-github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
-github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
-github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
-github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
-github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
-github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
-github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
-github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
-github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
-github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
-github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
-github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
-github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
-github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
-github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
-github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
-github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
-github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
-github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
-github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
-github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
-github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
-github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
-github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
-github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
-github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
-github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
-github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
-github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
-github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
-github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
-github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
-github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
-github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
-github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
-github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
-github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
-github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
-github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
-github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
-github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
-github.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg=
-github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
-github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
-github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
-github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE=
-github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
-github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
-github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -504,9 +164,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
-github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
-github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
-github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -525,10 +182,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
-github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
@@ -539,21 +192,16 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -561,130 +209,58 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
-github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
-github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
-github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
-github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
-github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
-github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
-github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
-github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
-github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
-github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
-github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
-github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY=
-github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
-github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
-github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
-github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
-github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
-github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE=
-github.com/hashicorp/vault/api v1.1.1/go.mod h1:29UXcn/1cLOPHQNMWA7bCz2By4PSd0VKPAydKXS5yN0=
-github.com/hashicorp/vault/sdk v0.1.14-0.20200519221530-14615acda45f/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
-github.com/hashicorp/vault/sdk v0.2.1/go.mod h1:WfUiO1vYzfBkz1TmoE4ZGU7HD0T0Cl/rZwaxjBkgN4U=
-github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
-github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jetstack/cert-manager v1.6.3 h1:t5Ldacaed2qmDEXsuzkfsa1uE5rpzdDM1vMzheUbbHI=
github.com/jetstack/cert-manager v1.6.3/go.mod h1:1nXjnzzsYcIFvl4eLTkVqpvh9NQogkCq4FaCmgvNDDY=
-github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
-github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
-github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
-github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -693,98 +269,38 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
-github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc=
-github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
-github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
-github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
-github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
-github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
-github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
-github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
-github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
-github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
-github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
-github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/miekg/dns v1.1.34/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
-github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
-github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
-github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
-github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
-github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
-github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
-github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
-github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
-github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
-github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -792,203 +308,94 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
-github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
-github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
-github.com/munnerz/crd-schema-fuzz v1.0.0/go.mod h1:4z/rcm37JxUkSsExFcLL6ZIT1SgDRdLiu7qq1evdVS0=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
-github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
-github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
-github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
-github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
-github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
-github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
-github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
-github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
-github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
-github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
-github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
-github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
-github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
-github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
-github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
-github.com/pavel-v-chernykh/keystore-go/v4 v4.1.0/go.mod h1:2ejgys4qY+iNVW1IittZhyRYA6MNv8TgM6VHqojbB9g=
-github.com/pavel-v-chernykh/keystore-go/v4 v4.2.0/go.mod h1:VxOBKEAW8/EJjil9qwfvVDSljDW0DCoZMD4ezsq9n8U=
-github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
-github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
-github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
-github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
-github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
-github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
-github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
-github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
-github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
-github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
-github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
-github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
-github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
-github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
-github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
-github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
-github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
-github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
-github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -997,55 +404,16 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
-github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
-github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
-github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
-github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
-github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
-github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
-github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
-github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
-github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
-github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
-github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
-github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
-github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
-github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
-github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
-github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
-github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
-github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
-github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
-go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
-go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
@@ -1053,17 +421,11 @@ go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lL
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
-go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
-go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
-go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
-go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
@@ -1076,55 +438,27 @@ go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
-go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
-golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1147,7 +481,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
@@ -1158,16 +491,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1175,21 +502,15 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1202,27 +523,14 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
-golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1230,16 +538,6 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 h1:Ati8dO7+U7mxpkPSxBZQEvzHVUYB/MqCklCN8ig5w/o=
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1253,7 +551,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1261,52 +558,27 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1316,79 +588,45 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -1398,17 +636,12 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1416,7 +649,6 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -1428,42 +660,28 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
-golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
-golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
-google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -1480,17 +698,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
-google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
-google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
-google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
-google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
-google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
-google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
-google.golang.org/api v0.53.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1499,13 +706,11 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
@@ -1514,7 +719,6 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
@@ -1533,38 +737,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
-google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
-google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
-google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
-google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
-google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
@@ -1573,21 +751,10 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
-google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
-google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1602,31 +769,20 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
-gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
-gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
@@ -1643,10 +799,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
-helm.sh/helm/v3 v3.7.0/go.mod h1:DajHtQTe8KrjNmvy5gxWkosFKaADrS3uRS5EkDtsmI4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1654,135 +808,46 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
-k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
-k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
-k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
-k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU=
k8s.io/api v0.22.0/go.mod h1:0AoXXqst47OI/L0oGKq9DG61dvGRPXs7X4/B7KyjBCU=
-k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY=
k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw=
k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
-k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo=
-k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
-k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs=
-k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c=
k8s.io/apiextensions-apiserver v0.22.2 h1:zK7qI8Ery7j2CaN23UCFaC1hj7dMiI87n01+nKuewd4=
k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA=
-k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
-k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
k8s.io/apimachinery v0.22.0/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
-k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk=
k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
-k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw=
-k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
-k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA=
-k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
-k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
k8s.io/apiserver v0.22.0/go.mod h1:04kaIEzIQrTGJ5syLppQWvpkLJXQtJECHmae+ZGc/nc=
-k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400=
k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI=
-k8s.io/cli-runtime v0.22.1/go.mod h1:YqwGrlXeEk15Yn3em2xzr435UGwbrCw5x+COQoTYfoo=
-k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
-k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
-k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE=
-k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
-k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
-k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA=
k8s.io/client-go v0.22.0/go.mod h1:GUjIuXR5PiEv/RVK5OODUsm6eZk7wtSWZSaSJbpFdGg=
-k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk=
k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc=
k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U=
-k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
-k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
-k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
-k8s.io/code-generator v0.21.0/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
k8s.io/code-generator v0.22.0/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
-k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
-k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
-k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
-k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0=
-k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
-k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
k8s.io/component-base v0.22.0/go.mod h1:SXj6Z+V6P6GsBhHZVbWCw9hFjUdUYnJerlhhPnYCBCg=
-k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo=
k8s.io/component-base v0.22.2 h1:vNIvE0AIrLhjX8drH0BgCNJcR4QZxMXcJzBsDplDx9M=
k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug=
-k8s.io/component-helpers v0.22.1/go.mod h1:QvBcDbX+qU5I2tMZABBF5fRwAlQwiv771IGBHK9WYh4=
-k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
-k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
-k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
-k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
-k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
-k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
-k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
-k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/kube-aggregator v0.22.0 h1:he3plI8vlaPJxR9vsy/lL5ga1V8CoA8M8x1Bn8eTCeM=
k8s.io/kube-aggregator v0.22.0/go.mod h1:zHTepg0Q4tKzru7Pwg1QYHWrU/wrvIXM8hUdDAH66qg=
-k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
-k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
-k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d h1:lUK8GPtuJy8ClWZhuvKoaLdKGPLq9H1PxWp7VPBZBkU=
k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
-k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw=
-k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
-k8s.io/metrics v0.22.1/go.mod h1:i/ZNap89UkV1gLa26dn7fhKAdheJaKy+moOqJbiif7E=
-k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
-k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210305010621-2afb4311ab10/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-oras.land/oras-go v0.4.0/go.mod h1:VJcU+VE4rkclUbum5C0O7deEZbBYnsnpbGSACwTjOcg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
sigs.k8s.io/controller-runtime v0.10.1 h1:+eLHgY/VrJWnfg6iXUqhCUqNXgPH1NZeP9drNAAgWlg=
sigs.k8s.io/controller-runtime v0.10.1/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY=
-sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUyp0jmnAM/I=
-sigs.k8s.io/controller-tools v0.7.0/go.mod h1:bpBAo0VcSDDLuWt47evLhMLPxRPxMDInTEH/YbdeMK0=
-sigs.k8s.io/gateway-api v0.3.0/go.mod h1:Wb8bx7QhGVZxOSEU3i9vw/JqTB5Nlai9MLMYVZeDmRQ=
-sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
-sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs=
-sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go=
-sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
-sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
-sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
-sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
-software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ=
-software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78/go.mod h1:B7Wf0Ya4DHF9Yw+qfZuJijQYkWicqDa+79Ytmmq3Kjg=
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 410f07c..6025ae2 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -26,15 +26,16 @@ const (
Issuer = "Issuer"
)
-type testCase struct {
- kind string
- name types.NamespacedName
- objects []client.Object
- expectedResult ctrl.Result
- expectedErrorMsg string
-}
-
func TestIssuerReconcile(t *testing.T) {
+
+ type testCase struct {
+ kind string
+ name types.NamespacedName
+ objects []client.Object
+ expectedResult ctrl.Result
+ expectedErrorMsg string
+ }
+
tests := map[string]testCase{
"successIssuer": {
name: types.NamespacedName{Namespace: "ncm-issuer", Name: "issuer"},
diff --git a/release_notes.txt b/release_notes.txt
index 7866be8..a625b9b 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -16,3 +16,6 @@ Version 1.0.0 (Build Version 0.1.149)
Version 1.0.1 (Build Version 1.0.0)
- Added Ncm Issuer version to logging
+
+Version 1.0.2 (Build Version 1.0.1)
+- Update go version to 1.17
From 93f471f3ed44291580e7ef4a991acaaeec469ecf Mon Sep 17 00:00:00 2001
From: LissaGreense
Date: Wed, 10 Aug 2022 14:54:35 +0200
Subject: [PATCH 030/175] Updated go version in unitest workflow
---
.github/workflows/unit_test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
index 89ab70c..03fb8bc 100644
--- a/.github/workflows/unit_test.yml
+++ b/.github/workflows/unit_test.yml
@@ -15,7 +15,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
- go-version: 1.16
+ go-version: 1.17
- name: Build
run: go build -v ./...
From b3d12355908b74f33c71d42b620705ce9990fa52 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Tue, 16 Aug 2022 17:38:09 +0200
Subject: [PATCH 031/175] disable pr trigger for wf accessing secrets
---
.github/workflows/cahref-test.yml | 3 ---
.github/workflows/certmanager-application-test.yml | 3 ---
.github/workflows/clientauth-test.yml | 3 ---
.github/workflows/pkey-tests.yml | 3 ---
.github/workflows/san-tests.yml | 3 ---
5 files changed, 15 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index bc072fd..aa5b0ad 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -2,9 +2,6 @@ name: key algorithm tests
on:
push:
- pull_request:
- branches: [ main ]
-
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 2 * * 6'
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 817dd00..17c5e0c 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -2,9 +2,6 @@ name: enrollment tests
on:
push:
- pull_request:
- branches: [ main ]
-
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 2 * * 6'
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index 933b6a1..0dd02ef 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -2,9 +2,6 @@ name: clientauth tests
on:
push:
- pull_request:
- branches: [ main ]
-
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 2 * * 6'
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
index ad32f9e..e259f85 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/pkey-tests.yml
@@ -2,9 +2,6 @@ name: key algorithm tests
on:
push:
- pull_request:
- branches: [ main ]
-
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 2 * * 6'
diff --git a/.github/workflows/san-tests.yml b/.github/workflows/san-tests.yml
index 66ac543..5b8b403 100644
--- a/.github/workflows/san-tests.yml
+++ b/.github/workflows/san-tests.yml
@@ -2,9 +2,6 @@ name: san tests
on:
push:
- pull_request:
- branches: [ main ]
-
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 2 * * 6'
From c2472acb1829d4edfbd25ede5c02762778ba6dd4 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 09:10:51 +0200
Subject: [PATCH 032/175] version update
---
.github/workflows/certmanager-application-test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 17c5e0c..04e09fb 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -12,8 +12,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- k8sversion: ['1.21', '1.22', '1.23', '1.24']
- certmgrversion: ['1.6.1', '1.7', '1.8']
+ k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25']
+ certmgrversion: ['1.6.1', '1.7', '1.8', '1.9']
steps:
- name: "checkout GIT"
From 67b384d0534f503f5a6630757133f732d6ce9d30 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 09:13:18 +0200
Subject: [PATCH 033/175] version update in clusterissuer test
---
.github/workflows/certmanager-application-test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 04e09fb..47e7273 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -121,8 +121,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- k8sversion: ['1.21', '1.22', '1.23', '1.24']
- certmgrversion: ['1.6.1', '1.7', '1.8']
+ k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25']
+ certmgrversion: ['1.6.1', '1.7', '1.8', '1.9']
steps:
- name: "checkout GIT"
From 6b5f6cea454d9b162cb2a531771e23725c9d2ba1 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 11:00:20 +0200
Subject: [PATCH 034/175] remove cert-mgr 1.7 from test
---
.github/workflows/certmanager-application-test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 47e7273..8544ce7 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -13,7 +13,7 @@ jobs:
strategy:
matrix:
k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25']
- certmgrversion: ['1.6.1', '1.7', '1.8', '1.9']
+ certmgrversion: ['1.6.1', '1.8', '1.9']
steps:
- name: "checkout GIT"
@@ -122,7 +122,7 @@ jobs:
strategy:
matrix:
k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25']
- certmgrversion: ['1.6.1', '1.7', '1.8', '1.9']
+ certmgrversion: ['1.6.1', '1.8', '1.9']
steps:
- name: "checkout GIT"
From fad582a4ca4965f13b18f5ea17eacabceca3fd92 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 14:40:42 +0200
Subject: [PATCH 035/175] renewal tests in pkey-test workflow
---
.github/cert-resource.yml | 2 ++
.github/workflows/pkey-tests.yml | 48 ++++++++++++++++++++++++++++++--
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/.github/cert-resource.yml b/.github/cert-resource.yml
index 5abbb1f..9b2583b 100644
--- a/.github/cert-resource.yml
+++ b/.github/cert-resource.yml
@@ -14,6 +14,8 @@ spec:
- foo.bar.local
renewBefore: 120h
secretName: mysecret-secret
+ privateKey:
+ rotationPolicy: Always
issuerRef:
group: certmanager.ncm.nokia.com
kind: Issuer
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
index e259f85..9e52575 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/pkey-tests.yml
@@ -42,13 +42,19 @@ jobs:
echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+ - name: "install kubectl cert-manager plugin"
+ run: |
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.7.2/kubectl-cert_manager-$OS-$ARCH.tar.gz
+ tar xzf kubectl-cert-manager.tar.gz
+ sudo mv kubectl-cert_manager /usr/local/bin
+
- name: "prepare environment / create namespace and secret"
run: |
mkdir -p data/logs
echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s/secretName: mysecret-secret/secretName: mysecret-secret\n privateKey:\n algorithm: ECDSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
+ sed -i "s/rotationPolicy: Always/rotationPolicy: Always\n algorithm: ECDSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
@@ -88,6 +94,7 @@ jobs:
- name: "check certificate resource"
run: |
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
@@ -99,6 +106,21 @@ jobs:
openssl x509 -in /tmp/cert.der -text -noout | grep "NIST CURVE: P-${{ matrix.keysize }}"
openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+ - name: "renew certificate"
+ run: |
+ sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer | grep "No CertificateRequest found for this Certificate"
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
@@ -160,13 +182,19 @@ jobs:
echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+ - name: "install kubectl cert-manager plugin"
+ run: |
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.7.2/kubectl-cert_manager-$OS-$ARCH.tar.gz
+ tar xzf kubectl-cert-manager.tar.gz
+ sudo mv kubectl-cert_manager /usr/local/bin
+
- name: "prepare environment / create namespace and secret"
run: |
mkdir -p data/logs
echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s/secretName: mysecret-secret/secretName: mysecret-secret\n privateKey:\n algorithm: RSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
+ sed -i "s/rotationPolicy: Always/rotationPolicy: Always\n algorithm: RSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
@@ -206,6 +234,7 @@ jobs:
- name: "check certificate resource"
run: |
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
@@ -217,6 +246,21 @@ jobs:
openssl x509 -in /tmp/cert.der -text -noout | grep "RSA Public-Key: (${{ matrix.keysize }} bit)"
openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+ - name: "renew certificate"
+ run: |
+ sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer | grep "No CertificateRequest found for this Certificate"
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
From 678b7a8ee501f4896f27c4b4e3c3c9329e325d3a Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 14:46:06 +0200
Subject: [PATCH 036/175] renamed workflow
---
.github/workflows/cahref-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index aa5b0ad..065991f 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -1,4 +1,4 @@
-name: key algorithm tests
+name: caname-href tests
on:
push:
From e93dda5db93b46267813dd12991f2dcc712f7d73 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 15:58:11 +0200
Subject: [PATCH 037/175] renewal in certmanager wf
---
.../certmanager-application-test.yml | 55 +++++++++++++++++--
1 file changed, 51 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml
index 8544ce7..c0f3d08 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/certmanager-application-test.yml
@@ -26,12 +26,14 @@ jobs:
go mod vendor
make docker_build_img
make save
+
- name: "install microk8s"
run: |
sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
sudo microk8s status --wait-ready
sudo microk8s enable helm3
sudo microk8s enable dns
+
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
@@ -41,6 +43,12 @@ jobs:
echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+ - name: "install kubectl cert-manager plugin"
+ run: |
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.7.2/kubectl-cert_manager-$OS-$ARCH.tar.gz
+ tar xzf kubectl-cert-manager.tar.gz
+ sudo mv kubectl-cert_manager /usr/local/bin
+
- name: "prepare environment / create namespace and secret"
run: |
mkdir -p data/logs
@@ -75,13 +83,15 @@ jobs:
- name: "create certificate resource"
run: |
sudo microk8s.kubectl apply -f data/cert-resource.yml
- - name: "sleep for 10s"
+
+ - name: "sleep for 15s"
uses: juliangruber/sleep-action@v1
with:
- time: 10s
+ time: 15s
- name: "check certificate resource"
run: |
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
@@ -91,6 +101,21 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+ - name: "renew certificate"
+ run: |
+ sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-issuer
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer | grep "No CertificateRequest found for this Certificate"
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
@@ -152,6 +177,12 @@ jobs:
echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+ - name: "install kubectl cert-manager plugin"
+ run: |
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.7.2/kubectl-cert_manager-$OS-$ARCH.tar.gz
+ tar xzf kubectl-cert-manager.tar.gz
+ sudo mv kubectl-cert_manager /usr/local/bin
+
- name: "prepare environment / create namespace and secret"
run: |
mkdir -p data/logs
@@ -198,13 +229,14 @@ jobs:
cat data/cert-resource.yml
sudo microk8s.kubectl apply -f data/cert-resource.yml
- - name: "sleep for 10s"
+ - name: "sleep for 15s"
uses: juliangruber/sleep-action@v1
with:
- time: 10s
+ time: 15s
- name: "check certificate resource"
run: |
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-cert
sudo microk8s.kubectl describe cert ncm-cert -n ncm-cert
sudo microk8s.kubectl describe cert ncm-cert -n ncm-cert | grep "The certificate has been successfully issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert
@@ -214,6 +246,21 @@ jobs:
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-cert | grep "Ca:" | awk '{print $2}' | base64 -d > /tmp/ca.pem
openssl verify -CAfile /tmp/ca.pem --untrusted /tmp/cert.der /tmp/cert.der
+ - name: "renew certificate"
+ run: |
+ sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-cert
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl get certificaterequest -n ncm-cert
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-cert
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-cert | grep "No CertificateRequest found for this Certificate"
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
From 3ae436d0961eeec68fa96ecc677096e4f7bacd57 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 16:24:53 +0200
Subject: [PATCH 038/175] timer adjustments
---
.github/workflows/pkey-tests.yml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
index 9e52575..cfd4975 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/pkey-tests.yml
@@ -87,10 +87,10 @@ jobs:
run: |
sudo microk8s.kubectl apply -f data/cert-resource.yml
- - name: "sleep for 10s"
+ - name: "sleep for 15s"
uses: juliangruber/sleep-action@v1
with:
- time: 10s
+ time: 15s
- name: "check certificate resource"
run: |
@@ -110,10 +110,10 @@ jobs:
run: |
sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-issuer
- - name: "sleep for 10s"
+ - name: "sleep for 15s"
uses: juliangruber/sleep-action@v1
with:
- time: 10s
+ time: 15s
- name: "check certificate resource"
run: |
@@ -227,10 +227,10 @@ jobs:
run: |
sudo microk8s.kubectl apply -f data/cert-resource.yml
- - name: "sleep for 10s"
+ - name: "sleep for 15s"
uses: juliangruber/sleep-action@v1
with:
- time: 10s
+ time: 15s
- name: "check certificate resource"
run: |
@@ -250,10 +250,10 @@ jobs:
run: |
sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-issuer
- - name: "sleep for 10s"
+ - name: "sleep for 15s"
uses: juliangruber/sleep-action@v1
with:
- time: 10s
+ time: 15s
- name: "check certificate resource"
run: |
From 37f6ff6b3ac3bcc94520d17a622ebfbaf0d814ff Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 16:43:11 +0200
Subject: [PATCH 039/175] renewal in clientauth workflow
---
.github/workflows/clientauth-test.yml | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index 0dd02ef..ba80cdb 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -26,12 +26,14 @@ jobs:
go mod vendor
make docker_build_img
make save
+
- name: "install microk8s"
run: |
sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
sudo microk8s status --wait-ready
sudo microk8s enable helm3
sudo microk8s enable dns
+
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
@@ -41,6 +43,12 @@ jobs:
echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
+ - name: "install kubectl cert-manager plugin"
+ run: |
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.7.2/kubectl-cert_manager-$OS-$ARCH.tar.gz
+ tar xzf kubectl-cert-manager.tar.gz
+ sudo mv kubectl-cert_manager /usr/local/bin
+
- name: "prepare environment / create namespace and secret"
run: |
mkdir -p data/logs
@@ -64,10 +72,12 @@ jobs:
- name: "install plugin"
run: |
sudo microk8s.helm3 install -n ncm-issuer ncm-issuer "$(pwd)/helm"
+
- name: "create issuer"
run: |
sudo microk8s.kubectl apply -f data/ncm-issuer.yml
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
+
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
with:
@@ -77,6 +87,7 @@ jobs:
run: |
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer
sudo microk8s.kubectl get issuers.certmanager.ncm.nokia.com -n ncm-issuer | grep -i True
+
- name: "create certificate resource"
run: |
sudo microk8s.kubectl apply -f data/cert-resource.yml
@@ -87,12 +98,28 @@ jobs:
- name: "check certificate resource"
run: |
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe cert ncm-cert -n ncm-issuer | grep "The certificate has been successfully issued"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Approved"
sudo microk8s.kubectl describe certificaterequest ncm-cert -n ncm-issuer | grep "Issued"
+ - name: "renew certificate"
+ run: |
+ sudo microk8s.kubectl cert-manager renew ncm-cert -n ncm-issuer
+
+ - name: "sleep for 15s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 15s
+
+ - name: "check certificate resource"
+ run: |
+ sudo microk8s.kubectl get certificaterequest -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer
+ sudo microk8s.kubectl cert-manager status certificate ncm-cert -n ncm-issuer | grep "No CertificateRequest found for this Certificate"
+
- name: "[ * ] collecting test logs"
continue-on-error: true
if: ${{ failure() }}
From 6996fef0e0e0c65dc01afa3fd2eaf1c92c88b093 Mon Sep 17 00:00:00 2001
From: grindsa
Date: Sun, 28 Aug 2022 16:57:54 +0200
Subject: [PATCH 040/175] version updates
---
.github/workflows/clientauth-test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index ba80cdb..a7413b5 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -12,8 +12,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- k8sversion: ['1.21', '1.22', '1.23', '1.24']
- certmgrversion: ['1.6.1', '1.7', '1.8']
+ k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25']
+ certmgrversion: ['1.6.1', '1.8', '1.9']
steps:
- name: "checkout GIT"
From e622e62c99041dd0bf8143a5939a23d27bc85ce2 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 5 Jan 2023 14:15:21 +0100
Subject: [PATCH 041/175] Added basic structure for NCM API Client
---
pkg/ncmapi/ncmapi.go | 329 +++++++++++++++++++++++++++++++++++++++++++
pkg/ncmapi/util.go | 49 +++++++
2 files changed, 378 insertions(+)
create mode 100644 pkg/ncmapi/ncmapi.go
create mode 100644 pkg/ncmapi/util.go
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
new file mode 100644
index 0000000..6fe9f4b
--- /dev/null
+++ b/pkg/ncmapi/ncmapi.go
@@ -0,0 +1,329 @@
+package ncmapi
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/go-logr/logr"
+ "github.com/nokia/ncm-issuer/pkg/controllers"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+const (
+ HTTPTimeout = 10
+ CAsURL = "/v1/cas"
+ CSRURL = "/v1/requests"
+)
+
+type Client struct {
+ // Main NCM EXTERNAL API server address
+ ncmServer string
+
+ // Secondary NCM EXTERNAL API server address in case of the lack of connection
+ // to the main one (can be empty)
+ ncmServer2 string
+
+ // User used for authentication to NCM EXTERNAL API
+ user string
+
+ // Password used for authentication to NCM EXTERNAL API
+ password string
+
+ // Determines whether, in the case of lack of the connection to the main server (no response within
+ // a certain time period), there is an address of a second server to which client can send the
+ // same request
+ allowRetry bool
+
+ HTTPClient *http.Client
+ Log logr.Logger
+}
+
+type ClientError struct {
+ Type string
+ Message error
+}
+
+func (c *ClientError) Error() string {
+ return fmt.Sprintf("NCM API Client error type=%s error=%w", c.Type, c.Message)
+}
+
+type CAsResponse struct {
+ TotalCount int `json:"totalCount"`
+ Href string `json:"href"`
+ CAsList []CAResponse `json:"cas"`
+}
+
+type CAResponse struct {
+ Href string `json:"href"`
+ Name string `json:"name"`
+ Description string `json:"description,omitempty"`
+ Status string `json:"status"`
+ Type string `json:"type,omitempty"`
+ Certificates map[string]string `json:"certificates"`
+}
+
+type CSRResponse struct {
+ Href string `json:"href"`
+ Issuer string `json:"issuer"`
+ Certificate string `json:"certificate"`
+ CertificateBase64 string `json:"certificateBase64"`
+}
+
+type CSRStatusResponse struct {
+ Href string `json:"href"`
+ Issuer string `json:"issuer"`
+ Certificate string `json:"certificate"`
+ Status string `json:"status"`
+}
+
+type CertificateDownloadResponse struct {
+ Href string `json:"href"`
+ Request string `json:"request"`
+ IssuerCA string `json:"issuerCa"`
+ IssuedTime *metav1.Time `json:"issuedTime,omitempty"`
+ Type string `json:"type"`
+ Status string `json:"status"`
+ CertificateBase64 string `json:"certificateBase64"`
+}
+
+type RenewCertificateResponse struct {
+ Result string `json:"result"`
+ Request string `json:"request,omitempty"`
+ Certificate string `json:"certificate"`
+}
+
+type APIError struct {
+ Slug string `json:"error_slug"`
+ ErrorMessage string `json:"error"`
+}
+
+func (a *APIError) Error() string {
+ return fmt.Sprintf("NCM EXTERNAL API Error slug=%s error=%s", a.Slug, a.ErrorMessage)
+}
+
+// Creates a new client used to perform requests to the NCM EXTERNAL API
+func NewClient(ncmConfig *controllers.NcmConfig, log logr.Logger) (*Client, error) {
+ HTTPClient, err := configureHTTPClient(ncmConfig)
+
+ if err != nil {
+ return nil, &ClientError{Type: "client creation error", Message: err}
+ }
+
+ c := &Client{
+ ncmServer: ncmConfig.NcmSERVER,
+ ncmServer2: ncmConfig.NcmSERVER2,
+ allowRetry: ncmConfig.NcmSERVER2 != "",
+ user: ncmConfig.Username,
+ password: ncmConfig.UsrPassword,
+ HTTPClient: HTTPClient,
+ Log: log,
+ }
+
+ return c, nil
+}
+
+// Configures http.Client used for connection to NCM EXTERNAL API according to NCM config
+func configureHTTPClient(ncmConfig *controllers.NcmConfig) (*http.Client, error) {
+ if !strings.HasPrefix(ncmConfig.NcmSERVER, "https") {
+ HTTPClient := &http.Client{
+ Timeout: HTTPTimeout * time.Second,
+ }
+
+ return HTTPClient, nil
+ }
+
+ var tlsConfig *tls.Config
+
+ if ncmConfig.InsecureSkipVerify {
+ tlsConfig = &tls.Config{InsecureSkipVerify: true}
+ } else {
+ CACertPool := x509.NewCertPool()
+ CACertPool.AppendCertsFromPEM([]byte(ncmConfig.Cacert))
+
+ if ncmConfig.Mtls {
+ // Reads the key pair for client certificate
+ clientCert, err := tls.LoadX509KeyPair(ncmConfig.Cert, ncmConfig.Key)
+ if err != nil {
+ return nil, err
+ }
+
+ tlsConfig = &tls.Config{
+ RootCAs: CACertPool,
+ Certificates: []tls.Certificate{clientCert},
+ }
+ } else {
+ tlsConfig = &tls.Config{
+ RootCAs: CACertPool,
+ }
+ }
+ }
+
+ // Creates an HTTPS client and supply it with created CA pool (and client CA if mTLS is enabled)
+ HTTPClient := &http.Client{
+ Timeout: HTTPTimeout * time.Second,
+ Transport: &http.Transport{
+ TLSClientConfig: tlsConfig,
+ },
+ }
+
+ return HTTPClient, nil
+}
+
+func (c *Client) newRequest(method, path string, extraParams map[string]string) (*http.Request, error) {
+ ncmServerURL, err := url.Parse(c.ncmServer)
+ if err != nil {
+ return nil, &ClientError{Type: "URL parsing error", Message: err}
+ }
+
+ ncmServerURL.Path = path
+ params := url.Values{}
+
+ if extraParams != nil {
+ for k, v := range extraParams {
+ params.Add(k, v)
+ }
+ }
+
+ req, err := http.NewRequest(method, ncmServerURL.String(), strings.NewReader(params.Encode()))
+ if err != nil {
+ return nil, &ClientError{Type: "http.NewRequest creation error", Message: err}
+ }
+
+ req.SetBasicAuth(c.user, c.password)
+ req.Header.Set("Accept-Language", "en_US")
+
+ return req, nil
+}
+
+func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
+ c.Log.V(1).Info("retrying request to the second NCM EXTERNAL API")
+ ncmServer2URL, err := url.Parse(c.ncmServer2)
+
+ if err != nil {
+ return nil, &ClientError{Type: "URL parsing error", Message: err}
+ }
+
+ req.URL.Host = ncmServer2URL.Host
+ resp, err := c.HTTPClient.Do(req)
+
+ if err != nil {
+ return nil, &ClientError{Type: "http.Client.Do error", Message: err}
+ }
+
+ return resp, nil
+}
+
+func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
+ if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
+ body, err := io.ReadAll(resp.Body)
+
+ if err != nil {
+ return nil, &ClientError{Type: "response body read error", Message: err}
+ }
+
+ return body, nil
+
+ } else {
+ body, err := io.ReadAll(resp.Body)
+
+ if err != nil {
+ return nil, &ClientError{Type: "response body read error", Message: err}
+ }
+
+ apiError := APIError{}
+
+ err = json.Unmarshal(body, &apiError)
+
+ if err != nil {
+ return nil, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+
+ return nil, &apiError
+ }
+}
+
+func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
+ resp, err := c.HTTPClient.Do(req)
+
+ if err != nil && os.IsTimeout(err) && c.allowRetry {
+ c.Log.V(1).Info("connection timeout exceeded while connection to the main NCM EXTERNAL API")
+
+ resp, err := c.retryRequest(req)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return resp, nil
+
+ } else if err != nil {
+ return nil, &ClientError{Type: "http.Client.Do error", Message: err}
+ }
+
+ return resp, nil
+}
+
+func (c *Client) GetCAs() (CAsResponse, error) {
+ req, err := c.newRequest("GET", CAsURL, nil)
+ req.Header.Set("Accept", "application/json")
+
+ if err != nil {
+ return CAsResponse{}, err
+ }
+
+ resp, err := c.doRequest(req)
+
+ if err != nil {
+ return CAsResponse{}, err
+ }
+
+ defer resp.Body.Close()
+
+ body, err := c.validateResponse(resp)
+
+ if err != nil {
+ return CAsResponse{}, err
+ }
+
+ cas := CAsResponse{}
+ err = json.Unmarshal(body, &cas)
+
+ if err != nil {
+ return CAsResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+
+ return cas, nil
+
+}
+
+func (c *Client) GetCA(path string) (CAResponse, error) {
+
+}
+
+func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRResponse, error) {
+
+}
+
+func (c *Client) CheckCSRStatus(path string) (CSRStatusResponse, error) {
+
+}
+
+func (c *Client) DownloadCertificate(path string) (CertificateDownloadResponse, error) {
+
+}
+
+func (c *Client) DownloadCertificateInPEM(path string) (CertificateDownloadResponse, error) {
+
+}
+
+func (c *Client) RenewCertificate(path string, certDuration metav1.Duration) (RenewCertificateResponse, error) {
+
+}
diff --git a/pkg/ncmapi/util.go b/pkg/ncmapi/util.go
new file mode 100644
index 0000000..11620f7
--- /dev/null
+++ b/pkg/ncmapi/util.go
@@ -0,0 +1,49 @@
+package ncmapi
+
+import (
+ "crypto/rand"
+ "fmt"
+ "io"
+ "os"
+)
+
+// Generates a random UUID according to RFC 4122
+func newUUID() (string, error) {
+ uuid := make([]byte, 16)
+ n, err := io.ReadFull(rand.Reader, uuid)
+ if n != len(uuid) || err != nil {
+ return "", err
+ }
+ // variant bits; see section 4.1.1
+ uuid[8] = uuid[8]&^0xc0 | 0x80
+ // version 4 (pseudo-random); see section 4.1.3
+ uuid[6] = uuid[6]&^0xf0 | 0x40
+ return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
+}
+
+// Writes PEM to temp file (dirprefix is dir prefix)
+func writePemToTempFile(dirprefix string, pem []byte) (string, error) {
+ myuuid, err := newUUID()
+ if err != nil {
+ return "", err
+ }
+
+ // path := "/tmp/ncm_new.pem"
+ path := dirprefix + myuuid + ".pem"
+
+ // write CSRPEM into csrfile
+ csrfile, err := os.Create(path)
+ if err != nil {
+ // return nil, err, "no such file"
+ return path, err
+ }
+ _, err = csrfile.Write(pem)
+ if err != nil {
+ // return nil, err, "err to write file"
+ return path, err
+ }
+ csrfile.Sync()
+ csrfile.Close()
+
+ return path, err
+}
From a7c6b00000a3b6fe709beb92baebc5482ff03aee Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 6 Jan 2023 14:47:12 +0100
Subject: [PATCH 042/175] Finished NCM API Client
---
pkg/ncmapi/ncmapi.go | 276 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 232 insertions(+), 44 deletions(-)
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 6fe9f4b..f961cc9 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -1,14 +1,17 @@
package ncmapi
import (
+ "bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"io"
+ "mime/multipart"
"net/http"
"net/url"
"os"
+ "path/filepath"
"strings"
"time"
@@ -42,6 +45,9 @@ type Client struct {
// same request
allowRetry bool
+ // Determines whether the profile ID should be used during a certificate renewal operation
+ useProfileIDforRenew bool
+
HTTPClient *http.Client
Log logr.Logger
}
@@ -118,13 +124,14 @@ func NewClient(ncmConfig *controllers.NcmConfig, log logr.Logger) (*Client, erro
}
c := &Client{
- ncmServer: ncmConfig.NcmSERVER,
- ncmServer2: ncmConfig.NcmSERVER2,
- allowRetry: ncmConfig.NcmSERVER2 != "",
- user: ncmConfig.Username,
- password: ncmConfig.UsrPassword,
- HTTPClient: HTTPClient,
- Log: log,
+ ncmServer: ncmConfig.NcmSERVER,
+ ncmServer2: ncmConfig.NcmSERVER2,
+ allowRetry: ncmConfig.NcmSERVER2 != "",
+ user: ncmConfig.Username,
+ password: ncmConfig.UsrPassword,
+ useProfileIDforRenew: ncmConfig.UseProfileIDForRenew,
+ HTTPClient: HTTPClient,
+ Log: log,
}
return c, nil
@@ -177,27 +184,21 @@ func configureHTTPClient(ncmConfig *controllers.NcmConfig) (*http.Client, error)
return HTTPClient, nil
}
-func (c *Client) newRequest(method, path string, extraParams map[string]string) (*http.Request, error) {
+func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
ncmServerURL, err := url.Parse(c.ncmServer)
if err != nil {
return nil, &ClientError{Type: "URL parsing error", Message: err}
}
ncmServerURL.Path = path
- params := url.Values{}
-
- if extraParams != nil {
- for k, v := range extraParams {
- params.Add(k, v)
- }
- }
- req, err := http.NewRequest(method, ncmServerURL.String(), strings.NewReader(params.Encode()))
+ req, err := http.NewRequest(method, ncmServerURL.String(), body)
if err != nil {
return nil, &ClientError{Type: "http.NewRequest creation error", Message: err}
}
req.SetBasicAuth(c.user, c.password)
+ req.Header.Set("Accept", "application/json")
req.Header.Set("Accept-Language", "en_US")
return req, nil
@@ -205,15 +206,14 @@ func (c *Client) newRequest(method, path string, extraParams map[string]string)
func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
c.Log.V(1).Info("retrying request to the second NCM EXTERNAL API")
- ncmServer2URL, err := url.Parse(c.ncmServer2)
+ ncmServer2URL, err := url.Parse(c.ncmServer2)
if err != nil {
return nil, &ClientError{Type: "URL parsing error", Message: err}
}
req.URL.Host = ncmServer2URL.Host
resp, err := c.HTTPClient.Do(req)
-
if err != nil {
return nil, &ClientError{Type: "http.Client.Do error", Message: err}
}
@@ -224,40 +224,34 @@ func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
body, err := io.ReadAll(resp.Body)
-
if err != nil {
return nil, &ClientError{Type: "response body read error", Message: err}
}
return body, nil
- } else {
- body, err := io.ReadAll(resp.Body)
-
- if err != nil {
- return nil, &ClientError{Type: "response body read error", Message: err}
- }
-
- apiError := APIError{}
-
- err = json.Unmarshal(body, &apiError)
+ }
- if err != nil {
- return nil, &ClientError{Type: "json unmarshal error", Message: err}
- }
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return nil, &ClientError{Type: "response body read error", Message: err}
+ }
- return nil, &apiError
+ apiError := APIError{}
+ err = json.Unmarshal(body, &apiError)
+ if err != nil {
+ return nil, &ClientError{Type: "json unmarshal error", Message: err}
}
+
+ return nil, &apiError
}
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
resp, err := c.HTTPClient.Do(req)
-
if err != nil && os.IsTimeout(err) && c.allowRetry {
- c.Log.V(1).Info("connection timeout exceeded while connection to the main NCM EXTERNAL API")
+ c.Log.V(1).Info("connection timeout exceeded while connecting to the main NCM EXTERNAL API")
resp, err := c.retryRequest(req)
-
if err != nil {
return nil, err
}
@@ -272,15 +266,13 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
}
func (c *Client) GetCAs() (CAsResponse, error) {
- req, err := c.newRequest("GET", CAsURL, nil)
- req.Header.Set("Accept", "application/json")
-
+ params := url.Values{}
+ req, err := c.newRequest(http.MethodGet, CAsURL, strings.NewReader(params.Encode()))
if err != nil {
return CAsResponse{}, err
}
resp, err := c.doRequest(req)
-
if err != nil {
return CAsResponse{}, err
}
@@ -288,14 +280,12 @@ func (c *Client) GetCAs() (CAsResponse, error) {
defer resp.Body.Close()
body, err := c.validateResponse(resp)
-
if err != nil {
return CAsResponse{}, err
}
cas := CAsResponse{}
err = json.Unmarshal(body, &cas)
-
if err != nil {
return CAsResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
}
@@ -305,25 +295,223 @@ func (c *Client) GetCAs() (CAsResponse, error) {
}
func (c *Client) GetCA(path string) (CAResponse, error) {
+ params := url.Values{}
+ req, err := c.newRequest(http.MethodGet, CAsURL+path, strings.NewReader(params.Encode()))
+ if err != nil {
+ return CAResponse{}, err
+ }
+ resp, err := c.doRequest(req)
+ if err != nil {
+ return CAResponse{}, err
+ }
+
+ defer resp.Body.Close()
+
+ body, err := c.validateResponse(resp)
+ if err != nil {
+ return CAResponse{}, err
+ }
+
+ ca := CAResponse{}
+ err = json.Unmarshal(body, &ca)
+ if err != nil {
+ return CAResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+
+ return ca, nil
}
func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRResponse, error) {
+ filePath, err := writePemToTempFile("/tmp/ncm", pem)
+ if err != nil {
+ return CSRResponse{}, &ClientError{Type: "writing file error", Message: err}
+ }
+
+ file, err := os.Open(filePath)
+ if err != nil {
+ return CSRResponse{}, &ClientError{Type: "opening file error", Message: err}
+ }
+
+ defer file.Close()
+
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+ part, err := writer.CreateFormFile("pkcs10", filepath.Base(filePath))
+ if err != nil {
+ return CSRResponse{}, &ClientError{Type: "writer error", Message: err}
+ }
+
+ params := map[string]string{
+ "ca": CA.Href,
+ }
+
+ if profileId != "" {
+ params["profileId"] = profileId
+ }
+
+ for k, v := range params {
+ _ = writer.WriteField(k, v)
+ }
+
+ _, _ = io.Copy(part, file)
+
+ err = writer.Close()
+ if err != nil {
+ return CSRResponse{}, &ClientError{Type: "writer error", Message: err}
+ }
+
+ req, err := c.newRequest(http.MethodPost, CSRURL, body)
+ if err != nil {
+ return CSRResponse{}, err
+ }
+
+ req.Header.Set("Content-Type", writer.FormDataContentType())
+
+ err = os.Remove(filePath)
+ if err != nil {
+ return CSRResponse{}, &ClientError{Type: "removing file error", Message: err}
+ }
+
+ resp, err := c.doRequest(req)
+ if err != nil {
+ return CSRResponse{}, err
+ }
+
+ defer resp.Body.Close()
+
+ respBody, err := c.validateResponse(resp)
+ if err != nil {
+ return CSRResponse{}, err
+ }
+
+ csr := CSRResponse{}
+ err = json.Unmarshal(respBody, &csr)
+ if err != nil {
+ return CSRResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+ return csr, nil
}
func (c *Client) CheckCSRStatus(path string) (CSRStatusResponse, error) {
+ params := url.Values{}
+ req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
+ if err != nil {
+ return CSRStatusResponse{}, err
+ }
+
+ resp, err := c.doRequest(req)
+ if err != nil {
+ return CSRStatusResponse{}, err
+ }
+ defer resp.Body.Close()
+
+ body, err := c.validateResponse(resp)
+ if err != nil {
+ return CSRStatusResponse{}, err
+ }
+
+ csrStatus := CSRStatusResponse{}
+ err = json.Unmarshal(body, &csrStatus)
+ if err != nil {
+ return CSRStatusResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+
+ return csrStatus, nil
}
func (c *Client) DownloadCertificate(path string) (CertificateDownloadResponse, error) {
+ params := url.Values{}
+ req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
+ if err != nil {
+ return CertificateDownloadResponse{}, err
+ }
+
+ resp, err := c.doRequest(req)
+ if err != nil {
+ return CertificateDownloadResponse{}, err
+ }
+
+ defer resp.Body.Close()
+
+ body, err := c.validateResponse(resp)
+ if err != nil {
+ return CertificateDownloadResponse{}, err
+ }
+ certificate := CertificateDownloadResponse{}
+ err = json.Unmarshal(body, &certificate)
+ if err != nil {
+ return CertificateDownloadResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+
+ return certificate, nil
}
-func (c *Client) DownloadCertificateInPEM(path string) (CertificateDownloadResponse, error) {
+func (c *Client) DownloadCertificateInPEM(path string) ([]byte, error) {
+ params := url.Values{}
+ req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
+ if err != nil {
+ return nil, err
+ }
+
+ req.Header.Set("Accept", "application/x-pem-file")
+ resp, err := c.doRequest(req)
+ if err != nil {
+ return nil, err
+ }
+
+ defer resp.Body.Close()
+
+ body, err := c.validateResponse(resp)
+ if err != nil {
+ return nil, err
+ }
+
+ return body, nil
}
-func (c *Client) RenewCertificate(path string, certDuration metav1.Duration) (RenewCertificateResponse, error) {
+func (c *Client) RenewCertificate(path string, certDuration metav1.Duration, profileId string) (RenewCertificateResponse, error) {
+ notBefore := time.Now()
+ notAfter := notBefore.Add(certDuration.Duration)
+
+ newData := map[string]string{
+ "notBefore": notBefore.Format(time.RFC3339Nano),
+ "notAfter": notAfter.Format(time.RFC3339Nano),
+ }
+
+ if profileId != "" && c.useProfileIDforRenew {
+ newData["profileId"] = profileId
+ }
+
+ jsonData, _ := json.Marshal(&newData)
+ req, err := c.newRequest(http.MethodPost, path+"/update", strings.NewReader(string(jsonData)))
+ if err != nil {
+ return RenewCertificateResponse{}, err
+ }
+
+ req.Header.Set("Content-Type", "application/json")
+
+ resp, err := c.doRequest(req)
+ if err != nil {
+ return RenewCertificateResponse{}, err
+ }
+
+ defer resp.Body.Close()
+
+ body, err := c.validateResponse(resp)
+ if err != nil {
+ return RenewCertificateResponse{}, err
+ }
+
+ renewedCertificate := RenewCertificateResponse{}
+ err = json.Unmarshal(body, &renewedCertificate)
+ if err != nil {
+ return RenewCertificateResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ }
+ return renewedCertificate, nil
}
From 78bf62e469999b08ea609370905b70a79556dde6 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 6 Jan 2023 15:50:05 +0100
Subject: [PATCH 043/175] Fixed converting error messages in ClientError
---
pkg/ncmapi/ncmapi.go | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index f961cc9..dc3f6a7 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -49,7 +49,7 @@ type Client struct {
useProfileIDforRenew bool
HTTPClient *http.Client
- Log logr.Logger
+ log logr.Logger
}
type ClientError struct {
@@ -58,7 +58,7 @@ type ClientError struct {
}
func (c *ClientError) Error() string {
- return fmt.Sprintf("NCM API Client error type=%s error=%w", c.Type, c.Message)
+ return fmt.Sprintf("NCM API Client error type=%s error=%v", c.Type, c.Message)
}
type CAsResponse struct {
@@ -131,7 +131,7 @@ func NewClient(ncmConfig *controllers.NcmConfig, log logr.Logger) (*Client, erro
password: ncmConfig.UsrPassword,
useProfileIDforRenew: ncmConfig.UseProfileIDForRenew,
HTTPClient: HTTPClient,
- Log: log,
+ log: log,
}
return c, nil
@@ -205,7 +205,7 @@ func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request,
}
func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
- c.Log.V(1).Info("retrying request to the second NCM EXTERNAL API")
+ c.log.V(1).Info("retrying request to the second NCM EXTERNAL API")
ncmServer2URL, err := url.Parse(c.ncmServer2)
if err != nil {
@@ -249,7 +249,7 @@ func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
resp, err := c.HTTPClient.Do(req)
if err != nil && os.IsTimeout(err) && c.allowRetry {
- c.Log.V(1).Info("connection timeout exceeded while connecting to the main NCM EXTERNAL API")
+ c.log.V(1).Info("connection timeout exceeded while connecting to the main NCM EXTERNAL API")
resp, err := c.retryRequest(req)
if err != nil {
From b7c8dda5f1947fc3944d922ab56c99a48d4be96b Mon Sep 17 00:00:00 2001
From: raczu
Date: Sun, 8 Jan 2023 14:18:21 +0100
Subject: [PATCH 044/175] Moved NCM config to ncmapi pkg
---
pkg/ncmapi/ncmapi.go | 78 +++++++++++++++++++++++++++++++++++---------
1 file changed, 63 insertions(+), 15 deletions(-)
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index dc3f6a7..c30f092 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -16,7 +16,6 @@ import (
"time"
"github.com/go-logr/logr"
- "github.com/nokia/ncm-issuer/pkg/controllers"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -26,6 +25,55 @@ const (
CSRURL = "/v1/requests"
)
+// NCM config set up with secret and used for NCM API Client configuration
+type NCMConfig struct {
+ Username string
+ UsrPassword string
+ NcmSERVER string
+ NcmSERVER2 string
+
+ // CAs for BCMTNCM
+ CASNAME string
+
+ // href for BCMTNCM
+ CASHREF string
+
+ ReenrollmentOnRenew bool
+ UseProfileIDForRenew bool
+
+ // NCM root CA
+ InstaCA string
+
+ // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
+ LittleEndianPem bool
+
+ // Determines whether Issuer of the Cert should be taken into consideration instead of root
+ NoRoot bool
+
+ // TLS CA Cert
+ CACert string
+
+ // TLS client Key
+ Key string
+
+ // TLS client Cert
+ Cert string
+
+ // Determines whether SSL certificate verification between client instance and NCM EXTERNAL API
+ // should be enabled
+ InsecureSkipVerify bool
+
+ // Determines whether mTLS should be enabled
+ MTLS bool
+}
+
+// Used to separate different configurations for different namespaces
+type NCMConfigKey struct {
+ Namespace string
+ Name string
+}
+
+// Client used to communicate with the NCM EXTERNAL API
type Client struct {
// Main NCM EXTERNAL API server address
ncmServer string
@@ -116,20 +164,20 @@ func (a *APIError) Error() string {
}
// Creates a new client used to perform requests to the NCM EXTERNAL API
-func NewClient(ncmConfig *controllers.NcmConfig, log logr.Logger) (*Client, error) {
- HTTPClient, err := configureHTTPClient(ncmConfig)
+func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
+ HTTPClient, err := configureHTTPClient(cfg)
if err != nil {
return nil, &ClientError{Type: "client creation error", Message: err}
}
c := &Client{
- ncmServer: ncmConfig.NcmSERVER,
- ncmServer2: ncmConfig.NcmSERVER2,
- allowRetry: ncmConfig.NcmSERVER2 != "",
- user: ncmConfig.Username,
- password: ncmConfig.UsrPassword,
- useProfileIDforRenew: ncmConfig.UseProfileIDForRenew,
+ ncmServer: cfg.NcmSERVER,
+ ncmServer2: cfg.NcmSERVER2,
+ allowRetry: cfg.NcmSERVER2 != "",
+ user: cfg.Username,
+ password: cfg.UsrPassword,
+ useProfileIDforRenew: cfg.UseProfileIDForRenew,
HTTPClient: HTTPClient,
log: log,
}
@@ -138,8 +186,8 @@ func NewClient(ncmConfig *controllers.NcmConfig, log logr.Logger) (*Client, erro
}
// Configures http.Client used for connection to NCM EXTERNAL API according to NCM config
-func configureHTTPClient(ncmConfig *controllers.NcmConfig) (*http.Client, error) {
- if !strings.HasPrefix(ncmConfig.NcmSERVER, "https") {
+func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
+ if !strings.HasPrefix(cfg.NcmSERVER, "https") {
HTTPClient := &http.Client{
Timeout: HTTPTimeout * time.Second,
}
@@ -149,15 +197,15 @@ func configureHTTPClient(ncmConfig *controllers.NcmConfig) (*http.Client, error)
var tlsConfig *tls.Config
- if ncmConfig.InsecureSkipVerify {
+ if cfg.InsecureSkipVerify {
tlsConfig = &tls.Config{InsecureSkipVerify: true}
} else {
CACertPool := x509.NewCertPool()
- CACertPool.AppendCertsFromPEM([]byte(ncmConfig.Cacert))
+ CACertPool.AppendCertsFromPEM([]byte(cfg.CACert))
- if ncmConfig.Mtls {
+ if cfg.MTLS {
// Reads the key pair for client certificate
- clientCert, err := tls.LoadX509KeyPair(ncmConfig.Cert, ncmConfig.Key)
+ clientCert, err := tls.LoadX509KeyPair(cfg.Cert, cfg.Key)
if err != nil {
return nil, err
}
From f0f2957bb9a0502948211962054bbf76182b9d98 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sun, 8 Jan 2023 18:29:03 +0100
Subject: [PATCH 045/175] Rewritten certificate request controller to make it
work with NCM API Client
---
api/v1/issuer_types.go | 10 +-
.../certificaterequest_controller.go | 389 +++++++++++------
pkg/controllers/httputil.go | 214 ----------
pkg/controllers/issuer_controller.go | 130 +++---
pkg/controllers/ncm_controller.go | 398 ------------------
pkg/ncmapi/ncmapi.go | 4 +-
pkg/ncmapi/util.go | 12 +-
7 files changed, 332 insertions(+), 825 deletions(-)
delete mode 100644 pkg/controllers/httputil.go
delete mode 100644 pkg/controllers/ncm_controller.go
diff --git a/api/v1/issuer_types.go b/api/v1/issuer_types.go
index 8fb58f7..4341c3e 100644
--- a/api/v1/issuer_types.go
+++ b/api/v1/issuer_types.go
@@ -25,7 +25,11 @@ type IssuerSpec struct {
// Define external NCM REST API URL here, as of now http/https are supported
NcmSERVER string `json:"ncmSERVER"`
- // the name of the logical CA on the NCM instance.
+ // +optional
+ // Secondary external NCM REST API URL in case of lack of connection to the main one
+ NcmSERVER2 string `json:"ncmSERVER2"`
+
+ // The name of the logical CA on the NCM instance.
// make sure the names are unique across whole NCM installation
CASNAME string `json:"CASNAME"`
@@ -35,7 +39,7 @@ type IssuerSpec struct {
UseProfileIDForRenew bool `json:"useProfileIDForRenew"`
NoRoot bool `json:"noRoot"`
- // the secret which contains REST API username and password
+ // The secret which contains REST API username and password
AuthSecretName string `json:"secretName"`
// +optional
@@ -43,7 +47,7 @@ type IssuerSpec struct {
ProfileId string `json:"profileId,omitempty"`
// +optional
- // the secret which contains TLS configuration to external NCM server
+ // The secret which contains TLS configuration to external NCM server
// the secret must contain 3 fields:
// cacert for root CA; key, cert for client CA and key pair.
//
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index e3181b1..d45463c 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -19,11 +19,16 @@ package controllers
import (
"context"
"fmt"
+ "regexp"
+ "strings"
+ "time"
+
"github.com/go-logr/logr"
apiutil "github.com/jetstack/cert-manager/pkg/api/util"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
"github.com/nokia/ncm-issuer/pkg/pkiutil"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -32,11 +37,8 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/record"
"k8s.io/utils/clock"
- "regexp"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
- "strings"
- "time"
)
// CertificateRequestReconciler reconciles a MyCRD object
@@ -48,7 +50,7 @@ type CertificateRequestReconciler struct {
Recorder record.EventRecorder
}
-/////////////////////////////////////
+// ///////////////////////////////////
var (
// CertificateRequestPendingList CertificateRequest pending list, only one should be queued
CertificateRequestPendingList = make(map[CertificateRequestPendingKey]*CertificateRequestPendingState)
@@ -67,7 +69,7 @@ type CertificateRequestPendingState struct {
const (
SleepTime = 20000 // in time.Millisecond, 20s
- SetStatusErrMsg = "Fail to set status"
+ SetStatusErrMsg = "Failed to set status"
)
/////////////////////////////////////
@@ -142,7 +144,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
secretNamespace = issuerSpec.AuthNamespace
}
- // Check if the MyCRD resource has been marked Ready
+ // Checks if the MyCRD resource has been marked Ready
if !pkiutil.MyCRDHasCondition(*issuerStatus, certmanagerv1.IssuerCondition{
Type: certmanagerv1.IssuerConditionReady,
Status: certmanagerv1.ConditionTrue,
@@ -155,11 +157,11 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, err
}
- // once CRD resource is ready, the config data should be ready
- if NcmConfigSetting == nil || NcmConfigSetting[NcmConfigKey{secretNamespace, issuerName.Name}] == nil {
+ // Once CRD resource is ready, the config data should be ready
+ if NCMConfigMap == nil || NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}] == nil {
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
- "Failed: CRD configuration %s/%s is not Ready; type,status in myCRD.Status.Conditions=%s, conf is nil=%v", secretNamespace, issuerName.Name, issuerStatus.Conditions, NcmConfigSetting)
+ "Failed: CRD configuration %s/%s is not Ready; type,status in myCRD.Status.Conditions=%s, cfg is nil=%v", secretNamespace, issuerName.Name, issuerStatus.Conditions, NCMConfigMap)
if err != nil {
log.Error(err, "Fail to set certificateRequest status")
}
@@ -181,108 +183,158 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- ncmConfigOne := NcmConfigSetting[NcmConfigKey{secretNamespace, issuerName.Name}]
+ ncmCfg := NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}]
+ ncmClient, err := ncmapi.NewClient(ncmCfg, log)
+ if err != nil {
+ log.Error(err, "failed to create NCM API Client")
+
+ err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly, err=%v", err)
+ if err != nil {
+ log.Error(err, "failed to set certificate request status")
+ }
+
+ return ctrl.Result{}, nil
+ }
+
var pemChain []byte
- // the http interface to NCM (netguard certificate manager)
- // to find CA with the external NCM server
- _, err, casInfoTotal := findCa(ncmConfigOne, log)
+ casResponse, err := ncmClient.GetCAs()
if err != nil {
- log.Error(err, "failed find CA")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Check your external NCM server. Failed to find ca: %v", err)
+ log.Error(err, "failed to get CAs")
+
+ err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Please, check your external NCM server. Failed to get CAs: %v", err)
if err != nil {
- log.Error(err, "Fail to set certificateRequest status")
+ log.Error(err, "failed to set certificate request status")
}
- go r.waitCheckFindca(ctx, req, &cr, ncmConfigOne, log)
+
+ go r.waitAndGetCAs(ctx, req, &cr, ncmClient, log)
+
return ctrl.Result{}, nil
}
- // find the certificate for bcmtncm
- casOneNcm := CasOneType{}
-
+ // Finds the certificate for BCMTNCM
+ wantedCA := ncmapi.CAResponse{}
hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
- for _, cas1 := range casInfoTotal.CasoneList {
- if strings.EqualFold(cas1.Status, "active") {
- if ncmConfigOne.CASHREF != "" {
- href := hrefRegex.Find([]byte(cas1.Href))
+ for _, ca := range casResponse.CAList {
+ if strings.EqualFold(ca.Status, "active") {
+ if ncmCfg.CASHREF != "" {
+ href := hrefRegex.Find([]byte(ca.Href))
- if strings.EqualFold(string(href), ncmConfigOne.CASHREF) {
- casOneNcm = cas1
+ if strings.EqualFold(string(href), ncmCfg.CASHREF) {
+ wantedCA = ca
break
}
- } else if strings.EqualFold(cas1.Name, ncmConfigOne.CASNAME) {
- casOneNcm = cas1
+
+ } else if strings.EqualFold(ca.Name, ncmCfg.CASNAME) {
+ wantedCA = ca
break
}
}
}
- if casOneNcm.Href == "" {
- log.Error(err, "CA certificate has not been found. Please check provided CASHREF/CASNAME", "cashref", ncmConfigOne.CASHREF, "casname", ncmConfigOne.CASNAME)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found. Please check provided CASHREF/CASNAME url=%v, CASNAME=%v; CASHREF=%v", ncmConfigOne.NcmSERVER+findCaURL, ncmConfigOne.CASNAME, ncmConfigOne.CASHREF)
+ if wantedCA.Href == "" {
+ log.Error(err, "CA certificate has not been found. Please check provided CASHREF/CASNAME", "cashref", ncmCfg.CASHREF, "casname", ncmCfg.CASNAME)
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found. Please check provided CASHREF/CASNAME url=%v, CASNAME=%v; CASHREF=%v", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- // find the root CA
- casoneInstaCa := CasOneType{}
- lastCa := casOneNcm
+
+ // Finds the root CA
+ instaCA := ncmapi.CAResponse{}
+ lastCA := wantedCA
for {
- log.Info(fmt.Sprintf("lastCa href: %s", lastCa.Href))
- _, err, currentCert := downloadCertificate(lastCa.Certificates["active"], ncmConfigOne, log)
+ log.Info("lastCA href: ", lastCA.Href)
+
+ lastCAURLPath, err := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
+ if err != nil {
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
+
+ return ctrl.Result{}, nil
+ }
+ currentCert, err := ncmClient.DownloadCertificate(lastCAURLPath)
if err != nil {
- log.Error(err, "Failed to download Certificate", "certURL", lastCa.Certificates["active"])
+ log.Error(err, "failed to download Certificate", "certURL", lastCA.Certificates["active"])
+
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: %v", err)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- if lastCa.Href == currentCert.IssuerCa || currentCert.IssuerCa == "" {
+ if lastCA.Href == currentCert.IssuerCA || currentCert.IssuerCA == "" {
break
}
- _, err, currentPem := downloadCertificateInPEM(lastCa.Certificates["active"], ncmConfigOne, log)
+
+ currentCertInPEM, err := ncmClient.DownloadCertificateInPEM(lastCAURLPath)
if err != nil {
- log.Error(err, "failed to download PEM Certificate", "certURL", lastCa.Certificates["active"])
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: err=%v; resp=%v", err, lastCa)
+ log.Error(err, "failed to download PEM Certificate", "certURL", lastCA.Certificates["active"])
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: err=%v; resp=%v", err, lastCA)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- pemChain = appendPem(ncmConfigOne, pemChain, currentPem)
- _, err, lastCa = findOneCa(currentCert.IssuerCa, ncmConfigOne, log)
+ pemChain = appendPem(ncmCfg, pemChain, currentCertInPEM)
+
+ lastCAURLPATH, err := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
if err != nil {
- log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCa)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: err=%v; resp=%v", err, currentCert)
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+
+ return ctrl.Result{}, nil
+ }
+
+ lastCA, err = ncmClient.GetCA(lastCAURLPATH)
+ if err != nil {
+ log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v; resp=%v", err, currentCert)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
}
- if ncmConfigOne.noRoot {
- casoneInstaCa = casOneNcm
- log.Info(fmt.Sprintf("Found Issuer: %s", casoneInstaCa.Name))
+ if ncmCfg.NoRoot {
+ instaCA = wantedCA
+ log.Info("Found Issuer: ", instaCA.Name)
} else {
- casoneInstaCa = lastCa
- log.Info(fmt.Sprintf("Found root CA: %s", casoneInstaCa.Name))
+ instaCA = lastCA
+ log.Info("Found root CA: ", instaCA.Name)
}
- // download rootCA certificate
- _, err, InstaCaInpem := downloadCertificateInPEM(casoneInstaCa.Certificates["active"], ncmConfigOne, log)
+
+ // Downloads root CA certificate
+ instaCAURLPath, err := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
+ if err != nil {
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+
+ return ctrl.Result{}, nil
+ }
+
+ instaCAInPEM, err := ncmClient.DownloadCertificateInPEM(instaCAURLPath)
if err != nil {
log.Error(err, "failed to download ROOT Certificate")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: err=%v; resp=%v", err, InstaCaInpem)
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v; resp=%v", err, instaCAInPEM)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
@@ -295,7 +347,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- var enduserCaInpem []byte
+ var enduserCAInPEM []byte
var secretName = req.Name[:positionToSlice] + "-details"
if crt.Status.Revision != nil {
@@ -304,54 +356,76 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Info("Revision value is set to nil")
}
- secretList, err := r.getSecretList(ctx, req, err)
+ secretList, err := r.getSecretList(ctx, req)
if err != nil {
log.Error(err, "failed to list certificates resources")
+
return ctrl.Result{}, nil
}
- if crt.Status.Revision != nil && *crt.Status.Revision >= 1 && ncmConfigOne.reenrollmentOnRenew != true && pkiutil.FindIfSecretExists(secretList, secretName) && crt.Spec.PrivateKey.RotationPolicy != "Always" {
- // Get saved certificate id
+ if crt.Status.Revision != nil && *crt.Status.Revision >= 1 && !ncmCfg.ReenrollmentOnRenew && pkiutil.FindIfSecretExists(secretList, secretName) && crt.Spec.PrivateKey.RotationPolicy != "Always" {
+ // Gets saved certificate ID
log.Info("A secret with cert-id will be updated...")
secretCertID := core.Secret{}
+
err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID)
if err != nil {
log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret: %v", err)
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
+
log.Info("A certificate href fetched", "href", string(secretCertID.Data["cert-id"]))
- _, err, renewCertificateResp := renewCertificate(*cr.Spec.Duration, string(secretCertID.Data["cert-id"]), issuerSpec.ProfileId, ncmConfigOne, log)
+ certURLPath, err := ncmapi.GetPathFromCertURL(string(secretCertID.Data["cert-id"]))
+ if err != nil {
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+ return ctrl.Result{}, nil
+ }
+
+ renewCertResp, err := ncmClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed to renewCertificate")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renewCertificate: %v, resp=%v", err, renewCertificateResp)
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renewCertificate err=%v, resp=%v", err, renewCertResp)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- // download the renewed certificate
- _, err, enduserCaInpem = downloadCertificateInPEM(renewCertificateResp.Certificate, ncmConfigOne, log)
+ // Downloads the renewed certificate
+ renewedCertURLPath, err := ncmapi.GetPathFromCertURL(renewCertResp.Certificate)
+ if err != nil {
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+
+ return ctrl.Result{}, nil
+ }
+ enduserCAInPEM, err := ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
if err != nil {
- log.Error(err, "failed to download Certificate", "certURL", renewCertificateResp.Certificate)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: %v, resp=%v", err, enduserCaInpem)
+ log.Error(err, "failed to download Certificate", "certURL", renewCertResp.Certificate)
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v, resp=%v", err, enduserCAInPEM)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertificateResp.Certificate)
- err = r.Client.Update(ctx, &secretCertID)
+ secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
+ err = r.Client.Update(ctx, &secretCertID)
if err != nil {
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret: %v", err)
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
@@ -360,102 +434,132 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
} else {
log.Info("A new secret with cert-id will be created...")
- _, err, csrResp2 := sendCSRRequest(cr.Spec.Request, casOneNcm, ncmConfigOne, log, issuerSpec.ProfileId)
+ csrResp, err := ncmClient.SendCSR(cr.Spec.Request, wantedCA, issuerSpec.ProfileId)
if err != nil {
- log.Error(err, "failed send CSR request")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR request: %v, resp=%v, cr.ObjectMeta.name=%v/%v", err, csrResp2, cr.ObjectMeta.Name, cr.ObjectMeta.Namespace)
+ log.Error(err, "failed send CSR")
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR err=%v, resp=%v, cr.ObjectMeta.name=%v/%v", err, csrResp, cr.ObjectMeta.Name, cr.ObjectMeta.Namespace)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- _, err, csrRequestStatusResp3 := checkCsrRequestStatus(csrResp2.Href, ncmConfigOne, log)
+ requestedCertURLPath, err := ncmapi.GetPathFromCertURL(csrResp.Href)
if err != nil {
- log.Error(err, "failed to check CSR request csrRequestStatusResp3")
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+
+ return ctrl.Result{}, nil
+ }
+
+ csrStatusResp, err := ncmClient.CheckCSRStatus(requestedCertURLPath)
+ if err != nil {
+ log.Error(err, "failed to check CSR")
+
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status: %v", err)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- validCsrStatus := CheckCSRStatusResp(csrRequestStatusResp3)
-
- if strings.EqualFold(csrRequestStatusResp3.Status, "pending") {
+ validCSRStatus := checkCSRStatus(csrStatusResp)
+ if strings.EqualFold(csrStatusResp.Status, "pending") {
// save context: enqueue ( req, cr ) into job
//
// start new go route to do:
// 1. check csr status
// 2. download Certificate if it is accepted
// 3. take 1 again if it is pending
- validCsrStatus = true
+ validCSRStatus = true
- log.Error(err, "CSR request status is pending")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to snd check CSR status: %v", err)
+ log.Error(err, "CSR status is pending")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to snd check CSR status err=%v", err)
- go r.waitCheckCSRrequestStatus(ctx, req, &cr, ncmConfigOne, log, &csrResp2)
+ go r.waitAndCheckCSRStatus(ctx, req, &cr, ncmClient, requestedCertURLPath, log)
return ctrl.Result{}, nil
}
- if validCsrStatus == false {
+ if !validCSRStatus {
log.Error(err, "Invalid CSR Status")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid Csr Status. err=%v, status=%v, cr.meta=%v", err, csrRequestStatusResp3.Status, cr.ObjectMeta)
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid Csr Status. err=%v, status=%v, cr.meta=%v", err, csrStatusResp.Status, cr.ObjectMeta)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- // download certificate ascsrRequestStatusResp3.Certificate
- _, err, enduserCaInpem = downloadCertificateInPEM(csrRequestStatusResp3.Certificate, ncmConfigOne, log)
+ // Downloads certificate as csrRequestStatusResp3.Certificate
+ enduserCAURLPath, err := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
if err != nil {
- log.Error(err, "failed to download Certificate", "certURL", csrRequestStatusResp3.Certificate)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: %v, tmp_enduser_ca_InPEM=%v", err, enduserCaInpem)
+ log.Error(err, "failed to get certificate URL path needed for request")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+
+ return ctrl.Result{}, nil
+ }
+
+ enduserCAInPEM, err := ncmClient.DownloadCertificateInPEM(enduserCAURLPath)
+ if err != nil {
+ log.Error(err, "failed to download Certificate", "certURL", csrStatusResp.Certificate)
+
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v, tmp_enduser_ca_InPEM=%v", err, enduserCAInPEM)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
- // save cert-id to secret
+ // Saves cert-id to secret
if pkiutil.FindIfSecretExists(secretList, secretName) {
secretCertID := core.Secret{}
- secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, csrRequestStatusResp3.Certificate)
+ secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, csrStatusResp.Certificate)
err = r.Client.Update(ctx, &secretCertID)
} else {
- err = r.createSecret(ctx, req.Namespace, secretName, csrRequestStatusResp3.Certificate)
+ err = r.createSecret(ctx, req.Namespace, secretName, csrStatusResp.Certificate)
}
+
if err != nil {
log.Error(err, "failed to create/update a secret with cert-id", "secretName", secretName)
+
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create/update secret: %v", err)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, nil
}
}
+
log.Info("Storing PEM...")
- // Store the signed certificate data in the status
- if ncmConfigOne.littleEndianPem {
- pemChain = append(pemChain, enduserCaInpem...)
+
+ // Stores the signed certificate data in the status
+ if ncmCfg.LittleEndianPem {
+ pemChain = append(pemChain, enduserCAInPEM...)
} else {
- pemChain = append(enduserCaInpem, pemChain...)
+ pemChain = append(enduserCAInPEM, pemChain...)
}
- // set pems
+
+ // Set PEMs
cr.Status.Certificate = pemChain
- cr.Status.CA = InstaCaInpem
+ cr.Status.CA = instaCAInPEM
// Finally, update the status
return ctrl.Result{}, r.setStatus(ctx, &cr, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Successfully issued certificate")
}
-func (r *CertificateRequestReconciler) getSecretList(ctx context.Context, req ctrl.Request, err error) (core.SecretList, error) {
+func (r *CertificateRequestReconciler) getSecretList(ctx context.Context, req ctrl.Request) (core.SecretList, error) {
secretList := core.SecretList{}
options := client.ListOptions{Namespace: req.Namespace}
- err = r.Client.List(ctx, &secretList, &options)
+ err := r.Client.List(ctx, &secretList, &options)
+
return secretList, err
}
@@ -466,44 +570,49 @@ func (r *CertificateRequestReconciler) createSecret(ctx context.Context, namespa
return err
}
-func appendPem(ncmConfigOne *NcmConfig, pemChain []byte, currentPem []byte) []byte {
- if ncmConfigOne.littleEndianPem {
+func appendPem(cfg *ncmapi.NCMConfig, pemChain []byte, currentPem []byte) []byte {
+ if cfg.LittleEndianPem {
pemChain = append(currentPem, pemChain...)
} else {
pemChain = append(pemChain, currentPem...)
}
+
return pemChain
}
func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.CertificateRequest, status cmmeta.ConditionStatus, reason, message string, args ...interface{}) error {
- // Format the message and update the myCRD variable with the new Condition
+ // Formats the message and updates the myCRD variable with the new Condition
completeMessage := fmt.Sprintf(message, args...)
apiutil.SetCertificateRequestCondition(cr, cmapi.CertificateRequestConditionReady, status, reason, completeMessage)
- // Fire an Event to additionally inform users of the change
+ // Fires an Event to additionally inform users of the change
eventType := core.EventTypeNormal
if status == cmmeta.ConditionFalse {
eventType = core.EventTypeWarning
}
+
r.Recorder.Event(cr, eventType, reason, completeMessage)
r.Log.Info(completeMessage)
- // updating the status
+ // Updates the status
var err error
if updateErr := r.Status().Update(ctx, cr); updateErr != nil {
err = utilerrors.NewAggregate([]error{err, updateErr})
+
return err
}
+
return nil
}
-//////////////////////////////////////
-// wait and frequently check if the NCM external server is ready
-// when it is ready, trigger new round of reconcile
-func (r *CertificateRequestReconciler) waitCheckFindca(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, ncmConfigOne *NcmConfig, log logr.Logger) {
+// ////////////////////////////////////
+
+// Waits and frequently checks to see if the NCM server is responding (NCM API client tries to get CAs).
+// When the server responds to a request for CAs triggers new round of reconcile
+func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, client *ncmapi.Client, log logr.Logger) {
CrPendingKey := CertificateRequestPendingKey{cr.ObjectMeta.Namespace, cr.ObjectMeta.Name}
- inFuncStr := "waitCheckFindca"
+ inFuncStr := "waitAndGetCAs"
if CertificateRequestPendingList != nil && CertificateRequestPendingList[CrPendingKey] != nil {
nowTime := metav1.NewTime(r.Clock.Now())
@@ -512,6 +621,7 @@ func (r *CertificateRequestReconciler) waitCheckFindca(ctx context.Context, req
}
// multiple revoke CertificateRequestReconciler, do nothing
log.Info("multiple revoke CertificateRequestReconciler, do nothing ", "time", nowTime.Time)
+
return
}
@@ -529,21 +639,24 @@ func (r *CertificateRequestReconciler) waitCheckFindca(ctx context.Context, req
// Fetch the CertificateRequest resource that was being synced
newcr := cmapi.CertificateRequest{}
if err := r.Client.Get(ctx, req.NamespacedName, &newcr); err != nil {
- log.Error(err, "failed to retrieve CertificateRequest resource while in waitCheckFindca, take no more waiting")
+ log.Error(err, "failed to retrieve CertificateRequest resource while in waitAndGetCAs. Wait no longer")
CertificateRequestPendingList[CrPendingKey] = nil
+
return
}
- // check to find CA with the external NCM server
- if _, err, _ := findCa(ncmConfigOne, log); err != nil {
- log.Error(err, "failed find CA")
+ // Checks if NCM server is responding to a request
+ _, err := client.GetCAs()
+ if err != nil {
+ log.Error(err, "failed to get CAs")
} else {
- log.Info(inFuncStr, "time", nowTime.Time, "OK", "find the NCM external server ")
+ log.Info(inFuncStr, "time", nowTime.Time, "OK", "NCM external server is responding")
- // update new Certifier status change, which trigger new round of reconcile
- // status is updated from CertificateRequestReasonPending to CertificateRequestReasonFailed
+ // Updates new Certifier status change, which triggers new round of reconcile
+ // Status is updated from CertificateReasonPending to CertificateRequestReasonFailed
CertificateRequestPendingList[CrPendingKey] = nil
- _ = r.setStatus(ctx, &newcr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now the external NCM server is OK to find.")
+
+ _ = r.setStatus(ctx, &newcr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now the external NCM server is ready to get CAs")
break
}
@@ -551,20 +664,21 @@ func (r *CertificateRequestReconciler) waitCheckFindca(ctx context.Context, req
}
-// wait and frequently check if the check CSRrequest Status is 'accepted'
-// when it is ready, trigger new round of reconcile
-func (r *CertificateRequestReconciler) waitCheckCSRrequestStatus(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, ncmConfigOne *NcmConfig, log logr.Logger, csrResp2 *CsrRespType) {
+// Waits and frequently checks if the CSR status is 'accepted'.
+// When CSR status is accepted triggers new round fo reconcile
+func (r *CertificateRequestReconciler) waitAndCheckCSRStatus(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, c *ncmapi.Client, requestedCertURLPath string, log logr.Logger) {
CrPendingKey := CertificateRequestPendingKey{cr.ObjectMeta.Namespace, cr.ObjectMeta.Name}
- inFuncStr := "waitCheckCSRrequestStatus"
+ inFuncStr := "waitAndCheckCSRStatus"
if CertificateRequestPendingList != nil && CertificateRequestPendingList[CrPendingKey] != nil {
nowTime := metav1.NewTime(r.Clock.Now())
-
if CertificateRequestPendingList[CrPendingKey].InState != inFuncStr {
- log.Info("!! multiple revoke CertificateRequestReconciler but status is not waitCheckCSRrequestStatus", "time", nowTime.Time)
+ log.Info("!! multiple revoke CertificateRequestReconciler but status is not waitAndCheckCSRStatus", "time", nowTime.Time)
}
+
// multiple revoke CertificateRequestReconciler, do nothing
log.Info("multiple revoke CertificateRequestReconciler, do nothing ", "time", nowTime.Time)
+
return
}
@@ -583,27 +697,29 @@ func (r *CertificateRequestReconciler) waitCheckCSRrequestStatus(ctx context.Con
newcr := cmapi.CertificateRequest{}
if err := r.Client.Get(ctx, req.NamespacedName, &newcr); err != nil {
CertificateRequestPendingList[CrPendingKey] = nil
- log.Error(err, "failed to retrieve CertificateRequest resource while in waitCheckCSRrequestStatus, take no more waiting")
+ log.Error(err, "failed to retrieve CertificateRequest resource while in waitAndCheckCSRStatus. Wait no longer")
+
return
}
- // check to check CSRrequest Status
- _, err, csrRequestStatusResp3 := checkCsrRequestStatus(csrResp2.Href, ncmConfigOne, log)
+ // Checks the CSR status
+ csrStatusResp, err := c.CheckCSRStatus(requestedCertURLPath)
if err != nil {
- log.Info("failed to check CSR request csrRequestStatusResp3")
+ log.Error(err, "failed to check CSR status")
} else {
- if strings.EqualFold(csrRequestStatusResp3.Status, "accepted") {
- // continue to trigger new round CSR
- log.Info(inFuncStr, "time", nowTime.Time, "OK", "CSR request status is accepted")
+ if strings.EqualFold(csrStatusResp.Status, "accepted") {
+ // Continues to trigger new round CSR
+ log.Info(inFuncStr, "time", nowTime.Time, "OK", "CSR status is accepted")
- // update new CertificateRequest status change, which trigger new round of reconcile
- // status is updated from CertificateRequestReasonPending to CertificateRequestReasonFailed
+ // Updates new CertificateRequest status change, which trigger new round of reconcile
+ // Status is updated from CertificateRequestReasonPending to CertificateRequestReasonFailed
CertificateRequestPendingList[CrPendingKey] = nil
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now CSR request status is OK")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now CSR status is OK")
+
break
}
- // testCntCheckCSRrequestStatus++
- if strings.EqualFold(csrRequestStatusResp3.Status, "pending") {
+
+ if strings.EqualFold(csrStatusResp.Status, "pending") {
log.Info("CSR request status is still pending")
}
}
@@ -616,11 +732,6 @@ func (r *CertificateRequestReconciler) SetupWithManager(mgr ctrl.Manager) error
Complete(r)
}
-func CheckCSRStatusResp(csrRequestStatusResp3 CsrRequestStatusRespType) bool {
- validCsrStatus := false
-
- if strings.EqualFold(csrRequestStatusResp3.Status, "accepted") {
- validCsrStatus = true
- }
- return validCsrStatus
+func checkCSRStatus(csrStatusResp ncmapi.CSRStatusResponse) bool {
+ return strings.EqualFold(csrStatusResp.Status, "accepted")
}
diff --git a/pkg/controllers/httputil.go b/pkg/controllers/httputil.go
deleted file mode 100644
index 2e660ed..0000000
--- a/pkg/controllers/httputil.go
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package controllers http utilities function
-package controllers
-
-import (
- "bytes"
- "crypto/tls"
- "crypto/x509"
- "encoding/json"
- "fmt"
- "github.com/go-logr/logr"
- "io"
- "io/ioutil"
- "mime/multipart"
- "net/http"
- "net/url"
- "os"
- "path/filepath"
- "strings"
- "time"
-)
-
-const (
- HTTPTimeout = 10
-)
-
-type ErrorReturn struct {
- ErrorSlug string `json:"error_slug"`
- Error string `json:"error"`
-}
-
-type GetTokenErr struct{}
-
-func (_ *GetTokenErr) Error() string {
- return "fail to get token"
-}
-
-// make http NewRequest
-func makeHttpNewRequest(method string, uri string, ncmConfigOne *NcmConfig) (*http.Request, error) {
-
- data := url.Values{}
-
- req, err := http.NewRequest(method, uri, strings.NewReader(data.Encode()))
- if err != nil {
- return nil, err
- }
- req.SetBasicAuth(ncmConfigOne.Username, ncmConfigOne.UsrPassword)
-
- req.Header.Set("Accept", "application/json")
- req.Header.Set("Accept-Language", "en_US")
-
- return req, err
-}
-
-// configure http Client by NcmConfig
-func configureHttpClient(ncmConfigOne *NcmConfig) (*http.Client, error) {
-
- var client *http.Client
-
- if strings.HasPrefix(ncmConfigOne.NcmSERVER, "https:") {
- var tlsConfig *tls.Config
-
- if ncmConfigOne.InsecureSkipVerify == true {
- tlsConfig = &tls.Config{InsecureSkipVerify: true}
- } else {
- caCertPool := x509.NewCertPool()
- caCertPool.AppendCertsFromPEM([]byte(ncmConfigOne.Cacert))
-
- if ncmConfigOne.Mtls == true {
- // Read the key pair for client certificate
- clientcert, err := tls.LoadX509KeyPair(ncmConfigOne.Cert, ncmConfigOne.Key)
- if err != nil {
- return client, err
- }
-
- // Create an HTTPS client and supply the created CA pool and client CA
- tlsConfig = &tls.Config{RootCAs: caCertPool,
- Certificates: []tls.Certificate{clientcert},
- }
- } else {
-
- // Create an HTTPS client and supply the created CA pool
- tlsConfig = &tls.Config{RootCAs: caCertPool}
- }
- }
-
- transport := &http.Transport{TLSClientConfig: tlsConfig}
-
- client = &http.Client{
- Timeout: HTTPTimeout * time.Second,
- Transport: transport,
- }
- } else {
- // The timeout to 10 seconds, which gives it enough time to connect and get a response.
- client = &http.Client{
- Timeout: HTTPTimeout * time.Second,
- }
- }
- return client, nil
-}
-
-// http Client Do(req)
-func doHttpRequest(req *http.Request, ncmConfigOne *NcmConfig) (*http.Response, error) {
-
- client, err := configureHttpClient(ncmConfigOne)
- if err != nil {
- return nil, err
- }
-
- response, err := client.Do(req)
- if err != nil {
- return nil, err
- }
-
- return response, err
-}
-
-// Creates a new file upload http request with optional extra params
-func newPostRequestWithFile(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
- file, err := os.Open(path)
- if err != nil {
- // return nil, err, "no such file"
- return nil, err
- }
- defer file.Close()
-
- body := &bytes.Buffer{}
- writer := multipart.NewWriter(body)
- part, err := writer.CreateFormFile(paramName, filepath.Base(path))
- if err != nil {
- // return nil, err, "error in writer.CreateFormFile"
- return nil, err
- }
- _, err = io.Copy(part, file)
-
- for key, val := range params {
- _ = writer.WriteField(key, val)
- }
- err = writer.Close()
- if err != nil {
- // return nil, err, "error in writer.Close"
- return nil, err
- }
-
- req, err := http.NewRequest("POST", uri, body)
- req.Header.Set("Content-Type", writer.FormDataContentType())
- if err != nil {
- // log.V(1).Info("http.NewRequest POST err=", err)
- // log.V(1).Info("http.NewRequest POST reader= jsonValue=", reader, jsonValue)
- // return nil, err, "http.NewRequest POST err"
- return nil, err
- }
- return req, err
-}
-
-// FailResponseInfo printout the failed response
-func FailResponseInfo(response *http.Response, log logr.Logger) error {
- var p []byte
- var errorInfo ErrorReturn
- var err error
-
- p, err = ioutil.ReadAll(response.Body)
-
- if err != nil {
- log.Error(err, "failed to read response")
- return err
- }
-
- log.Info("Fail", "Http Response", string(p))
- err = json.Unmarshal(p, &errorInfo)
-
- if err != nil {
- log.Error(err, "failed to unmarshal error info")
- return err
- }
- fmt.Printf("Error_slug = '%s', Error = '%s'\n", errorInfo.ErrorSlug, errorInfo.Error)
- return nil
-}
-
-// check and print Failed resp
-// if 2xx, decode resp.body
-func getGoodResponseBody(response *http.Response, log logr.Logger) ([]byte, error) {
- var result []byte
-
- if response.StatusCode >= 200 && response.StatusCode <= 299 {
- body, err := ioutil.ReadAll(response.Body)
- if err != nil {
- log.V(1).Info("http Post body =", string(body), err)
- return result, err
- }
-
- return body, nil
-
- } else {
- log.V(1).Info("failed response status code")
- err := FailResponseInfo(response, log)
- return result, err
- }
-}
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index 35c8051..ced6f18 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -20,8 +20,11 @@ import (
"context"
"errors"
"fmt"
+ "strings"
+
"github.com/go-logr/logr"
certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
"github.com/nokia/ncm-issuer/pkg/pkiutil"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -32,7 +35,6 @@ import (
"k8s.io/utils/clock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
- "strings"
)
// IssuerReconciler reconciles a Issuer object
@@ -54,33 +56,9 @@ func (r *IssuerReconciler) newIssuer() (client.Object, error) {
return ro.(client.Object), nil
}
-// NcmConfig NCM config setting from the secret
-type NcmConfig struct {
- Username string
- UsrPassword string
- NcmSERVER string
- CASNAME string // cas for bcmtncm
- CASHREF string // href for bcmtncm
- reenrollmentOnRenew bool
- useProfileIDForRenew bool
- INSTA_CA string // NCM root CA
- littleEndianPem bool // bigEndian or littleEndian: bE Cert->issuers, lE issuers->cert
- noRoot bool // Issuer of the Cert instead of root
- Cacert string // tls Cacert
- Key string // tls client Key
- Cert string // tls client Cert
- InsecureSkipVerify bool // tls: InsecureSkipVerify
- Mtls bool // Mtls is enabled
-}
-
-type NcmConfigKey struct {
- Namespace string
- Name string
-}
-
var (
- // NcmConfigSetting : for each certifier, NCM config setting from the secret
- NcmConfigSetting = make(map[NcmConfigKey]*NcmConfig)
+ // NCMConfigMap : for each certifier, NCM config set up with the secret
+ NCMConfigMap = make(map[ncmapi.NCMConfigKey]*ncmapi.NCMConfig)
)
//+kubebuilder:rbac:groups=certmanager.ncm.nokia.com,resources=issuers;clusterissuers,verbs=get;list;watch;create;update;patch;delete
@@ -151,21 +129,25 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}
- conf := NcmConfig{}
- populateNCMConfData(&caSecret, &conf)
- conf.NcmSERVER = issuerSpec.NcmSERVER
- // if end with '/', remove it
- conf.NcmSERVER = strings.TrimSuffix(conf.NcmSERVER, "/")
- conf.CASNAME = issuerSpec.CASNAME
- conf.CASHREF = issuerSpec.CASHREF
- conf.INSTA_CA = issuerSpec.CASNAME
- conf.littleEndianPem = issuerSpec.LittleEndian
- conf.reenrollmentOnRenew = issuerSpec.ReenrollmentOnRenew
- conf.useProfileIDForRenew = issuerSpec.UseProfileIDForRenew
- conf.noRoot = issuerSpec.NoRoot
+ cfg := ncmapi.NCMConfig{}
+ populateNCMConfData(&caSecret, &cfg)
+
+ // in case suffix "/" is present removes it
+ cfg.NcmSERVER = strings.TrimSuffix(issuerSpec.NcmSERVER, "/")
+ if issuerSpec.NcmSERVER2 != "" {
+ cfg.NcmSERVER2 = strings.TrimSuffix(issuerSpec.NcmSERVER2, "/")
+ }
+
+ cfg.CASNAME = issuerSpec.CASNAME
+ cfg.CASHREF = issuerSpec.CASHREF
+ cfg.InstaCA = issuerSpec.CASNAME
+ cfg.LittleEndianPem = issuerSpec.LittleEndian
+ cfg.ReenrollmentOnRenew = issuerSpec.ReenrollmentOnRenew
+ cfg.UseProfileIDForRenew = issuerSpec.UseProfileIDForRenew
+ cfg.NoRoot = issuerSpec.NoRoot
///////////////////////
- conf.InsecureSkipVerify = true
+ cfg.InsecureSkipVerify = true
if issuerSpec.TlsSecretName != "" {
// Fetch the ncm tls Secret
tlsConfSecret := core.Secret{}
@@ -175,7 +157,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
log.Error(err, "failed to retrieve tls Secret")
return ctrl.Result{}, err
}
- err = populateNCMTLSConfData(&tlsConfSecret, &conf)
+ err = populateNCMTLSConfData(&tlsConfSecret, &cfg)
if err != nil {
reason = "incorrect TLS setting"
completeMessage = fmt.Sprintf("TLS secret config setting population is incorrect: %v", err)
@@ -183,8 +165,9 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}
}
- ncmConfigKey := NcmConfigKey{secretName.Namespace, req.NamespacedName.Name}
- NcmConfigSetting[ncmConfigKey] = &conf
+
+ cfgKey := ncmapi.NCMConfigKey{secretName.Namespace, req.NamespacedName.Name}
+ NCMConfigMap[cfgKey] = &cfg
reason = "Verified"
completeMessage = "Signing CA verified and ready to issue certificates"
condition = certmanagerv1.ConditionTrue
@@ -193,13 +176,13 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}
// setMyCRDCondition will set a 'condition' on the given MyCRD.
-// - If no condition of the same type already exists, the condition will be
-// inserted with the LastTransitionTime set to the current time.
-// - If a condition of the same type and state already exists, the condition
-// will be updated but the LastTransitionTime will not be modified.
-// - If a condition of the same type and different state already exists, the
-// condition will be updated and the LastTransitionTime set to the current
-// time.
+// - If no condition of the same type already exists, the condition will be
+// inserted with the LastTransitionTime set to the current time.
+// - If a condition of the same type and state already exists, the condition
+// will be updated but the LastTransitionTime will not be modified.
+// - If a condition of the same type and different state already exists, the
+// condition will be updated and the LastTransitionTime set to the current
+// time.
func (r *IssuerReconciler) setMyCRDCondition(issuerStatus *certmanagerv1.IssuerStatus, status certmanagerv1.ConditionStatus, reason, message string) {
newCondition := &certmanagerv1.IssuerCondition{
Type: certmanagerv1.IssuerConditionReady,
@@ -238,6 +221,7 @@ func (r *IssuerReconciler) setMyCRDStatus(ctx context.Context, issuer client.Obj
var err error
completeMessage := fmt.Sprintf(message, args...)
var issuerStatus *certmanagerv1.IssuerStatus
+
switch t := issuer.(type) {
case *certmanagerv1.Issuer:
issuerStatus = &t.Status
@@ -246,6 +230,7 @@ func (r *IssuerReconciler) setMyCRDStatus(ctx context.Context, issuer client.Obj
default:
r.Log.Info("Foreign type ", t)
}
+
r.setMyCRDCondition(issuerStatus, conditionStatus, reason, completeMessage)
// Fire an Event to additionally inform users of the change
@@ -262,66 +247,72 @@ func (r *IssuerReconciler) setMyCRDStatus(ctx context.Context, issuer client.Obj
return err
}
-// check if all the needed data are configured correctly
+// Checks if all the needed data are configured correctly
func checkNCMSecretData(s *core.Secret) error {
if s.Data == nil {
return fmt.Errorf("no setting found in secret %s/%s", s.Namespace, s.Name)
}
+
errMsg := ""
- // check the setting
+ // Checks the setting
if s.Data["username"] == nil {
errMsg += "username is needed; "
}
+
if s.Data["usrPassword"] == nil {
errMsg += "usrPassword is needed"
}
+
if errMsg != "" {
return fmt.Errorf("wrong auth secret %s/%s setting, error: %s", s.Namespace, s.Name, errMsg)
}
+
return nil
}
// populate all the needed config data from the secret
-func populateNCMConfData(s *core.Secret, cf *NcmConfig) {
+func populateNCMConfData(s *core.Secret, cfg *ncmapi.NCMConfig) {
if s.Data["username"] != nil {
- cf.Username = string(s.Data["username"])
+ cfg.Username = string(s.Data["username"])
}
+
if s.Data["usrPassword"] != nil {
- cf.UsrPassword = string(s.Data["usrPassword"])
+ cfg.UsrPassword = string(s.Data["usrPassword"])
}
}
// populate all the needed tls configure data from the tlsConfSecret
-func populateNCMTLSConfData(tlsConfSecret *core.Secret, conf *NcmConfig) error {
+func populateNCMTLSConfData(tlsConfSecret *core.Secret, cfg *ncmapi.NCMConfig) error {
- conf.Cacert = string(tlsConfSecret.Data["cacert"])
+ cfg.CACert = string(tlsConfSecret.Data["cacert"])
if string(tlsConfSecret.Data["key"]) != "" {
- keyPath, err := writePemToTempFile("/tmp/clientkey", tlsConfSecret.Data["key"])
+ keyPath, err := ncmapi.WritePemToTempFile("/tmp/clientkey", tlsConfSecret.Data["key"])
if err != nil {
return err
}
- conf.Key = keyPath
+ cfg.Key = keyPath
}
+
if string(tlsConfSecret.Data["cert"]) != "" {
- certPath, err := writePemToTempFile("/tmp/clientcert", tlsConfSecret.Data["cert"])
+ certPath, err := ncmapi.WritePemToTempFile("/tmp/clientcert", tlsConfSecret.Data["cert"])
if err != nil {
return err
}
- conf.Cert = certPath
+ cfg.Cert = certPath
}
- conf.InsecureSkipVerify = true
- if conf.Cacert != "" {
- conf.InsecureSkipVerify = false
+ cfg.InsecureSkipVerify = true
+ if cfg.CACert != "" {
+ cfg.InsecureSkipVerify = false
}
- conf.Mtls = false
- if conf.Key != "" && conf.Cert != "" {
- conf.Mtls = true
+ cfg.MTLS = false
+ if cfg.Key != "" && cfg.Cert != "" {
+ cfg.MTLS = true
}
- if conf.Cacert == "" && conf.Key == "" && conf.Cert == "" {
+ if cfg.CACert == "" && cfg.Key == "" && cfg.Cert == "" {
return fmt.Errorf("no useful data cacert, key or cert in Ttls secret")
}
@@ -333,9 +324,11 @@ func checkIssuerSpec(issuerSpec *certmanagerv1.IssuerSpec) string {
if len(issuerSpec.NcmSERVER) == 0 {
invalidStr = "The ncmSERVER should not be empty. "
}
+
if len(issuerSpec.CASNAME) == 0 && len(issuerSpec.CASHREF) == 0 {
invalidStr += "The CASNAME or CASHREF should not be empty."
}
+
return invalidStr
}
@@ -345,6 +338,7 @@ func (r *IssuerReconciler) SetupWithManager(mgr ctrl.Manager) error {
if err != nil {
return err
}
+
return ctrl.NewControllerManagedBy(mgr).
For(issuerType).
Complete(r)
diff --git a/pkg/controllers/ncm_controller.go b/pkg/controllers/ncm_controller.go
deleted file mode 100644
index 7ee8446..0000000
--- a/pkg/controllers/ncm_controller.go
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package controllers
-
-import (
- "crypto/rand"
- "encoding/json"
- "fmt"
- "github.com/go-logr/logr"
- "io"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "net/http"
- "os"
- "strings"
- "time"
-)
-
-// const URL
-const (
- findCaURL = "/v1/cas"
- sendCSRequestURL = "/v1/requests"
-)
-
-type CasType struct {
- TotalCount int `json:"totalCount"`
- Href string `json:"href"`
- CasoneList []CasOneType `json:"cas"`
-}
-
-type CasOneType struct {
- Href string `json:"href"`
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
- Status string `json:"status"`
- Type string `json:"type,omitempty"`
- Certificates map[string]string `json:"certificates"`
-}
-
-type CsrRespType struct {
- Href string `json:"href"`
- Issuer string `json:"issuer"`
- Certificate string `json:"certificate"`
- CertificateBase64 string `json:"certificateBase64"`
-}
-
-type CsrRequestStatusRespType struct {
- Href string `json:"href"`
- Issuer string `json:"issuer"`
- Certificate string `json:"certificate"`
- Status string `json:"status"`
-}
-
-type CertificateDownloadRespType struct {
- Href string `json:"href"`
- Request string `json:"request"`
- IssuerCa string `json:"issuerCa"`
- IssuedTime *metav1.Time `json:"issuedTime,omitempty"`
- Type string `json:"type"`
- Status string `json:"status"`
- CertificateBase64 string `json:"certificateBase64"`
-}
-
-type renewCertificateRespType struct {
- Result string `json:"result"`
- Request string `json:"request,omitempty"`
- Certificate string `json:"certificate"`
-}
-
-// newUUID generates a random UUID according to RFC 4122
-func newUUID() (string, error) {
- uuid := make([]byte, 16)
- n, err := io.ReadFull(rand.Reader, uuid)
- if n != len(uuid) || err != nil {
- return "", err
- }
- // variant bits; see section 4.1.1
- uuid[8] = uuid[8]&^0xc0 | 0x80
- // version 4 (pseudo-random); see section 4.1.3
- uuid[6] = uuid[6]&^0xf0 | 0x40
- return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
-}
-
-// write pem to temp file (dirprefix is dir prefix)
-func writePemToTempFile(dirprefix string, perm []byte) (string, error) {
- myuuid, err := newUUID()
- if err != nil {
- return "", err
- }
-
- // path := "/tmp/ncm_new.pem"
- path := dirprefix + myuuid + ".pem"
-
- // write CSRPEM into csrfile
- csrfile, err := os.Create(path)
- if err != nil {
- // return nil, err, "no such file"
- return path, err
- }
- _, err = csrfile.Write(perm)
- if err != nil {
- // return nil, err, "err to write file"
- return path, err
- }
- csrfile.Sync()
- csrfile.Close()
-
- return path, err
-}
-
-// find and get cas list: root CA and bcmtncm CA
-func findCa(ncmConfigOne *NcmConfig, log logr.Logger) (bool, error, CasType) {
- var err error
-
- casinfo := CasType{}
- result := CasType{}
-
- req, err := makeHttpNewRequest("GET", ncmConfigOne.NcmSERVER+findCaURL, ncmConfigOne)
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- return false, err, result
- }
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in find CA")
- return false, err, result
- }
-
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in find CA"), result
- }
-
- err = json.Unmarshal(body, &casinfo)
- if err != nil {
- log.V(1).Info("json.Unmarshal =", string(body), err)
- return false, err, result
- }
-
- result = casinfo
- return false, nil, result
-}
-func findOneCa(downloadCaURL string, ncmConfigOne *NcmConfig, log logr.Logger) (bool, error, CasOneType) {
- var err error
-
- casinfo := CasOneType{}
- result := CasOneType{}
-
- req, err := makeHttpNewRequest("GET", downloadCaURL, ncmConfigOne)
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- return false, err, result
- }
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in find CA")
- return false, err, result
- }
-
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in find CA"), result
- }
-
- err = json.Unmarshal(body, &casinfo)
- if err != nil {
- log.V(1).Info("json.Unmarshal =", string(body), err)
- return false, err, result
- }
-
- result = casinfo
- return false, nil, result
-}
-
-func sendCSRRequest(pem []byte, cas1 CasOneType, ncmConfigOne *NcmConfig, log logr.Logger, profileId string) (bool, error, CsrRespType) {
- var err error
- result := CsrRespType{}
-
- path, err := writePemToTempFile("/tmp/ncm", pem)
- if err != nil {
- return false, err, result
- }
-
- paramName := "pkcs10"
- extraParams := map[string]string{
- "ca": cas1.Href,
- }
-
- if profileId != "" {
- extraParams["profileId"] = profileId
- }
-
- req, err := newPostRequestWithFile(ncmConfigOne.NcmSERVER+sendCSRequestURL, extraParams, paramName, path)
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- return false, err, result
- }
-
- req.SetBasicAuth(ncmConfigOne.Username, ncmConfigOne.UsrPassword)
-
- req.Header.Set("Accept", "application/json")
- req.Header.Set("Accept-Language", "en_US")
-
- // remove the temp pem file
- err = os.Remove(path)
- if err != nil {
- // return nil, err, "no such file"
- return false, err, result
- }
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in sendCSRRequest")
- return false, err, result
- }
-
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in sendCSRRequest"), result
- }
-
- err = json.Unmarshal(body, &result)
- if err != nil {
- log.V(1).Info("json.Unmarshal body =", string(body), err)
- return false, err, result
- }
-
- return false, nil, result
-}
-
-func checkCsrRequestStatus(checkCSRrequestStatusURL string, ncmConfigOne *NcmConfig, log logr.Logger) (bool, error, CsrRequestStatusRespType) {
- var err error
- result := CsrRequestStatusRespType{}
-
- req, err := makeHttpNewRequest("GET", checkCSRrequestStatusURL, ncmConfigOne)
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- return false, err, result
- }
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in checkCsrRequestStatus")
- return false, err, result
- }
-
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in checkCsrRequestStatus"), result
- }
-
- err = json.Unmarshal(body, &result)
- if err != nil {
- log.V(1).Info("json.Unmarshal body =", string(body), err)
- return false, err, result
- }
-
- return false, nil, result
-}
-
-func downloadCertificate(downloadCertificateURL string, ncmConfigOne *NcmConfig, log logr.Logger) (bool, error, CertificateDownloadRespType) {
- var err error
- result := CertificateDownloadRespType{}
-
- req, err := makeHttpNewRequest("GET", downloadCertificateURL, ncmConfigOne)
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- return false, err, result
- }
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in downloadCertificate")
- return false, err, result
- }
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in downloadCertificate"), result
- }
-
- err = json.Unmarshal(body, &result)
- if err != nil {
- log.V(1).Info("json.Unmarshal body =", string(body), err)
- return false, err, result
- }
-
- return false, nil, result
-
-}
-
-func downloadCertificateInPEM(downloadCertificateURL string, ncmConfigOne *NcmConfig, log logr.Logger) (bool, error, []byte) {
- var err error
- var result []byte
-
- req, err := makeHttpNewRequest("GET", downloadCertificateURL, ncmConfigOne)
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- return false, err, result
- }
-
- req.Header.Set("Accept", "application/x-pem-file")
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in downloadCertificateInPEM")
- return false, err, result
- }
-
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in downloadCertificateInPEM"), result
- }
-
- result = body
-
- return false, nil, result
-}
-
-// Update/renew a certificate of 'cert', renewCertificateURL is url to update
-func renewCertificate(certDuration metav1.Duration, renewCertificateURL string, profileID string, ncmConfigOne *NcmConfig, log logr.Logger) (bool, error, renewCertificateRespType) {
- var err error
- result := renewCertificateRespType{}
- newData := make(map[string]string)
-
- notBefore := time.Now()
- notAfter := notBefore.Add(certDuration.Duration)
-
- newData["notBefore"] = notBefore.Format(time.RFC3339Nano)
- newData["notAfter"] = notAfter.Format(time.RFC3339Nano)
- if ncmConfigOne.useProfileIDForRenew == true {
- newData["profileID"] = profileID
- }
-
- jsonData, _ := json.Marshal(&newData)
-
- req, err := http.NewRequest("POST", renewCertificateURL+"/update", strings.NewReader(string(jsonData)))
-
- if err != nil {
- log.V(1).Info("http.NewRequest POST err=", err)
- // log.V(1).Info("http.NewRequest POST reader= jsonValue=", reader, jsonValue)
- // log.Fatal(err)
- return false, err, result
- }
-
- req.SetBasicAuth(ncmConfigOne.Username, ncmConfigOne.UsrPassword)
-
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Accept", "application/json")
- req.Header.Set("Accept-Language", "en_US")
-
- response, err := doHttpRequest(req, ncmConfigOne)
- if err != nil {
- log.Error(err, "failed to doHttpRequest in renewCertificate")
- return false, err, result
- }
-
- defer response.Body.Close()
-
- body, err := getGoodResponseBody(response, log)
- if err != nil || len(body) == 0 {
- return false, fmt.Errorf("failed response in renewCertificate"), result
- }
-
- err = json.Unmarshal(body, &result)
- if err != nil {
- log.V(1).Info("json.Unmarshal body =", string(body), err)
- return false, err, result
- }
-
- return false, nil, result
-}
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index c30f092..abc18de 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -112,7 +112,7 @@ func (c *ClientError) Error() string {
type CAsResponse struct {
TotalCount int `json:"totalCount"`
Href string `json:"href"`
- CAsList []CAResponse `json:"cas"`
+ CAList []CAResponse `json:"cas"`
}
type CAResponse struct {
@@ -371,7 +371,7 @@ func (c *Client) GetCA(path string) (CAResponse, error) {
}
func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRResponse, error) {
- filePath, err := writePemToTempFile("/tmp/ncm", pem)
+ filePath, err := WritePemToTempFile("/tmp/ncm", pem)
if err != nil {
return CSRResponse{}, &ClientError{Type: "writing file error", Message: err}
}
diff --git a/pkg/ncmapi/util.go b/pkg/ncmapi/util.go
index 11620f7..9f1cfc7 100644
--- a/pkg/ncmapi/util.go
+++ b/pkg/ncmapi/util.go
@@ -4,6 +4,7 @@ import (
"crypto/rand"
"fmt"
"io"
+ "net/url"
"os"
)
@@ -22,7 +23,7 @@ func newUUID() (string, error) {
}
// Writes PEM to temp file (dirprefix is dir prefix)
-func writePemToTempFile(dirprefix string, pem []byte) (string, error) {
+func WritePemToTempFile(dirprefix string, pem []byte) (string, error) {
myuuid, err := newUUID()
if err != nil {
return "", err
@@ -47,3 +48,12 @@ func writePemToTempFile(dirprefix string, pem []byte) (string, error) {
return path, err
}
+
+func GetPathFromCertURL(certURL string) (string, error) {
+ parsedURL, err := url.Parse(certURL)
+ if err != nil {
+ return "", fmt.Errorf("cannot parsed given URL: url=%s", certURL)
+ }
+
+ return parsedURL.Path, nil
+}
From df19409f4990e338f3ebb7889bbe55c677671f2d Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 11 Jan 2023 22:21:35 +0100
Subject: [PATCH 046/175] Added field for 2nd NCM API URL
---
.../crds/certmanager.ncm.nokia.com_clusterissuers.yaml | 4 ++++
helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml | 4 ++++
pkg/controllers/issuer_controller_test.go | 3 +++
3 files changed, 11 insertions(+)
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
index f8eedd1..e8bd170 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
@@ -62,6 +62,10 @@ spec:
description: Define external NCM REST API URL here, as of now http/https
are supported
type: string
+ ncmSERVER2:
+ description: Define secondary external NCM REST API URL in case of the lack of
+ connection to the main one
+ type: string
profileId:
description: ProfileId API parameter
type: string
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
index bfdf72f..859fa50 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
@@ -62,6 +62,10 @@ spec:
description: Define external NCM REST API URL here, as of now http/https
are supported
type: string
+ ncmSERVER2:
+ description: Define secondary external NCM REST API URL in case of the lack of
+ connection to the main one
+ type: string
profileId:
description: ProfileId API parameter
type: string
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 6025ae2..556c621 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -51,6 +51,7 @@ func TestIssuerReconcile(t *testing.T) {
Namespace: "ncm-issuer",
}, Spec: nokiaAPI.IssuerSpec{
NcmSERVER: "127.0.0.1",
+ NcmSERVER2: "",
CASNAME: "CA1",
CASHREF: "kdhu84hrjl",
LittleEndian: true,
@@ -107,6 +108,7 @@ func TestIssuerReconcile(t *testing.T) {
Namespace: "ncm-issuer",
}, Spec: nokiaAPI.IssuerSpec{
NcmSERVER: "127.0.0.1",
+ NcmSERVER2: "",
CASNAME: "CA1",
CASHREF: "kdhu84hrjl",
LittleEndian: true,
@@ -164,6 +166,7 @@ func TestIssuerReconcile(t *testing.T) {
Namespace: "ncm-issuer",
}, Spec: nokiaAPI.IssuerSpec{
NcmSERVER: "",
+ NcmSERVER2: "",
CASNAME: "CA1",
CASHREF: "kdhu84hrjl",
LittleEndian: true,
From 56efe58b25b88b8aee1fc8596aeb1b7cb11398cd Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 11 Jan 2023 22:23:35 +0100
Subject: [PATCH 047/175] Fixed not working logging & added new pkg to
Dockerfile
---
Dockerfile | 1 +
.../certificaterequest_controller.go | 49 ++++++++--------
pkg/controllers/issuer_controller.go | 2 +-
pkg/ncmapi/ncmapi.go | 56 +++++++++----------
4 files changed, 56 insertions(+), 52 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 2affba7..efa0cf1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,6 +14,7 @@ COPY main.go main.go
COPY api/ api/
COPY pkg/pkiutil pkg/pkiutil/
COPY pkg/controllers pkg/controllers/
+COPY pkg/ncmapi pkg/ncmapi/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index d45463c..47ad537 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -92,7 +92,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, client.IgnoreNotFound(err)
}
- // Check the CertificateRequest's issuerRef and if it does not match the
+ // Checks the CertificateRequest's issuerRef and if it does not match the
// cert-manager group name, log a message at a debug level and stop processing.
if cr.Spec.IssuerRef.Group != certmanagerv1.GroupVersion.Group {
log.V(4).Info("resource does not specify an issuerRef group name that we are responsible for", "group", cr.Spec.IssuerRef.Group)
@@ -154,6 +154,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, SetStatusErrMsg)
}
+
return ctrl.Result{}, err
}
@@ -165,6 +166,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "Fail to set certificateRequest status")
}
+
return ctrl.Result{}, err
}
@@ -180,6 +182,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if !apiutil.CertificateRequestIsApproved(&cr) {
log.V(4).Info("certificate request has not been approved")
+
return ctrl.Result{}, nil
}
@@ -188,7 +191,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to create NCM API Client")
- err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly, err=%v", err)
+ err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly: %v", err)
if err != nil {
log.Error(err, "failed to set certificate request status")
}
@@ -212,7 +215,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- // Finds the certificate for BCMTNCM
+ // Finds the certificate for bcmtncm
wantedCA := ncmapi.CAResponse{}
hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
@@ -249,7 +252,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
lastCA := wantedCA
for {
- log.Info("lastCA href: ", lastCA.Href)
+ log.Info("lastCA href: ", "href", lastCA.Href)
lastCAURLPath, err := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
if err != nil {
@@ -292,7 +295,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
lastCAURLPATH, err := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
return ctrl.Result{}, nil
}
@@ -301,7 +304,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v; resp=%v", err, currentCert)
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate resp=%v; %v", currentCert, err)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
@@ -312,17 +315,17 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if ncmCfg.NoRoot {
instaCA = wantedCA
- log.Info("Found Issuer: ", instaCA.Name)
+ log.Info("Found Issuer: ", "issuer", instaCA.Name)
} else {
instaCA = lastCA
- log.Info("Found root CA: ", instaCA.Name)
+ log.Info("Found root CA: ", "rootCA", instaCA.Name)
}
// Downloads root CA certificate
instaCAURLPath, err := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
return ctrl.Result{}, nil
}
@@ -449,14 +452,14 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
requestedCertURLPath, err := ncmapi.GetPathFromCertURL(csrResp.Href)
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
return ctrl.Result{}, nil
}
csrStatusResp, err := ncmClient.CheckCSRStatus(requestedCertURLPath)
if err != nil {
- log.Error(err, "failed to check CSR")
+ log.Error(err, "failed to check CSR status")
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status: %v", err)
if err != nil {
@@ -468,12 +471,12 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
validCSRStatus := checkCSRStatus(csrStatusResp)
if strings.EqualFold(csrStatusResp.Status, "pending") {
- // save context: enqueue ( req, cr ) into job
+ // Saves context: enqueues ( req, cr ) into job
//
- // start new go route to do:
- // 1. check csr status
- // 2. download Certificate if it is accepted
- // 3. take 1 again if it is pending
+ // Starts a new go route to:
+ // 1. Checks CSR status
+ // 2. Download Certificate if it is accepted
+ // 3. Takes once again if it is pending
validCSRStatus = true
log.Error(err, "CSR status is pending")
@@ -487,7 +490,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if !validCSRStatus {
log.Error(err, "Invalid CSR Status")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid Csr Status. err=%v, status=%v, cr.meta=%v", err, csrStatusResp.Status, cr.ObjectMeta)
+ err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid CSR Status. err=%v, status=%v, cr.meta=%v", err, csrStatusResp.Status, cr.ObjectMeta)
if err != nil {
log.Error(err, SetStatusErrMsg)
}
@@ -637,8 +640,8 @@ func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ct
log.Info(inFuncStr, "time", nowTime.Time)
// Fetch the CertificateRequest resource that was being synced
- newcr := cmapi.CertificateRequest{}
- if err := r.Client.Get(ctx, req.NamespacedName, &newcr); err != nil {
+ newCr := cmapi.CertificateRequest{}
+ if err := r.Client.Get(ctx, req.NamespacedName, &newCr); err != nil {
log.Error(err, "failed to retrieve CertificateRequest resource while in waitAndGetCAs. Wait no longer")
CertificateRequestPendingList[CrPendingKey] = nil
@@ -656,7 +659,7 @@ func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ct
// Status is updated from CertificateReasonPending to CertificateRequestReasonFailed
CertificateRequestPendingList[CrPendingKey] = nil
- _ = r.setStatus(ctx, &newcr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now the external NCM server is ready to get CAs")
+ _ = r.setStatus(ctx, &newCr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now the external NCM server is ready to get CAs")
break
}
@@ -694,8 +697,8 @@ func (r *CertificateRequestReconciler) waitAndCheckCSRStatus(ctx context.Context
log.Info(inFuncStr, "time", nowTime.Time)
// Fetch the CertificateRequest resource that was being synced
- newcr := cmapi.CertificateRequest{}
- if err := r.Client.Get(ctx, req.NamespacedName, &newcr); err != nil {
+ newCr := cmapi.CertificateRequest{}
+ if err := r.Client.Get(ctx, req.NamespacedName, &newCr); err != nil {
CertificateRequestPendingList[CrPendingKey] = nil
log.Error(err, "failed to retrieve CertificateRequest resource while in waitAndCheckCSRStatus. Wait no longer")
@@ -720,7 +723,7 @@ func (r *CertificateRequestReconciler) waitAndCheckCSRStatus(ctx context.Context
}
if strings.EqualFold(csrStatusResp.Status, "pending") {
- log.Info("CSR request status is still pending")
+ log.Info("CSR status is still pending")
}
}
}
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index ced6f18..a79fd49 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -166,7 +166,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}
}
- cfgKey := ncmapi.NCMConfigKey{secretName.Namespace, req.NamespacedName.Name}
+ cfgKey := ncmapi.NCMConfigKey{Namespace: secretName.Namespace, Name: req.NamespacedName.Name}
NCMConfigMap[cfgKey] = &cfg
reason = "Verified"
completeMessage = "Signing CA verified and ready to issue certificates"
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index abc18de..e5a73fb 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -25,17 +25,17 @@ const (
CSRURL = "/v1/requests"
)
-// NCM config set up with secret and used for NCM API Client configuration
+// NCMConfig set up with secret and used for NCM API Client configuration
type NCMConfig struct {
Username string
UsrPassword string
NcmSERVER string
NcmSERVER2 string
- // CAs for BCMTNCM
+ // CAs for bcmtncm
CASNAME string
- // href for BCMTNCM
+ // href for bcmtncm
CASHREF string
ReenrollmentOnRenew bool
@@ -67,7 +67,7 @@ type NCMConfig struct {
MTLS bool
}
-// Used to separate different configurations for different namespaces
+// NCMConfigKey used to separate different configurations for different namespaces
type NCMConfigKey struct {
Namespace string
Name string
@@ -94,10 +94,10 @@ type Client struct {
allowRetry bool
// Determines whether the profile ID should be used during a certificate renewal operation
- useProfileIDforRenew bool
+ useProfileIDForRenew bool
- HTTPClient *http.Client
- log logr.Logger
+ client *http.Client
+ log logr.Logger
}
type ClientError struct {
@@ -163,9 +163,9 @@ func (a *APIError) Error() string {
return fmt.Sprintf("NCM EXTERNAL API Error slug=%s error=%s", a.Slug, a.ErrorMessage)
}
-// Creates a new client used to perform requests to the NCM EXTERNAL API
+// NewClient creates a new client used to perform requests to the NCM EXTERNAL API
func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
- HTTPClient, err := configureHTTPClient(cfg)
+ client, err := configureHTTPClient(cfg)
if err != nil {
return nil, &ClientError{Type: "client creation error", Message: err}
@@ -177,8 +177,8 @@ func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
allowRetry: cfg.NcmSERVER2 != "",
user: cfg.Username,
password: cfg.UsrPassword,
- useProfileIDforRenew: cfg.UseProfileIDForRenew,
- HTTPClient: HTTPClient,
+ useProfileIDForRenew: cfg.UseProfileIDForRenew,
+ client: client,
log: log,
}
@@ -188,11 +188,11 @@ func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
// Configures http.Client used for connection to NCM EXTERNAL API according to NCM config
func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
if !strings.HasPrefix(cfg.NcmSERVER, "https") {
- HTTPClient := &http.Client{
+ client := &http.Client{
Timeout: HTTPTimeout * time.Second,
}
- return HTTPClient, nil
+ return client, nil
}
var tlsConfig *tls.Config
@@ -222,14 +222,14 @@ func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
}
// Creates an HTTPS client and supply it with created CA pool (and client CA if mTLS is enabled)
- HTTPClient := &http.Client{
+ client := &http.Client{
Timeout: HTTPTimeout * time.Second,
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
- return HTTPClient, nil
+ return client, nil
}
func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
@@ -261,7 +261,7 @@ func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
}
req.URL.Host = ncmServer2URL.Host
- resp, err := c.HTTPClient.Do(req)
+ resp, err := c.client.Do(req)
if err != nil {
return nil, &ClientError{Type: "http.Client.Do error", Message: err}
}
@@ -295,7 +295,7 @@ func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
}
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
- resp, err := c.HTTPClient.Do(req)
+ resp, err := c.client.Do(req)
if err != nil && os.IsTimeout(err) && c.allowRetry {
c.log.V(1).Info("connection timeout exceeded while connecting to the main NCM EXTERNAL API")
@@ -344,7 +344,7 @@ func (c *Client) GetCAs() (CAsResponse, error) {
func (c *Client) GetCA(path string) (CAResponse, error) {
params := url.Values{}
- req, err := c.newRequest(http.MethodGet, CAsURL+path, strings.NewReader(params.Encode()))
+ req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
if err != nil {
return CAResponse{}, err
}
@@ -376,6 +376,14 @@ func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRRespon
return CSRResponse{}, &ClientError{Type: "writing file error", Message: err}
}
+ params := map[string]string{
+ "ca": CA.Href,
+ }
+
+ if profileId != "" {
+ params["profileId"] = profileId
+ }
+
file, err := os.Open(filePath)
if err != nil {
return CSRResponse{}, &ClientError{Type: "opening file error", Message: err}
@@ -390,20 +398,12 @@ func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRRespon
return CSRResponse{}, &ClientError{Type: "writer error", Message: err}
}
- params := map[string]string{
- "ca": CA.Href,
- }
-
- if profileId != "" {
- params["profileId"] = profileId
- }
+ _, _ = io.Copy(part, file)
for k, v := range params {
_ = writer.WriteField(k, v)
}
- _, _ = io.Copy(part, file)
-
err = writer.Close()
if err != nil {
return CSRResponse{}, &ClientError{Type: "writer error", Message: err}
@@ -531,7 +531,7 @@ func (c *Client) RenewCertificate(path string, certDuration metav1.Duration, pro
"notAfter": notAfter.Format(time.RFC3339Nano),
}
- if profileId != "" && c.useProfileIDforRenew {
+ if profileId != "" && c.useProfileIDForRenew {
newData["profileId"] = profileId
}
From 1337a88bf6c626cb596b361b95f39529f72c372b Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 12 Jan 2023 18:45:41 +0100
Subject: [PATCH 048/175] Fixed infinite issuing certificate
---
pkg/controllers/certificaterequest_controller.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 47ad537..fc2d1fd 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -413,7 +413,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- enduserCAInPEM, err := ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
+ enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
if err != nil {
log.Error(err, "failed to download Certificate", "certURL", renewCertResp.Certificate)
@@ -507,7 +507,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- enduserCAInPEM, err := ncmClient.DownloadCertificateInPEM(enduserCAURLPath)
+ enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(enduserCAURLPath)
if err != nil {
log.Error(err, "failed to download Certificate", "certURL", csrStatusResp.Certificate)
From 3db650c2eee40fee743e73375fc80e5ddd8a445f Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 12 Jan 2023 23:22:54 +0100
Subject: [PATCH 049/175] Changed method responsible for checking if main NCM
EXTERNAL API server is unavailable & added some unit tests
---
.../certificaterequest_controller.go | 153 +++-------
pkg/ncmapi/ncmapi.go | 269 ++++++++----------
pkg/ncmapi/ncmapi_test.go | 113 ++++++++
3 files changed, 274 insertions(+), 261 deletions(-)
create mode 100644 pkg/ncmapi/ncmapi_test.go
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index fc2d1fd..d8ef087 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -68,8 +68,7 @@ type CertificateRequestPendingState struct {
}
const (
- SleepTime = 20000 // in time.Millisecond, 20s
- SetStatusErrMsg = "Failed to set status"
+ SleepTime = 20000 // in time.Millisecond, 20s
)
/////////////////////////////////////
@@ -96,6 +95,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// cert-manager group name, log a message at a debug level and stop processing.
if cr.Spec.IssuerRef.Group != certmanagerv1.GroupVersion.Group {
log.V(4).Info("resource does not specify an issuerRef group name that we are responsible for", "group", cr.Spec.IssuerRef.Group)
+
return ctrl.Result{}, nil
}
@@ -103,6 +103,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// has already been completed in the past.
if len(cr.Status.Certificate) > 0 {
log.V(4).Info("existing certificate data found in status, skipping already completed CertificateRequest")
+
return ctrl.Result{}, nil
}
@@ -111,6 +112,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerRO, err := r.Scheme.New(issuerGVK)
if err != nil {
log.Error(err, "Unrecognised kind. Ignoring.")
+
return ctrl.Result{}, nil
}
@@ -122,25 +124,32 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerName := types.NamespacedName{
Name: cr.Spec.IssuerRef.Name,
}
+
if cr.Spec.IssuerRef.Kind == "Issuer" {
issuerName.Namespace = req.Namespace
secretNamespace = req.Namespace
}
+
// Get the Issuer or ClusterIssuer
if err := r.Client.Get(ctx, issuerName, issuer); err != nil {
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Issuer is not existing yet")
log.Error(err, "fail to get "+issuerName.Name)
+
return ctrl.Result{}, nil
}
+
issuerSpec, issuerStatus, err := pkiutil.GetSpecAndStatus(issuer)
if err != nil {
log.Error(err, "Fail to get spec and status for the issuer")
+
return ctrl.Result{}, nil
}
+
if cr.Spec.IssuerRef.Kind == "ClusterIssuer" {
if issuerSpec.AuthNamespace == "" {
issuerSpec.AuthNamespace = "default"
}
+
secretNamespace = issuerSpec.AuthNamespace
}
@@ -151,21 +160,14 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}) {
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
"Failed: (Cluster)Issuer %s is not Ready; its condition is %s", issuerName, issuerStatus.Conditions)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
return ctrl.Result{}, err
}
// Once CRD resource is ready, the config data should be ready
if NCMConfigMap == nil || NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}] == nil {
-
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
"Failed: CRD configuration %s/%s is not Ready; type,status in myCRD.Status.Conditions=%s, cfg is nil=%v", secretNamespace, issuerName.Name, issuerStatus.Conditions, NCMConfigMap)
- if err != nil {
- log.Error(err, "Fail to set certificateRequest status")
- }
return ctrl.Result{}, err
}
@@ -173,9 +175,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if apiutil.CertificateRequestIsDenied(&cr) {
log.V(4).Info("certificate request has been denied")
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CSR has been denied")
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
return ctrl.Result{}, err
}
@@ -191,7 +190,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to create NCM API Client")
- err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly: %v", err)
+ err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
if err != nil {
log.Error(err, "failed to set certificate request status")
}
@@ -204,11 +203,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
casResponse, err := ncmClient.GetCAs()
if err != nil {
log.Error(err, "failed to get CAs")
-
- err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Please, check your external NCM server. Failed to get CAs: %v", err)
- if err != nil {
- log.Error(err, "failed to set certificate request status")
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Please, check your external NCM server. Failed to get CAs; %v", err)
go r.waitAndGetCAs(ctx, req, &cr, ncmClient, log)
@@ -216,21 +211,19 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
// Finds the certificate for bcmtncm
- wantedCA := ncmapi.CAResponse{}
+ wantedCA := &ncmapi.CAResponse{}
hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
for _, ca := range casResponse.CAList {
if strings.EqualFold(ca.Status, "active") {
if ncmCfg.CASHREF != "" {
href := hrefRegex.Find([]byte(ca.Href))
-
if strings.EqualFold(string(href), ncmCfg.CASHREF) {
- wantedCA = ca
+ wantedCA = &ca
break
}
-
} else if strings.EqualFold(ca.Name, ncmCfg.CASNAME) {
- wantedCA = ca
+ wantedCA = &ca
break
}
}
@@ -238,17 +231,13 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if wantedCA.Href == "" {
log.Error(err, "CA certificate has not been found. Please check provided CASHREF/CASNAME", "cashref", ncmCfg.CASHREF, "casname", ncmCfg.CASNAME)
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found. Please check provided CASHREF/CASNAME url=%v, CASNAME=%v; CASHREF=%v", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found. Please check provided CASHREF/CASNAME URL=%s, CASNAME=%s, CASHREF=%s", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
return ctrl.Result{}, nil
}
// Finds the root CA
- instaCA := ncmapi.CAResponse{}
+ instaCA := &ncmapi.CAResponse{}
lastCA := wantedCA
for {
@@ -257,7 +246,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
lastCAURLPath, err := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
return ctrl.Result{}, nil
}
@@ -265,11 +254,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
currentCert, err := ncmClient.DownloadCertificate(lastCAURLPath)
if err != nil {
log.Error(err, "failed to download Certificate", "certURL", lastCA.Certificates["active"])
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: %v", err)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -281,11 +266,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
currentCertInPEM, err := ncmClient.DownloadCertificateInPEM(lastCAURLPath)
if err != nil {
log.Error(err, "failed to download PEM Certificate", "certURL", lastCA.Certificates["active"])
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate: err=%v; resp=%v", err, lastCA)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -295,7 +276,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
lastCAURLPATH, err := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
return ctrl.Result{}, nil
}
@@ -303,11 +284,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
lastCA, err = ncmClient.GetCA(lastCAURLPATH)
if err != nil {
log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate resp=%v; %v", currentCert, err)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download CA certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -325,18 +302,15 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
instaCAURLPath, err := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
return ctrl.Result{}, nil
}
instaCAInPEM, err := ncmClient.DownloadCertificateInPEM(instaCAURLPath)
if err != nil {
- log.Error(err, "failed to download ROOT Certificate")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v; resp=%v", err, instaCAInPEM)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ log.Error(err, "failed to download ROOT certificate")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download ROOT certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -346,7 +320,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
positionToSlice := strings.LastIndex(req.Name, "-")
if err := r.Client.Get(ctx, client.ObjectKey{
Namespace: req.Namespace, Name: req.Name[:positionToSlice]}, &crt); err != nil {
- log.Error(err, "Certificate object not found!")
+ log.Error(err, "certificate object not found!")
return ctrl.Result{}, nil
}
@@ -354,9 +328,9 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
var secretName = req.Name[:positionToSlice] + "-details"
if crt.Status.Revision != nil {
- log.Info("Revision value fetched", "revision", crt.Status.Revision)
+ log.Info("revision value fetched", "revision", crt.Status.Revision)
} else {
- log.Info("Revision value is set to nil")
+ log.Info("revision value is set to nil")
}
secretList, err := r.getSecretList(ctx, req)
@@ -374,10 +348,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID)
if err != nil {
log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
return ctrl.Result{}, nil
}
@@ -395,11 +366,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
renewCertResp, err := ncmClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed to renewCertificate")
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renewCertificate err=%v, resp=%v", err, renewCertResp)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -415,12 +382,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
if err != nil {
- log.Error(err, "failed to download Certificate", "certURL", renewCertResp.Certificate)
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v, resp=%v", err, enduserCAInPEM)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -428,10 +391,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
err = r.Client.Update(ctx, &secretCertID)
if err != nil {
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
+
return ctrl.Result{}, nil
}
} else {
@@ -440,11 +401,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
csrResp, err := ncmClient.SendCSR(cr.Spec.Request, wantedCA, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed send CSR")
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR err=%v, resp=%v, cr.ObjectMeta.name=%v/%v", err, csrResp, cr.ObjectMeta.Name, cr.ObjectMeta.Namespace)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR cr.ObjectMeta.name=%s/%s; %v", cr.ObjectMeta.Name, cr.ObjectMeta.Namespace, err)
return ctrl.Result{}, nil
}
@@ -452,7 +409,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
requestedCertURLPath, err := ncmapi.GetPathFromCertURL(csrResp.Href)
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request: %v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
return ctrl.Result{}, nil
}
@@ -460,11 +417,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
csrStatusResp, err := ncmClient.CheckCSRStatus(requestedCertURLPath)
if err != nil {
log.Error(err, "failed to check CSR status")
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status: %v", err)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
return ctrl.Result{}, nil
}
@@ -480,7 +433,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
validCSRStatus = true
log.Error(err, "CSR status is pending")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to snd check CSR status err=%v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
go r.waitAndCheckCSRStatus(ctx, req, &cr, ncmClient, requestedCertURLPath, log)
@@ -489,16 +442,12 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if !validCSRStatus {
log.Error(err, "Invalid CSR Status")
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid CSR Status. err=%v, status=%v, cr.meta=%v", err, csrStatusResp.Status, cr.ObjectMeta)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid CSR Status status=%s, cr.meta=%v; %v", csrStatusResp.Status, cr.ObjectMeta, err)
return ctrl.Result{}, nil
}
- // Downloads certificate as csrRequestStatusResp3.Certificate
+ // Downloads enduser certificate
enduserCAURLPath, err := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
if err != nil {
log.Error(err, "failed to get certificate URL path needed for request")
@@ -509,12 +458,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(enduserCAURLPath)
if err != nil {
- log.Error(err, "failed to download Certificate", "certURL", csrStatusResp.Certificate)
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download Certificate err=%v, tmp_enduser_ca_InPEM=%v", err, enduserCAInPEM)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ log.Error(err, "failed to download enduser certificate", "certURL", csrStatusResp.Certificate)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download enduser certificate tmp_enduser_ca_InPEM=%v; %v", enduserCAInPEM, err)
return ctrl.Result{}, nil
}
@@ -531,11 +476,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to create/update a secret with cert-id", "secretName", secretName)
-
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create/update secret: %v", err)
- if err != nil {
- log.Error(err, SetStatusErrMsg)
- }
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create/update secret err=%v", err)
return ctrl.Result{}, nil
}
@@ -610,7 +551,7 @@ func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.
// ////////////////////////////////////
-// Waits and frequently checks to see if the NCM server is responding (NCM API client tries to get CAs).
+// waitAndGetCAs waits and frequently checks to see if the NCM server is responding (NCM API client tries to get CAs).
// When the server responds to a request for CAs triggers new round of reconcile
func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, client *ncmapi.Client, log logr.Logger) {
CrPendingKey := CertificateRequestPendingKey{cr.ObjectMeta.Namespace, cr.ObjectMeta.Name}
@@ -667,7 +608,7 @@ func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ct
}
-// Waits and frequently checks if the CSR status is 'accepted'.
+// waitAndCheckCSRStatus waits and frequently checks if the CSR status is 'accepted'.
// When CSR status is accepted triggers new round fo reconcile
func (r *CertificateRequestReconciler) waitAndCheckCSRStatus(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, c *ncmapi.Client, requestedCertURLPath string, log logr.Logger) {
CrPendingKey := CertificateRequestPendingKey{cr.ObjectMeta.Namespace, cr.ObjectMeta.Name}
@@ -735,6 +676,6 @@ func (r *CertificateRequestReconciler) SetupWithManager(mgr ctrl.Manager) error
Complete(r)
}
-func checkCSRStatus(csrStatusResp ncmapi.CSRStatusResponse) bool {
+func checkCSRStatus(csrStatusResp *ncmapi.CSRStatusResponse) bool {
return strings.EqualFold(csrStatusResp.Status, "accepted")
}
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index e5a73fb..1bdcb9e 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -27,44 +27,22 @@ const (
// NCMConfig set up with secret and used for NCM API Client configuration
type NCMConfig struct {
- Username string
- UsrPassword string
- NcmSERVER string
- NcmSERVER2 string
-
- // CAs for bcmtncm
- CASNAME string
-
- // href for bcmtncm
- CASHREF string
-
+ Username string
+ UsrPassword string
+ NcmSERVER string
+ NcmSERVER2 string
+ CASNAME string // CAs for bcmtncm
+ CASHREF string // href for bcmtncm
ReenrollmentOnRenew bool
UseProfileIDForRenew bool
-
- // NCM root CA
- InstaCA string
-
- // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
- LittleEndianPem bool
-
- // Determines whether Issuer of the Cert should be taken into consideration instead of root
- NoRoot bool
-
- // TLS CA Cert
- CACert string
-
- // TLS client Key
- Key string
-
- // TLS client Cert
- Cert string
-
- // Determines whether SSL certificate verification between client instance and NCM EXTERNAL API
- // should be enabled
- InsecureSkipVerify bool
-
- // Determines whether mTLS should be enabled
- MTLS bool
+ InstaCA string // NCM root CA
+ LittleEndianPem bool // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
+ NoRoot bool // determines whether Issuer of the Cert should be taken into consideration instead of root
+ CACert string // TLS CA Cert
+ Key string // TLS client Key
+ Cert string // TLS client Cert
+ InsecureSkipVerify bool // determines whether SSL certificate verification between client instance and NCM EXTERNAL API should be enabled
+ MTLS bool // determines whether mTLS should be enabled
}
// NCMConfigKey used to separate different configurations for different namespaces
@@ -75,38 +53,28 @@ type NCMConfigKey struct {
// Client used to communicate with the NCM EXTERNAL API
type Client struct {
- // Main NCM EXTERNAL API server address
- ncmServer string
-
- // Secondary NCM EXTERNAL API server address in case of the lack of connection
- // to the main one (can be empty)
- ncmServer2 string
-
- // User used for authentication to NCM EXTERNAL API
- user string
-
- // Password used for authentication to NCM EXTERNAL API
- password string
+ ncmServer string // main NCM EXTERNAL API server address
+ ncmServer2 string // Secondary NCM EXTERNAL API server address in case of the lack of connection to the main one (can be empty)
+ user string // user used for authentication to NCM EXTERNAL API
+ password string // password used for authentication to NCM EXTERNAL API
// Determines whether, in the case of lack of the connection to the main server (no response within
// a certain time period), there is an address of a second server to which client can send the
// same request
allowRetry bool
- // Determines whether the profile ID should be used during a certificate renewal operation
- useProfileIDForRenew bool
-
- client *http.Client
- log logr.Logger
+ useProfileIDForRenew bool // determines whether the profile ID should be used during a certificate renewal operation
+ client *http.Client
+ log logr.Logger
}
type ClientError struct {
- Type string
- Message error
+ Reason string
+ ErrorMessage error
}
func (c *ClientError) Error() string {
- return fmt.Sprintf("NCM API Client error type=%s error=%v", c.Type, c.Message)
+ return fmt.Sprintf("NCM API Client Error reason=%s err=%v", c.Reason, c.ErrorMessage)
}
type CAsResponse struct {
@@ -155,25 +123,35 @@ type RenewCertificateResponse struct {
}
type APIError struct {
- Slug string `json:"error_slug"`
- ErrorMessage string `json:"error"`
+ Message string `json:"message,omitempty"`
+ Status int `json:"status"`
+ StatusMessage string `json:"statusMessage"`
}
func (a *APIError) Error() string {
- return fmt.Sprintf("NCM EXTERNAL API Error slug=%s error=%s", a.Slug, a.ErrorMessage)
+ return fmt.Sprintf("NCM EXTERNAL API Error status=%d, message=%s, statusMessage=%s", a.Status, a.Message, a.StatusMessage)
}
// NewClient creates a new client used to perform requests to the NCM EXTERNAL API
func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
- client, err := configureHTTPClient(cfg)
+ ncmServerURL, err := url.Parse(cfg.NcmSERVER)
+ if err != nil {
+ return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
+ }
+
+ ncmServer2URL, err := url.Parse(cfg.NcmSERVER2)
+ if err != nil {
+ return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
+ }
+ client, err := configureHTTPClient(cfg)
if err != nil {
- return nil, &ClientError{Type: "client creation error", Message: err}
+ return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
}
c := &Client{
- ncmServer: cfg.NcmSERVER,
- ncmServer2: cfg.NcmSERVER2,
+ ncmServer: ncmServerURL.String(),
+ ncmServer2: ncmServer2URL.String(),
allowRetry: cfg.NcmSERVER2 != "",
user: cfg.Username,
password: cfg.UsrPassword,
@@ -233,16 +211,12 @@ func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
}
func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
- ncmServerURL, err := url.Parse(c.ncmServer)
- if err != nil {
- return nil, &ClientError{Type: "URL parsing error", Message: err}
- }
-
+ ncmServerURL, _ := url.Parse(c.ncmServer)
ncmServerURL.Path = path
req, err := http.NewRequest(method, ncmServerURL.String(), body)
if err != nil {
- return nil, &ClientError{Type: "http.NewRequest creation error", Message: err}
+ return nil, &ClientError{Reason: "cannot create new request", ErrorMessage: err}
}
req.SetBasicAuth(c.user, c.password)
@@ -253,42 +227,34 @@ func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request,
}
func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
- c.log.V(1).Info("retrying request to the second NCM EXTERNAL API")
-
- ncmServer2URL, err := url.Parse(c.ncmServer2)
- if err != nil {
- return nil, &ClientError{Type: "URL parsing error", Message: err}
- }
-
+ c.log.Info("retrying request to secondary NCM EXTERNAL API")
+ ncmServer2URL, _ := url.Parse(c.ncmServer2)
req.URL.Host = ncmServer2URL.Host
+
resp, err := c.client.Do(req)
if err != nil {
- return nil, &ClientError{Type: "http.Client.Do error", Message: err}
+ return nil, &ClientError{Reason: "cannot perform request", ErrorMessage: err}
}
return resp, nil
}
func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
- if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, &ClientError{Type: "response body read error", Message: err}
- }
-
- return body, nil
-
- }
-
body, err := io.ReadAll(resp.Body)
if err != nil {
- return nil, &ClientError{Type: "response body read error", Message: err}
+ return nil, &ClientError{Reason: "cannot read response body", ErrorMessage: err}
+ }
+
+ defer resp.Body.Close()
+
+ if status := resp.StatusCode; status >= 200 && status < 300 {
+ return body, nil
}
apiError := APIError{}
err = json.Unmarshal(body, &apiError)
if err != nil {
- return nil, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
return nil, &apiError
@@ -296,84 +262,87 @@ func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
resp, err := c.client.Do(req)
- if err != nil && os.IsTimeout(err) && c.allowRetry {
- c.log.V(1).Info("connection timeout exceeded while connecting to the main NCM EXTERNAL API")
+ if err != nil {
+ if c.allowRetry && os.IsTimeout(err) {
+ c.log.Info("connection timeout exceeded during request to main NCM EXTERNAL API")
+ resp, err = c.retryRequest(req)
+ if err != nil {
+ return nil, err
+ }
+ return resp, err
+ }
+ return nil, err
+ }
- resp, err := c.retryRequest(req)
+ if c.allowRetry && resp.StatusCode == http.StatusInternalServerError {
+ c.log.Info("got 500 status code from main NCM EXTERNAL API")
+ resp, err = c.retryRequest(req)
if err != nil {
return nil, err
}
-
return resp, nil
-
- } else if err != nil {
- return nil, &ClientError{Type: "http.Client.Do error", Message: err}
}
return resp, nil
}
-func (c *Client) GetCAs() (CAsResponse, error) {
+func (c *Client) GetCAs() (*CAsResponse, error) {
params := url.Values{}
req, err := c.newRequest(http.MethodGet, CAsURL, strings.NewReader(params.Encode()))
if err != nil {
- return CAsResponse{}, err
+ return nil, err
}
resp, err := c.doRequest(req)
if err != nil {
- return CAsResponse{}, err
+ return nil, err
}
- defer resp.Body.Close()
-
body, err := c.validateResponse(resp)
if err != nil {
- return CAsResponse{}, err
+ return nil, err
}
cas := CAsResponse{}
err = json.Unmarshal(body, &cas)
if err != nil {
- return CAsResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
- return cas, nil
+ return &cas, nil
}
-func (c *Client) GetCA(path string) (CAResponse, error) {
+func (c *Client) GetCA(path string) (*CAResponse, error) {
params := url.Values{}
req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
if err != nil {
- return CAResponse{}, err
+ return nil, err
}
resp, err := c.doRequest(req)
if err != nil {
- return CAResponse{}, err
+ return nil, err
}
- defer resp.Body.Close()
-
body, err := c.validateResponse(resp)
if err != nil {
- return CAResponse{}, err
+ return nil, err
}
ca := CAResponse{}
err = json.Unmarshal(body, &ca)
if err != nil {
- return CAResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
- return ca, nil
+ return &ca, nil
}
-func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRResponse, error) {
+func (c *Client) SendCSR(pem []byte, CA *CAResponse, profileId string) (*CSRResponse, error) {
filePath, err := WritePemToTempFile("/tmp/ncm", pem)
if err != nil {
- return CSRResponse{}, &ClientError{Type: "writing file error", Message: err}
+ return nil, &ClientError{Reason: "cannot write PEM to file", ErrorMessage: err}
}
params := map[string]string{
@@ -386,7 +355,7 @@ func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRRespon
file, err := os.Open(filePath)
if err != nil {
- return CSRResponse{}, &ClientError{Type: "opening file error", Message: err}
+ return nil, &ClientError{Reason: "cannot open file", ErrorMessage: err}
}
defer file.Close()
@@ -395,7 +364,7 @@ func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRRespon
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("pkcs10", filepath.Base(filePath))
if err != nil {
- return CSRResponse{}, &ClientError{Type: "writer error", Message: err}
+ return nil, &ClientError{Reason: "cannot create new form-data header", ErrorMessage: err}
}
_, _ = io.Copy(part, file)
@@ -406,96 +375,90 @@ func (c *Client) SendCSR(pem []byte, CA CAResponse, profileId string) (CSRRespon
err = writer.Close()
if err != nil {
- return CSRResponse{}, &ClientError{Type: "writer error", Message: err}
+ return nil, &ClientError{Reason: "cannot close writer", ErrorMessage: err}
}
req, err := c.newRequest(http.MethodPost, CSRURL, body)
if err != nil {
- return CSRResponse{}, err
+ return nil, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
err = os.Remove(filePath)
if err != nil {
- return CSRResponse{}, &ClientError{Type: "removing file error", Message: err}
+ return nil, &ClientError{Reason: "cannot remove file", ErrorMessage: err}
}
resp, err := c.doRequest(req)
if err != nil {
- return CSRResponse{}, err
+ return nil, err
}
- defer resp.Body.Close()
-
respBody, err := c.validateResponse(resp)
if err != nil {
- return CSRResponse{}, err
+ return nil, err
}
csr := CSRResponse{}
err = json.Unmarshal(respBody, &csr)
if err != nil {
- return CSRResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
- return csr, nil
+ return &csr, nil
}
-func (c *Client) CheckCSRStatus(path string) (CSRStatusResponse, error) {
+func (c *Client) CheckCSRStatus(path string) (*CSRStatusResponse, error) {
params := url.Values{}
req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
if err != nil {
- return CSRStatusResponse{}, err
+ return nil, err
}
resp, err := c.doRequest(req)
if err != nil {
- return CSRStatusResponse{}, err
+ return nil, err
}
- defer resp.Body.Close()
-
body, err := c.validateResponse(resp)
if err != nil {
- return CSRStatusResponse{}, err
+ return nil, err
}
csrStatus := CSRStatusResponse{}
err = json.Unmarshal(body, &csrStatus)
if err != nil {
- return CSRStatusResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
- return csrStatus, nil
+ return &csrStatus, nil
}
-func (c *Client) DownloadCertificate(path string) (CertificateDownloadResponse, error) {
+func (c *Client) DownloadCertificate(path string) (*CertificateDownloadResponse, error) {
params := url.Values{}
req, err := c.newRequest(http.MethodGet, path, strings.NewReader(params.Encode()))
if err != nil {
- return CertificateDownloadResponse{}, err
+ return nil, err
}
resp, err := c.doRequest(req)
if err != nil {
- return CertificateDownloadResponse{}, err
+ return nil, err
}
- defer resp.Body.Close()
-
body, err := c.validateResponse(resp)
if err != nil {
- return CertificateDownloadResponse{}, err
+ return nil, err
}
- certificate := CertificateDownloadResponse{}
- err = json.Unmarshal(body, &certificate)
+ crt := CertificateDownloadResponse{}
+ err = json.Unmarshal(body, &crt)
if err != nil {
- return CertificateDownloadResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
- return certificate, nil
+ return &crt, nil
}
func (c *Client) DownloadCertificateInPEM(path string) ([]byte, error) {
@@ -512,8 +475,6 @@ func (c *Client) DownloadCertificateInPEM(path string) ([]byte, error) {
return nil, err
}
- defer resp.Body.Close()
-
body, err := c.validateResponse(resp)
if err != nil {
return nil, err
@@ -522,7 +483,7 @@ func (c *Client) DownloadCertificateInPEM(path string) ([]byte, error) {
return body, nil
}
-func (c *Client) RenewCertificate(path string, certDuration metav1.Duration, profileId string) (RenewCertificateResponse, error) {
+func (c *Client) RenewCertificate(path string, certDuration metav1.Duration, profileId string) (*RenewCertificateResponse, error) {
notBefore := time.Now()
notAfter := notBefore.Add(certDuration.Duration)
@@ -538,28 +499,26 @@ func (c *Client) RenewCertificate(path string, certDuration metav1.Duration, pro
jsonData, _ := json.Marshal(&newData)
req, err := c.newRequest(http.MethodPost, path+"/update", strings.NewReader(string(jsonData)))
if err != nil {
- return RenewCertificateResponse{}, err
+ return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.doRequest(req)
if err != nil {
- return RenewCertificateResponse{}, err
+ return nil, err
}
- defer resp.Body.Close()
-
body, err := c.validateResponse(resp)
if err != nil {
- return RenewCertificateResponse{}, err
+ return nil, err
}
- renewedCertificate := RenewCertificateResponse{}
- err = json.Unmarshal(body, &renewedCertificate)
+ renewedCrt := RenewCertificateResponse{}
+ err = json.Unmarshal(body, &renewedCrt)
if err != nil {
- return RenewCertificateResponse{}, &ClientError{Type: "json unmarshal error", Message: err}
+ return nil, &ClientError{Reason: "cannot unmarshal json", ErrorMessage: err}
}
- return renewedCertificate, nil
+ return &renewedCrt, nil
}
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
new file mode 100644
index 0000000..5b13310
--- /dev/null
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -0,0 +1,113 @@
+package ncmapi
+
+import (
+ "bytes"
+ testr "github.com/go-logr/logr/testing"
+ "github.com/stretchr/testify/assert"
+ "io"
+ "net/http"
+ "testing"
+)
+
+func TestNewClientCreation(t *testing.T) {
+ tests := []struct {
+ name string
+ cfg *NCMConfig
+ }{
+ {
+ name: "invalidNCMServerURL",
+ cfg: &NCMConfig{
+ NcmSERVER: "https://malformed url.com:80",
+ },
+ },
+ {
+ name: "invalidNCMServer2URL",
+ cfg: &NCMConfig{
+ NcmSERVER: "https://working-url.com:3000",
+ NcmSERVER2: "https://malformed url.com:-17",
+ },
+ },
+ {
+ name: "invalidKeyPair",
+ cfg: &NCMConfig{
+ NcmSERVER: "https://working-url.com:3000",
+ NcmSERVER2: "https://working-url2.com:3000",
+ CACert: "CACert",
+ Key: "Key",
+ Cert: "Cert",
+ InsecureSkipVerify: false,
+ MTLS: true,
+ },
+ },
+ {
+ name: "properClientCreation",
+ cfg: &NCMConfig{
+ Username: "user",
+ UsrPassword: "password",
+ NcmSERVER: "https://working-url.com:3000",
+ NcmSERVER2: "",
+ CACert: "CACert",
+ Key: "Key",
+ Cert: "Cert",
+ InsecureSkipVerify: true,
+ MTLS: false,
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ log := testr.TestLogger{T: t}
+ if client, err := NewClient(tt.cfg, log); err != nil {
+ assert.ErrorIs(t, err, err.(*ClientError))
+ } else {
+ assert.IsType(t, &Client{}, client)
+ }
+ })
+ }
+}
+
+func TestResponseValidation(t *testing.T) {
+ tests := []struct {
+ name string
+ resp *http.Response
+ }{
+ {
+ name: "notValidResponse",
+ resp: &http.Response{
+ StatusCode: 400,
+ Body: io.NopCloser(bytes.NewReader([]byte(`{"message": "", "status": 400, "statusMessage": "Bad Request"}`))),
+ },
+ },
+ {
+ name: "validResponse",
+ resp: &http.Response{
+ StatusCode: 200,
+ Body: io.NopCloser(bytes.NewReader([]byte(`{"random": "field"}`))),
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ log := testr.TestLogger{T: t}
+ client, _ := NewClient(&NCMConfig{
+ Username: "user",
+ UsrPassword: "password",
+ NcmSERVER: "https://working-url.com:3000",
+ NcmSERVER2: "",
+ CACert: "CACert",
+ Key: "Key",
+ Cert: "Cert",
+ InsecureSkipVerify: true,
+ MTLS: false,
+ }, log)
+
+ if body, err := client.validateResponse(tt.resp); err != nil {
+ assert.ErrorIs(t, err, err.(*APIError))
+ } else {
+ assert.IsType(t, []byte("random-field"), body)
+ }
+ })
+ }
+}
From cfac548499125b8451406cf78da2b8a68f4f7a61 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 20 Jan 2023 16:52:15 +0100
Subject: [PATCH 050/175] Changed logging messages in NCM API client
---
pkg/ncmapi/ncmapi.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 1bdcb9e..e66faf8 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -227,7 +227,7 @@ func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request,
}
func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
- c.log.Info("retrying request to secondary NCM EXTERNAL API")
+ c.log.Info("retrying request to secondary NCM EXTERNAL API", "serverURL", c.ncmServer2)
ncmServer2URL, _ := url.Parse(c.ncmServer2)
req.URL.Host = ncmServer2URL.Host
@@ -235,6 +235,7 @@ func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
if err != nil {
return nil, &ClientError{Reason: "cannot perform request", ErrorMessage: err}
}
+ c.log.Info("received proper response from secondary NCM EXTERNAL API", "serverURL", c.ncmServer2)
return resp, nil
}
@@ -264,7 +265,7 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
resp, err := c.client.Do(req)
if err != nil {
if c.allowRetry && os.IsTimeout(err) {
- c.log.Info("connection timeout exceeded during request to main NCM EXTERNAL API")
+ c.log.Info("main NCM EXTERNAL API seems not responding", "serverURL", c.ncmServer, "err", err)
resp, err = c.retryRequest(req)
if err != nil {
return nil, err
@@ -275,7 +276,7 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
}
if c.allowRetry && resp.StatusCode == http.StatusInternalServerError {
- c.log.Info("got 500 status code from main NCM EXTERNAL API")
+ c.log.Info("main NCM EXTERNAL API cannot handle request", "serverURL", c.ncmServer, "status", resp.StatusCode)
resp, err = c.retryRequest(req)
if err != nil {
return nil, err
From 1c49da0288fa2e4cd5b6c1758f9a6e0d99fe1788 Mon Sep 17 00:00:00 2001
From: raczu
Date: Tue, 24 Jan 2023 00:25:00 +0100
Subject: [PATCH 051/175] Fixed misinterpretation in case of manually
triggering rotation of a private key
---
helm/Chart.yaml | 2 +-
helm/values.yaml | 8 +-
.../certificaterequest_controller.go | 151 +++++++-----------
pkg/ncmapi/ncmapi_test.go | 79 ++++-----
pkg/pkiutil/util.go | 7 +-
release_notes.txt | 6 +-
6 files changed, 107 insertions(+), 146 deletions(-)
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
index f271c68..b25e3d0 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -14,4 +14,4 @@ maintainers:
- name: Maxwell Jiang
- name: Lilian Liang
name: ncm-issuer
-version: 1.0.0
+version: 1.0.3
diff --git a/helm/values.yaml b/helm/values.yaml
index 4627993..d252697 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -7,12 +7,12 @@ resources:
# Limits to cap the resource usage in case of unexpected.
# NOTE! exceeding memory limit will cause pod to be killed by kubernetes.
limits:
- cpu: 200m
- memory: 250Mi
+ cpu: 400m
+ memory: 500Mi
# Requests to help kubernetes start pods on a node that has sufficient capacity.
requests:
- cpu: 200m
- memory: 250Mi
+ cpu: 400m
+ memory: 500Mi
updateStrategy:
rollingUpdate:
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index d8ef087..fb4c5bc 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -165,7 +165,9 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
// Once CRD resource is ready, the config data should be ready
- if NCMConfigMap == nil || NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}] == nil {
+ if NCMConfigMap == nil || NCMConfigMap[ncmapi.NCMConfigKey{
+ Namespace: secretNamespace,
+ Name: issuerName.Name}] == nil {
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
"Failed: CRD configuration %s/%s is not Ready; type,status in myCRD.Status.Conditions=%s, cfg is nil=%v", secretNamespace, issuerName.Name, issuerStatus.Conditions, NCMConfigMap)
@@ -243,14 +245,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
for {
log.Info("lastCA href: ", "href", lastCA.Href)
- lastCAURLPath, err := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
-
- return ctrl.Result{}, nil
- }
-
+ lastCAURLPath, _ := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
currentCert, err := ncmClient.DownloadCertificate(lastCAURLPath)
if err != nil {
log.Error(err, "failed to download Certificate", "certURL", lastCA.Certificates["active"])
@@ -273,14 +268,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
pemChain = appendPem(ncmCfg, pemChain, currentCertInPEM)
- lastCAURLPATH, err := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
-
- return ctrl.Result{}, nil
- }
-
+ lastCAURLPATH, _ := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
lastCA, err = ncmClient.GetCA(lastCAURLPATH)
if err != nil {
log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
@@ -299,14 +287,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
// Downloads root CA certificate
- instaCAURLPath, err := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
-
- return ctrl.Result{}, nil
- }
-
+ instaCAURLPath, _ := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
instaCAInPEM, err := ncmClient.DownloadCertificateInPEM(instaCAURLPath)
if err != nil {
log.Error(err, "failed to download ROOT certificate")
@@ -340,64 +321,55 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- if crt.Status.Revision != nil && *crt.Status.Revision >= 1 && !ncmCfg.ReenrollmentOnRenew && pkiutil.FindIfSecretExists(secretList, secretName) && crt.Spec.PrivateKey.RotationPolicy != "Always" {
- // Gets saved certificate ID
- log.Info("A secret with cert-id will be updated...")
- secretCertID := core.Secret{}
+ switch {
+ case crt.Status.Revision != nil && *crt.Status.Revision >= 1 &&
+ !ncmCfg.ReenrollmentOnRenew && crt.Spec.PrivateKey.RotationPolicy != "Always":
+ if pkiutil.FindIfSecretExists(secretList, secretName) && pkiutil.FindIfSecretExists(secretList, crt.ObjectMeta.Name) {
+ log.Info("Secret with cert-id will be updated")
- err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID)
- if err != nil {
- log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
-
- return ctrl.Result{}, nil
- }
-
- log.Info("A certificate href fetched", "href", string(secretCertID.Data["cert-id"]))
-
- certURLPath, err := ncmapi.GetPathFromCertURL(string(secretCertID.Data["cert-id"]))
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
-
- return ctrl.Result{}, nil
- }
+ secretCertID := core.Secret{}
+ err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID)
+ if err != nil {
+ log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
- renewCertResp, err := ncmClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
- if err != nil {
- log.Error(err, "failed to renewCertificate")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
+ return ctrl.Result{}, nil
+ }
- return ctrl.Result{}, nil
- }
+ log.Info("Certificate href has been fetched", "href", string(secretCertID.Data["cert-id"]))
- // Downloads the renewed certificate
- renewedCertURLPath, err := ncmapi.GetPathFromCertURL(renewCertResp.Certificate)
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
+ certURLPath, _ := ncmapi.GetPathFromCertURL(string(secretCertID.Data["cert-id"]))
+ renewCertResp, err := ncmClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
+ if err != nil {
+ log.Error(err, "failed to renewCertificate")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
- return ctrl.Result{}, nil
- }
+ return ctrl.Result{}, nil
+ }
- enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
- if err != nil {
- log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
+ // Downloads the renewed certificate
+ renewedCertURLPath, _ := ncmapi.GetPathFromCertURL(renewCertResp.Certificate)
+ enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
+ if err != nil {
+ log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
- return ctrl.Result{}, nil
- }
+ return ctrl.Result{}, nil
+ }
- secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
- err = r.Client.Update(ctx, &secretCertID)
- if err != nil {
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
+ secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
+ err = r.Client.Update(ctx, &secretCertID)
+ if err != nil {
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
- return ctrl.Result{}, nil
+ return ctrl.Result{}, nil
+ }
+ break
+ } else if !pkiutil.FindIfSecretExists(secretList, crt.ObjectMeta.Name) {
+ log.Info("Manually rotation of a private key has been triggered")
}
- } else {
- log.Info("A new secret with cert-id will be created...")
-
+ fallthrough
+ default:
csrResp, err := ncmClient.SendCSR(cr.Spec.Request, wantedCA, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed send CSR")
@@ -406,14 +378,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- requestedCertURLPath, err := ncmapi.GetPathFromCertURL(csrResp.Href)
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
-
- return ctrl.Result{}, nil
- }
-
+ requestedCertURLPath, _ := ncmapi.GetPathFromCertURL(csrResp.Href)
csrStatusResp, err := ncmClient.CheckCSRStatus(requestedCertURLPath)
if err != nil {
log.Error(err, "failed to check CSR status")
@@ -425,7 +390,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
validCSRStatus := checkCSRStatus(csrStatusResp)
if strings.EqualFold(csrStatusResp.Status, "pending") {
// Saves context: enqueues ( req, cr ) into job
- //
// Starts a new go route to:
// 1. Checks CSR status
// 2. Download Certificate if it is accepted
@@ -448,14 +412,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
// Downloads enduser certificate
- enduserCAURLPath, err := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
- if err != nil {
- log.Error(err, "failed to get certificate URL path needed for request")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get certificate URL path needed for request err=%v", err)
-
- return ctrl.Result{}, nil
- }
-
+ enduserCAURLPath, _ := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(enduserCAURLPath)
if err != nil {
log.Error(err, "failed to download enduser certificate", "certURL", csrStatusResp.Certificate)
@@ -466,11 +423,11 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Saves cert-id to secret
if pkiutil.FindIfSecretExists(secretList, secretName) {
- secretCertID := core.Secret{}
- secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, csrStatusResp.Certificate)
+ log.Info("Secret with cert-id will be updated")
+ secretCertID := pkiutil.GetSecretObject(req.Namespace, secretName, csrStatusResp.Certificate)
err = r.Client.Update(ctx, &secretCertID)
-
} else {
+ log.Info("New secret with cert-id will be created")
err = r.createSecret(ctx, req.Namespace, secretName, csrStatusResp.Certificate)
}
@@ -480,11 +437,11 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
+
}
+ // Stores the signed certificate data in the PEM chain
log.Info("Storing PEM...")
-
- // Stores the signed certificate data in the status
if ncmCfg.LittleEndianPem {
pemChain = append(pemChain, enduserCAInPEM...)
} else {
@@ -517,10 +474,10 @@ func (r *CertificateRequestReconciler) createSecret(ctx context.Context, namespa
func appendPem(cfg *ncmapi.NCMConfig, pemChain []byte, currentPem []byte) []byte {
if cfg.LittleEndianPem {
pemChain = append(currentPem, pemChain...)
- } else {
- pemChain = append(pemChain, currentPem...)
+ return pemChain
}
+ pemChain = append(pemChain, currentPem...)
return pemChain
}
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 5b13310..b50dc63 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -11,24 +11,30 @@ import (
func TestNewClientCreation(t *testing.T) {
tests := []struct {
- name string
- cfg *NCMConfig
+ name string
+ cfg *NCMConfig
+ expectedClient *Client
+ expectedError error
}{
{
- name: "invalidNCMServerURL",
+ name: "invalid NCM EXTERNAL API URL",
cfg: &NCMConfig{
NcmSERVER: "https://malformed url.com:80",
},
+ expectedClient: nil,
+ expectedError: &ClientError{},
},
{
- name: "invalidNCMServer2URL",
+ name: "invalid 2nd NCM EXTERNAL API URL",
cfg: &NCMConfig{
NcmSERVER: "https://working-url.com:3000",
NcmSERVER2: "https://malformed url.com:-17",
},
+ expectedClient: nil,
+ expectedError: &ClientError{},
},
{
- name: "invalidKeyPair",
+ name: "invalid key pair",
cfg: &NCMConfig{
NcmSERVER: "https://working-url.com:3000",
NcmSERVER2: "https://working-url2.com:3000",
@@ -38,9 +44,11 @@ func TestNewClientCreation(t *testing.T) {
InsecureSkipVerify: false,
MTLS: true,
},
+ expectedClient: nil,
+ expectedError: &ClientError{},
},
{
- name: "properClientCreation",
+ name: "proper client creation",
cfg: &NCMConfig{
Username: "user",
UsrPassword: "password",
@@ -52,62 +60,57 @@ func TestNewClientCreation(t *testing.T) {
InsecureSkipVerify: true,
MTLS: false,
},
+ expectedClient: &Client{},
+ expectedError: nil,
},
}
for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- log := testr.TestLogger{T: t}
- if client, err := NewClient(tt.cfg, log); err != nil {
- assert.ErrorIs(t, err, err.(*ClientError))
- } else {
- assert.IsType(t, &Client{}, client)
- }
- })
+ log := testr.TestLogger{T: t}
+ client, err := NewClient(tt.cfg, log)
+ assert.IsType(t, tt.expectedClient, client, "%s failed", tt.name)
+ assert.IsType(t, tt.expectedError, err, "%s failed", tt.name)
}
}
func TestResponseValidation(t *testing.T) {
tests := []struct {
- name string
- resp *http.Response
+ name string
+ resp *http.Response
+ expectedError error
}{
{
- name: "notValidResponse",
+ name: "not valid response",
resp: &http.Response{
StatusCode: 400,
Body: io.NopCloser(bytes.NewReader([]byte(`{"message": "", "status": 400, "statusMessage": "Bad Request"}`))),
},
+ expectedError: &APIError{},
},
{
- name: "validResponse",
+ name: "valid response",
resp: &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewReader([]byte(`{"random": "field"}`))),
},
+ expectedError: nil,
},
}
for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- log := testr.TestLogger{T: t}
- client, _ := NewClient(&NCMConfig{
- Username: "user",
- UsrPassword: "password",
- NcmSERVER: "https://working-url.com:3000",
- NcmSERVER2: "",
- CACert: "CACert",
- Key: "Key",
- Cert: "Cert",
- InsecureSkipVerify: true,
- MTLS: false,
- }, log)
-
- if body, err := client.validateResponse(tt.resp); err != nil {
- assert.ErrorIs(t, err, err.(*APIError))
- } else {
- assert.IsType(t, []byte("random-field"), body)
- }
- })
+ log := testr.TestLogger{T: t}
+ client, _ := NewClient(&NCMConfig{
+ Username: "user",
+ UsrPassword: "password",
+ NcmSERVER: "https://working-url.com:3000",
+ NcmSERVER2: "",
+ CACert: "CACert",
+ Key: "Key",
+ Cert: "Cert",
+ InsecureSkipVerify: true,
+ MTLS: false,
+ }, log)
+ _, err := client.validateResponse(tt.resp)
+ assert.IsType(t, tt.expectedError, err, "%s failed", tt.name)
}
}
diff --git a/pkg/pkiutil/util.go b/pkg/pkiutil/util.go
index a6ad0a6..61d38c2 100644
--- a/pkg/pkiutil/util.go
+++ b/pkg/pkiutil/util.go
@@ -35,15 +35,12 @@ func GetSecretNamespace(issuer client.Object, req ctrl.Request) (string, error)
}
func FindIfSecretExists(secretList v1.SecretList, secretName string) bool {
- ifSecretExists := false
-
for _, secret := range secretList.Items {
if secret.Name == secretName {
- ifSecretExists = true
- break
+ return true
}
}
- return ifSecretExists
+ return false
}
func GetSecretObject(namespace string, name string, certID string) v1.Secret {
diff --git a/release_notes.txt b/release_notes.txt
index a625b9b..7d4e096 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -15,7 +15,11 @@ Version 1.0.0 (Build Version 0.1.149)
- Support for cert-manager using API v1
Version 1.0.1 (Build Version 1.0.0)
-- Added Ncm Issuer version to logging
+- Added NCM Issuer version to logging
Version 1.0.2 (Build Version 1.0.1)
- Update go version to 1.17
+
+Version 1.0.3 (Build Version 1.0.2)
+- Added possibility to specify secondary NCM EXTERNAL API server in case of lack of connection to the main one
+- Fixed misinterpretation in case of manually triggering rotation of a private key
\ No newline at end of file
From 6898cff8ccd16e8af6f39b1ce035c150797f8f9f Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 8 Feb 2023 17:54:16 +0100
Subject: [PATCH 052/175] Limited size of certificate name to 52 characters
---
helm/Chart.yaml | 4 +-
helm/values.yaml | 2 +-
.../certificaterequest_controller.go | 63 ++++++++-----------
release_notes.txt | 3 +-
4 files changed, 31 insertions(+), 41 deletions(-)
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
index b25e3d0..e551453 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -1,5 +1,5 @@
apiVersion: v1
-appVersion: "1.0.1"
+appVersion: "1.0.3"
description: A Helm chart for cert-manager external issuer with NCM( Netguard certficate
manager )
icon: https://cert-manager.io/images/high-level-overview.svg
@@ -14,4 +14,4 @@ maintainers:
- name: Maxwell Jiang
- name: Lilian Liang
name: ncm-issuer
-version: 1.0.3
+version: 1.0.2
diff --git a/helm/values.yaml b/helm/values.yaml
index d252697..38d612b 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -34,7 +34,7 @@ certManagerRbac:
binding: cert-manager-controller-approve:ncm-certmanager-nokia-com
role: cert-manager-controller-approve:ncm-certmanager-nokia-comv
-# since NCM is outside of k8s cluster, so need external connection with NCM.
+# since NCM is outside k8s cluster, so need external connection with NCM.
# edge control is generally used to connect external network.
# prefer edge node
controller:
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index fb4c5bc..ca3142e 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -141,7 +141,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerSpec, issuerStatus, err := pkiutil.GetSpecAndStatus(issuer)
if err != nil {
log.Error(err, "Fail to get spec and status for the issuer")
-
return ctrl.Result{}, nil
}
@@ -149,7 +148,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if issuerSpec.AuthNamespace == "" {
issuerSpec.AuthNamespace = "default"
}
-
secretNamespace = issuerSpec.AuthNamespace
}
@@ -160,7 +158,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}) {
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
"Failed: (Cluster)Issuer %s is not Ready; its condition is %s", issuerName, issuerStatus.Conditions)
-
return ctrl.Result{}, err
}
@@ -170,20 +167,23 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
Name: issuerName.Name}] == nil {
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
"Failed: CRD configuration %s/%s is not Ready; type,status in myCRD.Status.Conditions=%s, cfg is nil=%v", secretNamespace, issuerName.Name, issuerStatus.Conditions, NCMConfigMap)
-
return ctrl.Result{}, err
}
if apiutil.CertificateRequestIsDenied(&cr) {
log.V(4).Info("certificate request has been denied")
err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CSR has been denied")
-
return ctrl.Result{}, err
}
if !apiutil.CertificateRequestIsApproved(&cr) {
log.V(4).Info("certificate request has not been approved")
+ return ctrl.Result{}, nil
+ }
+ if err = validateCertificateRequest(&cr); err != nil {
+ log.Error(err, "certificate request has issues", "cr", req.NamespacedName)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Certificate request has issues: %v", err)
return ctrl.Result{}, nil
}
@@ -191,24 +191,16 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
ncmClient, err := ncmapi.NewClient(ncmCfg, log)
if err != nil {
log.Error(err, "failed to create NCM API Client")
-
- err = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
- if err != nil {
- log.Error(err, "failed to set certificate request status")
- }
-
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
return ctrl.Result{}, nil
}
var pemChain []byte
-
casResponse, err := ncmClient.GetCAs()
if err != nil {
log.Error(err, "failed to get CAs")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Please, check your external NCM server. Failed to get CAs; %v", err)
-
go r.waitAndGetCAs(ctx, req, &cr, ncmClient, log)
-
return ctrl.Result{}, nil
}
@@ -234,7 +226,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if wantedCA.Href == "" {
log.Error(err, "CA certificate has not been found. Please check provided CASHREF/CASNAME", "cashref", ncmCfg.CASHREF, "casname", ncmCfg.CASNAME)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found. Please check provided CASHREF/CASNAME URL=%s, CASNAME=%s, CASHREF=%s", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
-
return ctrl.Result{}, nil
}
@@ -250,7 +241,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download Certificate", "certURL", lastCA.Certificates["active"])
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
-
return ctrl.Result{}, nil
}
@@ -262,7 +252,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download PEM Certificate", "certURL", lastCA.Certificates["active"])
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
-
return ctrl.Result{}, nil
}
@@ -273,7 +262,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download CA certificate; %v", err)
-
return ctrl.Result{}, nil
}
}
@@ -292,12 +280,10 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download ROOT certificate")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download ROOT certificate; %v", err)
-
return ctrl.Result{}, nil
}
crt := cmapi.Certificate{}
-
positionToSlice := strings.LastIndex(req.Name, "-")
if err := r.Client.Get(ctx, client.ObjectKey{
Namespace: req.Namespace, Name: req.Name[:positionToSlice]}, &crt); err != nil {
@@ -317,22 +303,18 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
secretList, err := r.getSecretList(ctx, req)
if err != nil {
log.Error(err, "failed to list certificates resources")
-
return ctrl.Result{}, nil
}
switch {
case crt.Status.Revision != nil && *crt.Status.Revision >= 1 &&
!ncmCfg.ReenrollmentOnRenew && crt.Spec.PrivateKey.RotationPolicy != "Always":
- if pkiutil.FindIfSecretExists(secretList, secretName) && pkiutil.FindIfSecretExists(secretList, crt.ObjectMeta.Name) {
+ if pkiutil.FindIfSecretExists(secretList, secretName) && pkiutil.FindIfSecretExists(secretList, crt.Spec.SecretName) {
log.Info("Secret with cert-id will be updated")
-
secretCertID := core.Secret{}
- err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID)
- if err != nil {
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID); err != nil {
log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
-
return ctrl.Result{}, nil
}
@@ -343,7 +325,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to renewCertificate")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
-
return ctrl.Result{}, nil
}
@@ -353,19 +334,18 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
-
return ctrl.Result{}, nil
}
secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
- err = r.Client.Update(ctx, &secretCertID)
- if err != nil {
+ if err := r.Client.Update(ctx, &secretCertID); err != nil {
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
-
return ctrl.Result{}, nil
}
+
+ log.Info("Updated secret", "updatedSecret", secretCertID)
break
- } else if !pkiutil.FindIfSecretExists(secretList, crt.ObjectMeta.Name) {
+ } else if !pkiutil.FindIfSecretExists(secretList, crt.Spec.SecretName) {
log.Info("Manually rotation of a private key has been triggered")
}
fallthrough
@@ -374,7 +354,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed send CSR")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR cr.ObjectMeta.name=%s/%s; %v", cr.ObjectMeta.Name, cr.ObjectMeta.Namespace, err)
-
return ctrl.Result{}, nil
}
@@ -383,7 +362,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to check CSR status")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
-
return ctrl.Result{}, nil
}
@@ -407,7 +385,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if !validCSRStatus {
log.Error(err, "Invalid CSR Status")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid CSR Status status=%s, cr.meta=%v; %v", csrStatusResp.Status, cr.ObjectMeta, err)
-
return ctrl.Result{}, nil
}
@@ -417,7 +394,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to download enduser certificate", "certURL", csrStatusResp.Certificate)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download enduser certificate tmp_enduser_ca_InPEM=%v; %v", enduserCAInPEM, err)
-
return ctrl.Result{}, nil
}
@@ -434,7 +410,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "failed to create/update a secret with cert-id", "secretName", secretName)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create/update secret err=%v", err)
-
return ctrl.Result{}, nil
}
@@ -451,6 +426,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Set PEMs
cr.Status.Certificate = pemChain
cr.Status.CA = instaCAInPEM
+ log.Info("Certificate request at the end of the plugin execution", "certRequest", cr)
// Finally, update the status
return ctrl.Result{}, r.setStatus(ctx, &cr, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Successfully issued certificate")
@@ -633,6 +609,19 @@ func (r *CertificateRequestReconciler) SetupWithManager(mgr ctrl.Manager) error
Complete(r)
}
+func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
+ if len(cr.Spec.Request) == 0 {
+ return fmt.Errorf("certificate request is empty")
+ }
+
+ if cr.ObjectMeta.GenerateName[:len(cr.ObjectMeta.GenerateName)-1] != cr.Annotations[cmapi.CertificateNameKey] {
+ return fmt.Errorf("certificate name is too long, suggested name based on provided one: %s",
+ cr.ObjectMeta.GenerateName[:len(cr.ObjectMeta.GenerateName)-1])
+ }
+
+ return nil
+}
+
func checkCSRStatus(csrStatusResp *ncmapi.CSRStatusResponse) bool {
return strings.EqualFold(csrStatusResp.Status, "accepted")
}
diff --git a/release_notes.txt b/release_notes.txt
index 7d4e096..fe95855 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -22,4 +22,5 @@ Version 1.0.2 (Build Version 1.0.1)
Version 1.0.3 (Build Version 1.0.2)
- Added possibility to specify secondary NCM EXTERNAL API server in case of lack of connection to the main one
-- Fixed misinterpretation in case of manually triggering rotation of a private key
\ No newline at end of file
+- Fixed misinterpretation in case of manually triggering rotation of a private key
+- Limited size of certificate name to 52 characters
\ No newline at end of file
From 9bc76b65ebf447a52e964c349c98d98fb2e0399f Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 9 Feb 2023 19:43:39 +0100
Subject: [PATCH 053/175] Added posibility to include crt chain in ca.crt & did
some code refactor
---
api/v1/issuer_types.go | 1 +
...tmanager.ncm.nokia.com_clusterissuers.yaml | 6 +-
.../certmanager.ncm.nokia.com_issuers.yaml | 10 +-
.../certificaterequest_controller.go | 128 ++++++------------
pkg/controllers/issuer_controller.go | 23 +---
pkg/controllers/util.go | 59 ++++++++
pkg/ncmapi/ncmapi.go | 1 +
pkg/pkiutil/decode.go | 15 ++
release_notes.txt | 3 +-
9 files changed, 138 insertions(+), 108 deletions(-)
create mode 100644 pkg/controllers/util.go
diff --git a/api/v1/issuer_types.go b/api/v1/issuer_types.go
index 4341c3e..ecb8d6e 100644
--- a/api/v1/issuer_types.go
+++ b/api/v1/issuer_types.go
@@ -38,6 +38,7 @@ type IssuerSpec struct {
ReenrollmentOnRenew bool `json:"reenrollmentOnRenew"`
UseProfileIDForRenew bool `json:"useProfileIDForRenew"`
NoRoot bool `json:"noRoot"`
+ ChainInSigner bool `json:"chainInSigner"`
// The secret which contains REST API username and password
AuthSecretName string `json:"secretName"`
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
index e8bd170..fbbe12b 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
@@ -49,13 +49,15 @@ spec:
CASHREF:
type: string
littleEndian:
- type: boolean
+ type: boolean
reenrollmentOnRenew:
type: boolean
useProfileIDForRenew:
type: boolean
noRoot:
- type: boolean
+ type: boolean
+ chainInSigner:
+ type: boolean
authNameSpace:
type: string
ncmSERVER:
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
index 859fa50..6b18d3c 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
@@ -55,7 +55,9 @@ spec:
useProfileIDForRenew:
type: boolean
noRoot:
- type: boolean
+ type: boolean
+ chainInSigner:
+ type: boolean
authNameSpace:
type: string
ncmSERVER:
@@ -63,9 +65,9 @@ spec:
are supported
type: string
ncmSERVER2:
- description: Define secondary external NCM REST API URL in case of the lack of
- connection to the main one
- type: string
+ description: Define secondary external NCM REST API URL in case of the
+ lack of connection to the main one
+ type: string
profileId:
description: ProfileId API parameter
type: string
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index ca3142e..97e3a80 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -19,7 +19,6 @@ package controllers
import (
"context"
"fmt"
- "regexp"
"strings"
"time"
@@ -191,11 +190,10 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
ncmClient, err := ncmapi.NewClient(ncmCfg, log)
if err != nil {
log.Error(err, "failed to create NCM API Client")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
return ctrl.Result{}, nil
}
- var pemChain []byte
casResponse, err := ncmClient.GetCAs()
if err != nil {
log.Error(err, "failed to get CAs")
@@ -205,33 +203,17 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
// Finds the certificate for bcmtncm
- wantedCA := &ncmapi.CAResponse{}
- hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
-
- for _, ca := range casResponse.CAList {
- if strings.EqualFold(ca.Status, "active") {
- if ncmCfg.CASHREF != "" {
- href := hrefRegex.Find([]byte(ca.Href))
- if strings.EqualFold(string(href), ncmCfg.CASHREF) {
- wantedCA = &ca
- break
- }
- } else if strings.EqualFold(ca.Name, ncmCfg.CASNAME) {
- wantedCA = &ca
- break
- }
- }
- }
-
- if wantedCA.Href == "" {
- log.Error(err, "CA certificate has not been found. Please check provided CASHREF/CASNAME", "cashref", ncmCfg.CASHREF, "casname", ncmCfg.CASNAME)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found. Please check provided CASHREF/CASNAME URL=%s, CASNAME=%s, CASHREF=%s", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
+ issuingCA, found := findCA(casResponse, ncmCfg.CASHREF, ncmCfg.CASNAME)
+ if !found {
+ log.Info("CA certificate has not been found, please check provided CAsHREF/CAsNAME", "CAsHREF", ncmCfg.CASHREF, "CAsNAME", ncmCfg.CASNAME)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found, please check provided CAsHREF/CAsNAME URL=%s, CAsNAME=%s, CAsHREF=%s", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
return ctrl.Result{}, nil
}
+ var crtChain []byte
// Finds the root CA
instaCA := &ncmapi.CAResponse{}
- lastCA := wantedCA
+ lastCA := issuingCA
for {
log.Info("lastCA href: ", "href", lastCA.Href)
@@ -239,7 +221,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
lastCAURLPath, _ := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
currentCert, err := ncmClient.DownloadCertificate(lastCAURLPath)
if err != nil {
- log.Error(err, "failed to download Certificate", "certURL", lastCA.Certificates["active"])
+ log.Error(err, "failed to download certificate", "certURL", lastCA.Certificates["active"])
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
return ctrl.Result{}, nil
}
@@ -250,12 +232,11 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
currentCertInPEM, err := ncmClient.DownloadCertificateInPEM(lastCAURLPath)
if err != nil {
- log.Error(err, "failed to download PEM Certificate", "certURL", lastCA.Certificates["active"])
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
+ log.Error(err, "failed to download certificate in PEM", "certURL", lastCA.Certificates["active"])
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate in PEM; %v", err)
return ctrl.Result{}, nil
}
-
- pemChain = appendPem(ncmCfg, pemChain, currentCertInPEM)
+ crtChain = addCertToChain(currentCertInPEM, crtChain, ncmCfg.LittleEndianPem)
lastCAURLPATH, _ := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
lastCA, err = ncmClient.GetCA(lastCAURLPATH)
@@ -266,38 +247,37 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
}
- if ncmCfg.NoRoot {
- instaCA = wantedCA
- log.Info("Found Issuer: ", "issuer", instaCA.Name)
+ if ncmCfg.NoRoot && !ncmCfg.ChainInSigner {
+ instaCA = issuingCA
+ log.Info("Issuing CA certificate was found: ", "issuingCA", instaCA.Name)
} else {
instaCA = lastCA
- log.Info("Found root CA: ", "rootCA", instaCA.Name)
+ log.Info("Root CA certificate was found: ", "rootCA", instaCA.Name)
}
- // Downloads root CA certificate
+ // Downloads root CA certificate or issuing CA certificate
instaCAURLPath, _ := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
instaCAInPEM, err := ncmClient.DownloadCertificateInPEM(instaCAURLPath)
if err != nil {
- log.Error(err, "failed to download ROOT certificate")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download ROOT certificate; %v", err)
+ log.Error(err, "failed to download root CA certificate or issuing CA certificate")
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download root CA certificate or issuing CA certificate; %v", err)
return ctrl.Result{}, nil
}
crt := cmapi.Certificate{}
- positionToSlice := strings.LastIndex(req.Name, "-")
if err := r.Client.Get(ctx, client.ObjectKey{
- Namespace: req.Namespace, Name: req.Name[:positionToSlice]}, &crt); err != nil {
+ Namespace: req.Namespace, Name: cr.Annotations[cmapi.CertificateNameKey]}, &crt); err != nil {
log.Error(err, "certificate object not found!")
return ctrl.Result{}, nil
}
- var enduserCAInPEM []byte
- var secretName = req.Name[:positionToSlice] + "-details"
+ var leafCertInPEM []byte
+ var secretName = cr.Annotations[cmapi.CertificateNameKey] + "-details"
if crt.Status.Revision != nil {
- log.Info("revision value fetched", "revision", crt.Status.Revision)
+ log.Info("Revision value was fetched", "revision", crt.Status.Revision)
} else {
- log.Info("revision value is set to nil")
+ log.Info("Revision value is set to nil")
}
secretList, err := r.getSecretList(ctx, req)
@@ -323,14 +303,14 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
certURLPath, _ := ncmapi.GetPathFromCertURL(string(secretCertID.Data["cert-id"]))
renewCertResp, err := ncmClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
if err != nil {
- log.Error(err, "failed to renewCertificate")
+ log.Error(err, "failed to renew certificate")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
return ctrl.Result{}, nil
}
// Downloads the renewed certificate
renewedCertURLPath, _ := ncmapi.GetPathFromCertURL(renewCertResp.Certificate)
- enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
+ leafCertInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
if err != nil {
log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
@@ -342,15 +322,13 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
return ctrl.Result{}, nil
}
-
- log.Info("Updated secret", "updatedSecret", secretCertID)
break
} else if !pkiutil.FindIfSecretExists(secretList, crt.Spec.SecretName) {
log.Info("Manually rotation of a private key has been triggered")
}
fallthrough
default:
- csrResp, err := ncmClient.SendCSR(cr.Spec.Request, wantedCA, issuerSpec.ProfileId)
+ csrResp, err := ncmClient.SendCSR(cr.Spec.Request, issuingCA, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed send CSR")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR cr.ObjectMeta.name=%s/%s; %v", cr.ObjectMeta.Name, cr.ObjectMeta.Namespace, err)
@@ -383,17 +361,17 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
if !validCSRStatus {
- log.Error(err, "Invalid CSR Status")
+ log.Error(err, "Invalid CSR status")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid CSR Status status=%s, cr.meta=%v; %v", csrStatusResp.Status, cr.ObjectMeta, err)
return ctrl.Result{}, nil
}
- // Downloads enduser certificate
- enduserCAURLPath, _ := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
- enduserCAInPEM, err = ncmClient.DownloadCertificateInPEM(enduserCAURLPath)
+ // Downloads end-entity (leaf) certificate
+ leafCertURLPath, _ := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
+ leafCertInPEM, err = ncmClient.DownloadCertificateInPEM(leafCertURLPath)
if err != nil {
- log.Error(err, "failed to download enduser certificate", "certURL", csrStatusResp.Certificate)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download enduser certificate tmp_enduser_ca_InPEM=%v; %v", enduserCAInPEM, err)
+ log.Error(err, "failed to download end-entity certificate", "certURL", csrStatusResp.Certificate)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download end-entity certificate tmp_endentity_ca_InPEM=%v; %v", leafCertInPEM, err)
return ctrl.Result{}, nil
}
@@ -417,16 +395,19 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Stores the signed certificate data in the PEM chain
log.Info("Storing PEM...")
- if ncmCfg.LittleEndianPem {
- pemChain = append(pemChain, enduserCAInPEM...)
- } else {
- pemChain = append(enduserCAInPEM, pemChain...)
- }
// Set PEMs
- cr.Status.Certificate = pemChain
- cr.Status.CA = instaCAInPEM
- log.Info("Certificate request at the end of the plugin execution", "certRequest", cr)
+ var crtChainWithRoot []byte
+ crtChainWithRoot = append(crtChainWithRoot, crtChain...)
+ crtChain = addLeafCertToChain(leafCertInPEM, crtChain, ncmCfg.LittleEndianPem)
+ if ncmCfg.ChainInSigner {
+ crtChainWithRoot = addCertToChain(instaCAInPEM, crtChainWithRoot, ncmCfg.LittleEndianPem)
+ cr.Status.CA = crtChainWithRoot
+ cr.Status.Certificate = crtChain
+ } else {
+ cr.Status.CA = instaCAInPEM
+ cr.Status.Certificate = crtChain
+ }
// Finally, update the status
return ctrl.Result{}, r.setStatus(ctx, &cr, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Successfully issued certificate")
@@ -447,16 +428,6 @@ func (r *CertificateRequestReconciler) createSecret(ctx context.Context, namespa
return err
}
-func appendPem(cfg *ncmapi.NCMConfig, pemChain []byte, currentPem []byte) []byte {
- if cfg.LittleEndianPem {
- pemChain = append(currentPem, pemChain...)
- return pemChain
- }
-
- pemChain = append(pemChain, currentPem...)
- return pemChain
-}
-
func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.CertificateRequest, status cmmeta.ConditionStatus, reason, message string, args ...interface{}) error {
// Formats the message and updates the myCRD variable with the new Condition
completeMessage := fmt.Sprintf(message, args...)
@@ -609,19 +580,6 @@ func (r *CertificateRequestReconciler) SetupWithManager(mgr ctrl.Manager) error
Complete(r)
}
-func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
- if len(cr.Spec.Request) == 0 {
- return fmt.Errorf("certificate request is empty")
- }
-
- if cr.ObjectMeta.GenerateName[:len(cr.ObjectMeta.GenerateName)-1] != cr.Annotations[cmapi.CertificateNameKey] {
- return fmt.Errorf("certificate name is too long, suggested name based on provided one: %s",
- cr.ObjectMeta.GenerateName[:len(cr.ObjectMeta.GenerateName)-1])
- }
-
- return nil
-}
-
func checkCSRStatus(csrStatusResp *ncmapi.CSRStatusResponse) bool {
return strings.EqualFold(csrStatusResp.Status, "accepted")
}
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index a79fd49..0e4bbd1 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -98,8 +98,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}()
// check Spec
- invalidStr := checkIssuerSpec(issuerSpec)
- if len(invalidStr) != 0 {
+ if invalidStr := checkIssuerSpec(issuerSpec); len(invalidStr) != 0 {
reason = "incorrect setting"
err = errors.New(reason)
completeMessage = fmt.Sprintf("Incorrect Spec config: %v", invalidStr)
@@ -121,8 +120,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}
- err = checkNCMSecretData(&caSecret)
- if err != nil {
+ if err = checkNCMSecretData(&caSecret); err != nil {
reason = "incorrect setting"
completeMessage = fmt.Sprintf("incorrect Auth Secret setting: %v", err)
log.Error(err, "incorrect Auth Secret setting")
@@ -145,6 +143,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
cfg.ReenrollmentOnRenew = issuerSpec.ReenrollmentOnRenew
cfg.UseProfileIDForRenew = issuerSpec.UseProfileIDForRenew
cfg.NoRoot = issuerSpec.NoRoot
+ cfg.ChainInSigner = issuerSpec.ChainInSigner
///////////////////////
cfg.InsecureSkipVerify = true
@@ -157,8 +156,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
log.Error(err, "failed to retrieve tls Secret")
return ctrl.Result{}, err
}
- err = populateNCMTLSConfData(&tlsConfSecret, &cfg)
- if err != nil {
+ if err = populateNCMTLSConfData(&tlsConfSecret, &cfg); err != nil {
reason = "incorrect TLS setting"
completeMessage = fmt.Sprintf("TLS secret config setting population is incorrect: %v", err)
log.Error(err, "TLS secret config setting population is incorrect")
@@ -302,15 +300,8 @@ func populateNCMTLSConfData(tlsConfSecret *core.Secret, cfg *ncmapi.NCMConfig) e
cfg.Cert = certPath
}
- cfg.InsecureSkipVerify = true
- if cfg.CACert != "" {
- cfg.InsecureSkipVerify = false
- }
-
- cfg.MTLS = false
- if cfg.Key != "" && cfg.Cert != "" {
- cfg.MTLS = true
- }
+ cfg.InsecureSkipVerify = cfg.CACert == ""
+ cfg.MTLS = cfg.Key != "" && cfg.Cert != ""
if cfg.CACert == "" && cfg.Key == "" && cfg.Cert == "" {
return fmt.Errorf("no useful data cacert, key or cert in Ttls secret")
@@ -326,7 +317,7 @@ func checkIssuerSpec(issuerSpec *certmanagerv1.IssuerSpec) string {
}
if len(issuerSpec.CASNAME) == 0 && len(issuerSpec.CASHREF) == 0 {
- invalidStr += "The CASNAME or CASHREF should not be empty."
+ invalidStr += "The CAsNAME or CAsHREF should not be empty."
}
return invalidStr
diff --git a/pkg/controllers/util.go b/pkg/controllers/util.go
new file mode 100644
index 0000000..f147764
--- /dev/null
+++ b/pkg/controllers/util.go
@@ -0,0 +1,59 @@
+package controllers
+
+import (
+ "fmt"
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
+ "github.com/nokia/ncm-issuer/pkg/pkiutil"
+ "regexp"
+ "strings"
+
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+)
+
+func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
+ if len(cr.Spec.Request) == 0 {
+ return fmt.Errorf("certificate request is empty")
+ }
+
+ csr, err := pkiutil.DecodeX509CertificateRequestBytes(cr.Spec.Request)
+ if err != nil {
+ return fmt.Errorf("failed to decode CSR for validation: %v", err)
+ }
+
+ if len(csr.Subject.CommonName) == 0 && len(csr.IPAddresses) == 0 && len(csr.DNSNames) == 0 && len(csr.EmailAddresses) == 0 {
+ return fmt.Errorf("at least one of field should be included in certificate spec: commonName, ipAddresses, dnsNames or emailAddresses")
+ }
+
+ return nil
+}
+
+func findCA(casResponse *ncmapi.CAsResponse, CAsHREF, CAsNAME string) (*ncmapi.CAResponse, bool) {
+ hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
+ for _, ca := range casResponse.CAList {
+ if strings.EqualFold(ca.Status, "active") {
+ if CAsHREF != "" {
+ href := hrefRegex.Find([]byte(ca.Href))
+ if strings.EqualFold(string(href), CAsHREF) {
+ return &ca, true
+ }
+ } else if strings.EqualFold(ca.Name, CAsNAME) {
+ return &ca, true
+ }
+ }
+ }
+ return nil, false
+}
+
+func addCertToChain(crt, crtChain []byte, littleEndian bool) []byte {
+ if littleEndian {
+ return append(crt, crtChain...)
+ }
+ return append(crtChain, crt...)
+}
+
+func addLeafCertToChain(leafCrt, crtChain []byte, littleEndian bool) []byte {
+ if littleEndian {
+ return append(crtChain, leafCrt...)
+ }
+ return append(leafCrt, crtChain...)
+}
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index e66faf8..56d8cc8 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -38,6 +38,7 @@ type NCMConfig struct {
InstaCA string // NCM root CA
LittleEndianPem bool // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
NoRoot bool // determines whether Issuer of the Cert should be taken into consideration instead of root
+ ChainInSigner bool // determines whether certificate chain should be included in ca.crt
CACert string // TLS CA Cert
Key string // TLS client Key
Cert string // TLS client Cert
diff --git a/pkg/pkiutil/decode.go b/pkg/pkiutil/decode.go
index 24cc1e9..84c48ac 100644
--- a/pkg/pkiutil/decode.go
+++ b/pkg/pkiutil/decode.go
@@ -105,3 +105,18 @@ func DecodeX509CertificateBytes(certBytes []byte) (*x509.Certificate, error) {
return certs[0], nil
}
+
+// DecodeX509CertificateRequestBytes will decode a PEM encoded x509 Certificate Request.
+func DecodeX509CertificateRequestBytes(csrBytes []byte) (*x509.CertificateRequest, error) {
+ block, _ := pem.Decode(csrBytes)
+ if block == nil {
+ return nil, fmt.Errorf("error decoding certificate request PEM block")
+ }
+
+ csr, err := x509.ParseCertificateRequest(block.Bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ return csr, nil
+}
diff --git a/release_notes.txt b/release_notes.txt
index fe95855..3f6e6e0 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -23,4 +23,5 @@ Version 1.0.2 (Build Version 1.0.1)
Version 1.0.3 (Build Version 1.0.2)
- Added possibility to specify secondary NCM EXTERNAL API server in case of lack of connection to the main one
- Fixed misinterpretation in case of manually triggering rotation of a private key
-- Limited size of certificate name to 52 characters
\ No newline at end of file
+- Fixed bug related to getting certificate object when the certificate name is long
+- Added possibility to include certificate chain in ca.crt
\ No newline at end of file
From 8e8f9bf451fcdf0f648b446faa48cdd713b03267 Mon Sep 17 00:00:00 2001
From: raczu
Date: Mon, 13 Feb 2023 14:20:42 +0100
Subject: [PATCH 054/175] Changed method of checking CA to exact match
---
pkg/controllers/util.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pkg/controllers/util.go b/pkg/controllers/util.go
index f147764..f86c097 100644
--- a/pkg/controllers/util.go
+++ b/pkg/controllers/util.go
@@ -33,10 +33,10 @@ func findCA(casResponse *ncmapi.CAsResponse, CAsHREF, CAsNAME string) (*ncmapi.C
if strings.EqualFold(ca.Status, "active") {
if CAsHREF != "" {
href := hrefRegex.Find([]byte(ca.Href))
- if strings.EqualFold(string(href), CAsHREF) {
+ if string(href) == CAsHREF {
return &ca, true
}
- } else if strings.EqualFold(ca.Name, CAsNAME) {
+ } else if ca.Name == CAsNAME {
return &ca, true
}
}
From 2cc89c20adc226eae8581d37e8129ac36d57c8eb Mon Sep 17 00:00:00 2001
From: raczu
Date: Mon, 13 Feb 2023 14:52:04 +0100
Subject: [PATCH 055/175] Updated README
---
README.md | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index eab21de..22dca74 100644
--- a/README.md
+++ b/README.md
@@ -129,7 +129,7 @@ $ kubectl -n NAMESPACE describe secrets SECRET_NAME
NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities, but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.
-### Create an issuer
+### Create an issuer or cluster issuer
Issuer .yaml file with all available options:
@@ -145,12 +145,16 @@ spec:
CASNAME: CERTIFICATE_NAME_FROM_NCM
CASHREF: HREF_FROM_NCM
ncmSERVER: ADDR_TO_NCM
+ ncmSERVER2: ADDR_TO_NCM2
+ chainInSigner: false (or true)
profileId: PROFILE_ID
reenrollmentOnRenew: false (or true)
useProfileIDForRenew: false (or true)
noRoot: false (or true)
```
+#### Issuer or cluster issuer fields
+
For **kind** variable use either Issuer for namespaced one or ClusterIssuer for cluster level issuer.
For **name** variable use some descriptive name of your choice for your issuing CA. This name will be used by your CNFs / applications.
@@ -163,7 +167,11 @@ For **tlsSecretName** use the secret name with TLS certificate.
For **CASNAME** use the CA name from NCM web UI visible under 'CA Hierarchy'. Please do not use CA's CN or DN, but CA name as plainly visible in the UI.
-For **ncmSERVER** please use your NCM REST API service URL.
+For **ncmSERVER** specify your NCM REST API service URL.
+
+If the **ncmSERVER2** field is defined, it will try to make the same query to the second provided NCM REST API service URL in case of lack of connection to the main one.
+
+Setting the **chainInSigner** field to "true" ensure that certificate chain will be included in **ca.crt** (intermediate certificates + issuing certificate + root CA).
If the **profileId** field is defined, then the profile ID will be set in enrollment requests, so it is included in the issued certificates.
From 64bb09cf0d2a0ee2fb360349b43d779dc468f5b6 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 16 Feb 2023 15:28:02 +0100
Subject: [PATCH 056/175] Added posibility to include only end-entity
certificate in tls.crt
---
Dockerfile | 3 +-
api/v1/issuer_types.go | 19 ++-
...tmanager.ncm.nokia.com_clusterissuers.yaml | 2 +
.../certmanager.ncm.nokia.com_issuers.yaml | 2 +
main.go | 4 +-
.../certificaterequest_controller.go | 79 +++++----
pkg/controllers/issuer_controller.go | 24 ++-
pkg/controllers/issuer_controller_test.go | 30 ++--
pkg/ncmapi/ncmapi.go | 159 ++++++++++++------
pkg/ncmapi/ncmapi_test.go | 18 +-
pkg/pkiutil/util.go | 4 +-
release_notes.txt | 8 +-
12 files changed, 203 insertions(+), 149 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index efa0cf1..b86f8f9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -26,5 +26,4 @@ WORKDIR /
COPY --from=builder /builds/manager .
USER 65532:65532
-ENTRYPOINT ["/manager"]
-
+ENTRYPOINT ["/manager"]
\ No newline at end of file
diff --git a/api/v1/issuer_types.go b/api/v1/issuer_types.go
index ecb8d6e..18916ef 100644
--- a/api/v1/issuer_types.go
+++ b/api/v1/issuer_types.go
@@ -23,22 +23,23 @@ import (
// IssuerSpec defines the desired state of Issuer
type IssuerSpec struct {
// Define external NCM REST API URL here, as of now http/https are supported
- NcmSERVER string `json:"ncmSERVER"`
+ NCMServer string `json:"ncmSERVER"`
// +optional
// Secondary external NCM REST API URL in case of lack of connection to the main one
- NcmSERVER2 string `json:"ncmSERVER2"`
+ NCMServer2 string `json:"ncmSERVER2"`
// The name of the logical CA on the NCM instance.
// make sure the names are unique across whole NCM installation
- CASNAME string `json:"CASNAME"`
+ CAsName string `json:"CASNAME"`
- CASHREF string `json:"CASHREF"`
+ CAsHREF string `json:"CASHREF"`
LittleEndian bool `json:"littleEndian"`
ReenrollmentOnRenew bool `json:"reenrollmentOnRenew"`
UseProfileIDForRenew bool `json:"useProfileIDForRenew"`
NoRoot bool `json:"noRoot"`
ChainInSigner bool `json:"chainInSigner"`
+ OnlyEECert bool `json:"onlyEECert"`
// The secret which contains REST API username and password
AuthSecretName string `json:"secretName"`
@@ -50,13 +51,13 @@ type IssuerSpec struct {
// +optional
// The secret which contains TLS configuration to external NCM server
// the secret must contain 3 fields:
- // cacert for root CA; key, cert for client CA and key pair.
+ // CA certificate for root CA certificate; key, cert for client CA certificate and key pair.
//
// for https connection,
- // if the field is absent, InsecureSkipVerify is used.
- // if the field is with cacert only, cacert is used.
- // if the field are with cacert, key,cert, mtls is used.
- TlsSecretName string `json:"tlsSecretName"`
+ // if the field is empty, InsecureSkipVerify is used.
+ // if the field is with CA certificate only, CA certificate is used.
+ // if the field are with CA certificate, key, cert and mTLS is used.
+ TLSSecretName string `json:"tlsSecretName"`
// +optional
AuthNamespace string `json:"authNameSpace,omitempty"`
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
index fbbe12b..c74bfb2 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
@@ -58,6 +58,8 @@ spec:
type: boolean
chainInSigner:
type: boolean
+ onlyEECert:
+ type: boolean
authNameSpace:
type: string
ncmSERVER:
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
index 6b18d3c..e6a431f 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
@@ -58,6 +58,8 @@ spec:
type: boolean
chainInSigner:
type: boolean
+ onlyEECert:
+ type: boolean
authNameSpace:
type: string
ncmSERVER:
diff --git a/main.go b/main.go
index 8aa6a98..e29062e 100644
--- a/main.go
+++ b/main.go
@@ -40,7 +40,7 @@ import (
var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
- ncmIssuerVersion = "1.0.1"
+ NCMIssuerVersion = "1.0.2"
)
const setupErrMsg = "unable to create controller"
@@ -72,7 +72,7 @@ func main() {
setupLog.Info(
"starting",
- "version", ncmIssuerVersion,
+ "version", NCMIssuerVersion,
"enable-leader-election", enableLeaderElection,
"metrics-addr", metricsAddr,
)
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 97e3a80..164c3a5 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -49,7 +49,6 @@ type CertificateRequestReconciler struct {
Recorder record.EventRecorder
}
-// ///////////////////////////////////
var (
// CertificateRequestPendingList CertificateRequest pending list, only one should be queued
CertificateRequestPendingList = make(map[CertificateRequestPendingKey]*CertificateRequestPendingState)
@@ -70,8 +69,6 @@ const (
SleepTime = 20000 // in time.Millisecond, 20s
)
-/////////////////////////////////////
-
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=get;list;watch;update
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests/status,verbs=get;update;patch
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
@@ -115,7 +112,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- // get Issuer or ClusterIssuer resource
+ // Get Issuer or ClusterIssuer resource
issuer := issuerRO.(client.Object)
var secretNamespace string
@@ -186,31 +183,31 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- ncmCfg := NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}]
- ncmClient, err := ncmapi.NewClient(ncmCfg, log)
+ NCMCfg := NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}]
+ NCMClient, err := ncmapi.NewClient(NCMCfg, log)
if err != nil {
log.Error(err, "failed to create NCM API Client")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
return ctrl.Result{}, nil
}
- casResponse, err := ncmClient.GetCAs()
+ casResponse, err := NCMClient.GetCAs()
if err != nil {
log.Error(err, "failed to get CAs")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Please, check your external NCM server. Failed to get CAs; %v", err)
- go r.waitAndGetCAs(ctx, req, &cr, ncmClient, log)
+ go r.waitAndGetCAs(ctx, req, &cr, NCMClient, log)
return ctrl.Result{}, nil
}
// Finds the certificate for bcmtncm
- issuingCA, found := findCA(casResponse, ncmCfg.CASHREF, ncmCfg.CASNAME)
+ issuingCA, found := findCA(casResponse, NCMCfg.CAsHREF, NCMCfg.CAsName)
if !found {
- log.Info("CA certificate has not been found, please check provided CAsHREF/CAsNAME", "CAsHREF", ncmCfg.CASHREF, "CAsNAME", ncmCfg.CASNAME)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found, please check provided CAsHREF/CAsNAME URL=%s, CAsNAME=%s, CAsHREF=%s", ncmCfg.NcmSERVER+ncmapi.CAsURL, ncmCfg.CASNAME, ncmCfg.CASHREF)
+ log.Info("CA certificate has not been found, please check provided CAsHREF/CAsNAME", "CAsHREF", NCMCfg.CAsHREF, "CAsNAME", NCMCfg.CAsName)
+ _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found, please check provided CAsHREF/CAsNAME URL=%s, CAsNAME=%s, CAsHREF=%s", NCMCfg.NCMServer+ncmapi.CAsURL, NCMCfg.CAsName, NCMCfg.CAsHREF)
return ctrl.Result{}, nil
}
- var crtChain []byte
+ var certChain []byte
// Finds the root CA
instaCA := &ncmapi.CAResponse{}
lastCA := issuingCA
@@ -219,7 +216,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Info("lastCA href: ", "href", lastCA.Href)
lastCAURLPath, _ := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
- currentCert, err := ncmClient.DownloadCertificate(lastCAURLPath)
+ currentCert, err := NCMClient.DownloadCertificate(lastCAURLPath)
if err != nil {
log.Error(err, "failed to download certificate", "certURL", lastCA.Certificates["active"])
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
@@ -230,16 +227,16 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
break
}
- currentCertInPEM, err := ncmClient.DownloadCertificateInPEM(lastCAURLPath)
+ currentCertInPEM, err := NCMClient.DownloadCertificateInPEM(lastCAURLPath)
if err != nil {
log.Error(err, "failed to download certificate in PEM", "certURL", lastCA.Certificates["active"])
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate in PEM; %v", err)
return ctrl.Result{}, nil
}
- crtChain = addCertToChain(currentCertInPEM, crtChain, ncmCfg.LittleEndianPem)
+ certChain = addCertToChain(currentCertInPEM, certChain, NCMCfg.LittleEndianPem)
lastCAURLPATH, _ := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
- lastCA, err = ncmClient.GetCA(lastCAURLPATH)
+ lastCA, err = NCMClient.GetCA(lastCAURLPATH)
if err != nil {
log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download CA certificate; %v", err)
@@ -247,7 +244,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
}
- if ncmCfg.NoRoot && !ncmCfg.ChainInSigner {
+ if NCMCfg.NoRoot && !NCMCfg.ChainInSigner {
instaCA = issuingCA
log.Info("Issuing CA certificate was found: ", "issuingCA", instaCA.Name)
} else {
@@ -257,7 +254,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Downloads root CA certificate or issuing CA certificate
instaCAURLPath, _ := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
- instaCAInPEM, err := ncmClient.DownloadCertificateInPEM(instaCAURLPath)
+ instaCAInPEM, err := NCMClient.DownloadCertificateInPEM(instaCAURLPath)
if err != nil {
log.Error(err, "failed to download root CA certificate or issuing CA certificate")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download root CA certificate or issuing CA certificate; %v", err)
@@ -288,11 +285,11 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
switch {
case crt.Status.Revision != nil && *crt.Status.Revision >= 1 &&
- !ncmCfg.ReenrollmentOnRenew && crt.Spec.PrivateKey.RotationPolicy != "Always":
+ !NCMCfg.ReenrollmentOnRenew && crt.Spec.PrivateKey.RotationPolicy != "Always":
if pkiutil.FindIfSecretExists(secretList, secretName) && pkiutil.FindIfSecretExists(secretList, crt.Spec.SecretName) {
log.Info("Secret with cert-id will be updated")
- secretCertID := core.Secret{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, &secretCertID); err != nil {
+ secretCertID := &core.Secret{}
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
return ctrl.Result{}, nil
@@ -301,7 +298,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Info("Certificate href has been fetched", "href", string(secretCertID.Data["cert-id"]))
certURLPath, _ := ncmapi.GetPathFromCertURL(string(secretCertID.Data["cert-id"]))
- renewCertResp, err := ncmClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
+ renewCertResp, err := NCMClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed to renew certificate")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
@@ -310,7 +307,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Downloads the renewed certificate
renewedCertURLPath, _ := ncmapi.GetPathFromCertURL(renewCertResp.Certificate)
- leafCertInPEM, err = ncmClient.DownloadCertificateInPEM(renewedCertURLPath)
+ leafCertInPEM, err = NCMClient.DownloadCertificateInPEM(renewedCertURLPath)
if err != nil {
log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
@@ -318,7 +315,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
- if err := r.Client.Update(ctx, &secretCertID); err != nil {
+ if err := r.Client.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
return ctrl.Result{}, nil
}
@@ -328,7 +325,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
fallthrough
default:
- csrResp, err := ncmClient.SendCSR(cr.Spec.Request, issuingCA, issuerSpec.ProfileId)
+ csrResp, err := NCMClient.SendCSR(cr.Spec.Request, issuingCA, issuerSpec.ProfileId)
if err != nil {
log.Error(err, "failed send CSR")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR cr.ObjectMeta.name=%s/%s; %v", cr.ObjectMeta.Name, cr.ObjectMeta.Namespace, err)
@@ -336,7 +333,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
requestedCertURLPath, _ := ncmapi.GetPathFromCertURL(csrResp.Href)
- csrStatusResp, err := ncmClient.CheckCSRStatus(requestedCertURLPath)
+ csrStatusResp, err := NCMClient.CheckCSRStatus(requestedCertURLPath)
if err != nil {
log.Error(err, "failed to check CSR status")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
@@ -355,7 +352,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Error(err, "CSR status is pending")
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
- go r.waitAndCheckCSRStatus(ctx, req, &cr, ncmClient, requestedCertURLPath, log)
+ go r.waitAndCheckCSRStatus(ctx, req, &cr, NCMClient, requestedCertURLPath, log)
return ctrl.Result{}, nil
}
@@ -368,7 +365,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Downloads end-entity (leaf) certificate
leafCertURLPath, _ := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
- leafCertInPEM, err = ncmClient.DownloadCertificateInPEM(leafCertURLPath)
+ leafCertInPEM, err = NCMClient.DownloadCertificateInPEM(leafCertURLPath)
if err != nil {
log.Error(err, "failed to download end-entity certificate", "certURL", csrStatusResp.Certificate)
_ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download end-entity certificate tmp_endentity_ca_InPEM=%v; %v", leafCertInPEM, err)
@@ -379,7 +376,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if pkiutil.FindIfSecretExists(secretList, secretName) {
log.Info("Secret with cert-id will be updated")
secretCertID := pkiutil.GetSecretObject(req.Namespace, secretName, csrStatusResp.Certificate)
- err = r.Client.Update(ctx, &secretCertID)
+ err = r.Client.Update(ctx, secretCertID)
} else {
log.Info("New secret with cert-id will be created")
err = r.createSecret(ctx, req.Namespace, secretName, csrStatusResp.Certificate)
@@ -397,16 +394,20 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Info("Storing PEM...")
// Set PEMs
- var crtChainWithRoot []byte
- crtChainWithRoot = append(crtChainWithRoot, crtChain...)
- crtChain = addLeafCertToChain(leafCertInPEM, crtChain, ncmCfg.LittleEndianPem)
- if ncmCfg.ChainInSigner {
- crtChainWithRoot = addCertToChain(instaCAInPEM, crtChainWithRoot, ncmCfg.LittleEndianPem)
- cr.Status.CA = crtChainWithRoot
- cr.Status.Certificate = crtChain
+ if NCMCfg.ChainInSigner {
+ var certChainWithRoot []byte
+ certChainWithRoot = append(certChainWithRoot, certChain...)
+ certChainWithRoot = addCertToChain(instaCAInPEM, certChainWithRoot, NCMCfg.LittleEndianPem)
+ cr.Status.CA = certChainWithRoot
} else {
cr.Status.CA = instaCAInPEM
- cr.Status.Certificate = crtChain
+ }
+
+ if !NCMCfg.OnlyEECert {
+ certChain = addLeafCertToChain(leafCertInPEM, certChain, NCMCfg.LittleEndianPem)
+ cr.Status.Certificate = certChain
+ } else {
+ cr.Status.Certificate = leafCertInPEM
}
// Finally, update the status
@@ -423,7 +424,7 @@ func (r *CertificateRequestReconciler) getSecretList(ctx context.Context, req ct
func (r *CertificateRequestReconciler) createSecret(ctx context.Context, namespace string, name string, certID string) error {
secret := pkiutil.GetSecretObject(namespace, name, certID)
- err := r.Client.Create(ctx, &secret)
+ err := r.Client.Create(ctx, secret)
return err
}
@@ -453,8 +454,6 @@ func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.
return nil
}
-// ////////////////////////////////////
-
// waitAndGetCAs waits and frequently checks to see if the NCM server is responding (NCM API client tries to get CAs).
// When the server responds to a request for CAs triggers new round of reconcile
func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, client *ncmapi.Client, log logr.Logger) {
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index 0e4bbd1..b571f92 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -131,26 +131,24 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
populateNCMConfData(&caSecret, &cfg)
// in case suffix "/" is present removes it
- cfg.NcmSERVER = strings.TrimSuffix(issuerSpec.NcmSERVER, "/")
- if issuerSpec.NcmSERVER2 != "" {
- cfg.NcmSERVER2 = strings.TrimSuffix(issuerSpec.NcmSERVER2, "/")
- }
-
- cfg.CASNAME = issuerSpec.CASNAME
- cfg.CASHREF = issuerSpec.CASHREF
- cfg.InstaCA = issuerSpec.CASNAME
+ cfg.NCMServer = strings.TrimSuffix(issuerSpec.NCMServer, "/")
+ cfg.NCMServer2 = strings.TrimSuffix(issuerSpec.NCMServer2, "/")
+ cfg.CAsName = issuerSpec.CAsName
+ cfg.CAsHREF = issuerSpec.CAsHREF
+ cfg.InstaCA = issuerSpec.CAsName
cfg.LittleEndianPem = issuerSpec.LittleEndian
cfg.ReenrollmentOnRenew = issuerSpec.ReenrollmentOnRenew
cfg.UseProfileIDForRenew = issuerSpec.UseProfileIDForRenew
cfg.NoRoot = issuerSpec.NoRoot
cfg.ChainInSigner = issuerSpec.ChainInSigner
+ cfg.OnlyEECert = issuerSpec.OnlyEECert
///////////////////////
cfg.InsecureSkipVerify = true
- if issuerSpec.TlsSecretName != "" {
- // Fetch the ncm tls Secret
+ if issuerSpec.TLSSecretName != "" {
+ // Fetch the NCM TLS secret
tlsConfSecret := core.Secret{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: issuerSpec.TlsSecretName}, &tlsConfSecret); err != nil {
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: issuerSpec.TLSSecretName}, &tlsConfSecret); err != nil {
reason = "NotFound"
completeMessage = fmt.Sprintf("Failed to retrieve tls Secret: %v", err)
log.Error(err, "failed to retrieve tls Secret")
@@ -312,11 +310,11 @@ func populateNCMTLSConfData(tlsConfSecret *core.Secret, cfg *ncmapi.NCMConfig) e
func checkIssuerSpec(issuerSpec *certmanagerv1.IssuerSpec) string {
invalidStr := ""
- if len(issuerSpec.NcmSERVER) == 0 {
+ if len(issuerSpec.NCMServer) == 0 {
invalidStr = "The ncmSERVER should not be empty. "
}
- if len(issuerSpec.CASNAME) == 0 && len(issuerSpec.CASHREF) == 0 {
+ if len(issuerSpec.CAsName) == 0 && len(issuerSpec.CAsHREF) == 0 {
invalidStr += "The CAsNAME or CAsHREF should not be empty."
}
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 556c621..594edce 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -50,17 +50,17 @@ func TestIssuerReconcile(t *testing.T) {
Name: "issuer",
Namespace: "ncm-issuer",
}, Spec: nokiaAPI.IssuerSpec{
- NcmSERVER: "127.0.0.1",
- NcmSERVER2: "",
- CASNAME: "CA1",
- CASHREF: "kdhu84hrjl",
+ NCMServer: "127.0.0.1",
+ NCMServer2: "",
+ CAsName: "CA1",
+ CAsHREF: "kdhu84hrjl",
LittleEndian: true,
ReenrollmentOnRenew: true,
UseProfileIDForRenew: true,
NoRoot: true,
AuthSecretName: "secretName1",
ProfileId: "100",
- TlsSecretName: "secretName2",
+ TLSSecretName: "secretName2",
},
Status: nokiaAPI.IssuerStatus{Conditions: []nokiaAPI.IssuerCondition{
{Type: "",
@@ -107,17 +107,17 @@ func TestIssuerReconcile(t *testing.T) {
Name: "clsissuer",
Namespace: "ncm-issuer",
}, Spec: nokiaAPI.IssuerSpec{
- NcmSERVER: "127.0.0.1",
- NcmSERVER2: "",
- CASNAME: "CA1",
- CASHREF: "kdhu84hrjl",
+ NCMServer: "127.0.0.1",
+ NCMServer2: "",
+ CAsName: "CA1",
+ CAsHREF: "kdhu84hrjl",
LittleEndian: true,
ReenrollmentOnRenew: true,
UseProfileIDForRenew: true,
NoRoot: true,
AuthSecretName: "secretName1",
ProfileId: "100",
- TlsSecretName: "secretName2",
+ TLSSecretName: "secretName2",
AuthNamespace: "namespaceAuth",
},
Status: nokiaAPI.IssuerStatus{Conditions: []nokiaAPI.IssuerCondition{
@@ -165,17 +165,17 @@ func TestIssuerReconcile(t *testing.T) {
Name: "issuer",
Namespace: "ncm-issuer",
}, Spec: nokiaAPI.IssuerSpec{
- NcmSERVER: "",
- NcmSERVER2: "",
- CASNAME: "CA1",
- CASHREF: "kdhu84hrjl",
+ NCMServer: "",
+ NCMServer2: "",
+ CAsName: "CA1",
+ CAsHREF: "kdhu84hrjl",
LittleEndian: true,
ReenrollmentOnRenew: true,
UseProfileIDForRenew: true,
NoRoot: true,
AuthSecretName: "secretName1",
ProfileId: "100",
- TlsSecretName: "secretName2",
+ TLSSecretName: "secretName2",
},
Status: nokiaAPI.IssuerStatus{Conditions: []nokiaAPI.IssuerCondition{
{Type: "",
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 56d8cc8..f0d0355 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -20,53 +20,99 @@ import (
)
const (
- HTTPTimeout = 10
- CAsURL = "/v1/cas"
- CSRURL = "/v1/requests"
+ DefaultHTTPTimeout = 10
+ CAsURL = "/v1/cas"
+ CSRURL = "/v1/requests"
)
-// NCMConfig set up with secret and used for NCM API Client configuration
+// NCMConfig is a config set up with secret and used for NCM API Client configuration
type NCMConfig struct {
- Username string
- UsrPassword string
- NcmSERVER string
- NcmSERVER2 string
- CASNAME string // CAs for bcmtncm
- CASHREF string // href for bcmtncm
- ReenrollmentOnRenew bool
+ Username string
+ UsrPassword string
+ NCMServer string
+ NCMServer2 string
+
+ // CAsName is a CAs for bcmtncm
+ CAsName string
+
+ // CAsHREF is a HREF for bcmtncm
+ CAsHREF string
+
+ // ReenrollmentOnRenew determines whether during renewal certificate
+ // should be re-enrolled instead of renewed
+ ReenrollmentOnRenew bool
+
UseProfileIDForRenew bool
- InstaCA string // NCM root CA
- LittleEndianPem bool // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
- NoRoot bool // determines whether Issuer of the Cert should be taken into consideration instead of root
- ChainInSigner bool // determines whether certificate chain should be included in ca.crt
- CACert string // TLS CA Cert
- Key string // TLS client Key
- Cert string // TLS client Cert
- InsecureSkipVerify bool // determines whether SSL certificate verification between client instance and NCM EXTERNAL API should be enabled
- MTLS bool // determines whether mTLS should be enabled
+
+ // InstaCA is a NCM root CA
+ InstaCA string
+
+ // LittleEndianPem determines
+ LittleEndianPem bool // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
+
+ // NoRoot determines whether issuing CA certificate should be included
+ // in ca.crt instead of root CA certificate
+ NoRoot bool
+
+ // ChainInSigner determines whether certificate chain should be included in ca.crt
+ // (intermediate certificates + issuing CA certificate + root CA certificate)
+ ChainInSigner bool
+
+ // OnlyEECert determines whether only end-entity certificate should be included
+ // in tls.crt
+ OnlyEECert bool
+
+ // CACert is a TLS CA certificate
+ CACert string
+
+ // Key is a TLS client key
+ Key string
+
+ // Cert is a TLS client certificate
+ Cert string
+
+ // InsecureSkipVerify determines whether SSL certificate verification between client
+ // instance and NCM EXTERNAL API should be enabled
+ InsecureSkipVerify bool
+
+ // MTLS determines whether mTLS should be enabled
+ MTLS bool
}
-// NCMConfigKey used to separate different configurations for different namespaces
+// NCMConfigKey is a structure used to separate different configurations for
+// different namespaces
type NCMConfigKey struct {
Namespace string
Name string
}
-// Client used to communicate with the NCM EXTERNAL API
+// Client is a client used to communicate with the NCM EXTERNAL API
type Client struct {
- ncmServer string // main NCM EXTERNAL API server address
- ncmServer2 string // Secondary NCM EXTERNAL API server address in case of the lack of connection to the main one (can be empty)
- user string // user used for authentication to NCM EXTERNAL API
- password string // password used for authentication to NCM EXTERNAL API
-
- // Determines whether, in the case of lack of the connection to the main server (no response within
- // a certain time period), there is an address of a second server to which client can send the
- // same request
+ // NCMServer is a main NCM EXTERNAL API server address
+ NCMServer string
+
+ // NCMServer2 is a secondary NCM EXTERNAL API server address
+ // in case of the lack of connection to the main one (can be empty)
+ NCMServer2 string
+
+ // user is a user used for authentication to NCM EXTERNAL API
+ user string
+
+ // password is a password used for authentication to NCM EXTERNAL API
+ password string
+
+ // allowRetry determines whether, in the case of lack of the connection
+ // to the main server (no response within a certain time period
+ // or 5XX status code), there is an address of a second server to which
+ // client can send the same request
allowRetry bool
- useProfileIDForRenew bool // determines whether the profile ID should be used during a certificate renewal operation
- client *http.Client
- log logr.Logger
+ // userProfileIDForRenew determines whether the profile ID should be used
+ // during a certificate renewal operation
+ useProfileIDForRenew bool
+
+ client *http.Client
+ log logr.Logger
}
type ClientError struct {
@@ -133,14 +179,15 @@ func (a *APIError) Error() string {
return fmt.Sprintf("NCM EXTERNAL API Error status=%d, message=%s, statusMessage=%s", a.Status, a.Message, a.StatusMessage)
}
-// NewClient creates a new client used to perform requests to the NCM EXTERNAL API
+// NewClient creates a new client used to perform requests to
+// the NCM EXTERNAL API
func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
- ncmServerURL, err := url.Parse(cfg.NcmSERVER)
+ NCMServerURL, err := url.Parse(cfg.NCMServer)
if err != nil {
return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
}
- ncmServer2URL, err := url.Parse(cfg.NcmSERVER2)
+ NCMServer2URL, err := url.Parse(cfg.NCMServer2)
if err != nil {
return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
}
@@ -151,9 +198,9 @@ func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
}
c := &Client{
- ncmServer: ncmServerURL.String(),
- ncmServer2: ncmServer2URL.String(),
- allowRetry: cfg.NcmSERVER2 != "",
+ NCMServer: NCMServerURL.String(),
+ NCMServer2: NCMServer2URL.String(),
+ allowRetry: cfg.NCMServer2 != "",
user: cfg.Username,
password: cfg.UsrPassword,
useProfileIDForRenew: cfg.UseProfileIDForRenew,
@@ -164,11 +211,12 @@ func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
return c, nil
}
-// Configures http.Client used for connection to NCM EXTERNAL API according to NCM config
+// configureHTTPClient configures http.Client used for connection
+// to NCM EXTERNAL API according to NCM config
func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
- if !strings.HasPrefix(cfg.NcmSERVER, "https") {
+ if !strings.HasPrefix(cfg.NCMServer, "https") {
client := &http.Client{
- Timeout: HTTPTimeout * time.Second,
+ Timeout: DefaultHTTPTimeout * time.Second,
}
return client, nil
@@ -200,9 +248,10 @@ func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
}
}
- // Creates an HTTPS client and supply it with created CA pool (and client CA if mTLS is enabled)
+ // Creates an HTTPS client and supply it with created CA pool
+ // (and client CA if mTLS is enabled)
client := &http.Client{
- Timeout: HTTPTimeout * time.Second,
+ Timeout: DefaultHTTPTimeout * time.Second,
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
@@ -212,10 +261,10 @@ func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
}
func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
- ncmServerURL, _ := url.Parse(c.ncmServer)
- ncmServerURL.Path = path
+ NCMServerURL, _ := url.Parse(c.NCMServer)
+ NCMServerURL.Path = path
- req, err := http.NewRequest(method, ncmServerURL.String(), body)
+ req, err := http.NewRequest(method, NCMServerURL.String(), body)
if err != nil {
return nil, &ClientError{Reason: "cannot create new request", ErrorMessage: err}
}
@@ -228,15 +277,15 @@ func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request,
}
func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
- c.log.Info("retrying request to secondary NCM EXTERNAL API", "serverURL", c.ncmServer2)
- ncmServer2URL, _ := url.Parse(c.ncmServer2)
- req.URL.Host = ncmServer2URL.Host
+ c.log.Info("retrying request to secondary NCM EXTERNAL API", "serverURL", c.NCMServer2)
+ NCMServer2URL, _ := url.Parse(c.NCMServer2)
+ req.URL.Host = NCMServer2URL.Host
resp, err := c.client.Do(req)
if err != nil {
return nil, &ClientError{Reason: "cannot perform request", ErrorMessage: err}
}
- c.log.Info("received proper response from secondary NCM EXTERNAL API", "serverURL", c.ncmServer2)
+ c.log.Info("received response from secondary NCM EXTERNAL API", "serverURL", c.NCMServer2, "status", resp.StatusCode)
return resp, nil
}
@@ -265,8 +314,8 @@ func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
resp, err := c.client.Do(req)
if err != nil {
- if c.allowRetry && os.IsTimeout(err) {
- c.log.Info("main NCM EXTERNAL API seems not responding", "serverURL", c.ncmServer, "err", err)
+ c.log.Info("main NCM EXTERNAL API seems not responding", "serverURL", c.NCMServer, "err", err)
+ if c.allowRetry {
resp, err = c.retryRequest(req)
if err != nil {
return nil, err
@@ -276,8 +325,8 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
return nil, err
}
- if c.allowRetry && resp.StatusCode == http.StatusInternalServerError {
- c.log.Info("main NCM EXTERNAL API cannot handle request", "serverURL", c.ncmServer, "status", resp.StatusCode)
+ if c.allowRetry && resp.StatusCode >= 500 && resp.StatusCode < 600 {
+ c.log.Info("main NCM EXTERNAL API returned server error status code", "serverURL", c.NCMServer, "status", resp.StatusCode)
resp, err = c.retryRequest(req)
if err != nil {
return nil, err
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index b50dc63..27cebc2 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -19,7 +19,7 @@ func TestNewClientCreation(t *testing.T) {
{
name: "invalid NCM EXTERNAL API URL",
cfg: &NCMConfig{
- NcmSERVER: "https://malformed url.com:80",
+ NCMServer: "https://malformed url.com:80",
},
expectedClient: nil,
expectedError: &ClientError{},
@@ -27,8 +27,8 @@ func TestNewClientCreation(t *testing.T) {
{
name: "invalid 2nd NCM EXTERNAL API URL",
cfg: &NCMConfig{
- NcmSERVER: "https://working-url.com:3000",
- NcmSERVER2: "https://malformed url.com:-17",
+ NCMServer: "https://working-url.com:3000",
+ NCMServer2: "https://malformed url.com:-17",
},
expectedClient: nil,
expectedError: &ClientError{},
@@ -36,8 +36,8 @@ func TestNewClientCreation(t *testing.T) {
{
name: "invalid key pair",
cfg: &NCMConfig{
- NcmSERVER: "https://working-url.com:3000",
- NcmSERVER2: "https://working-url2.com:3000",
+ NCMServer: "https://working-url.com:3000",
+ NCMServer2: "https://working-url2.com:3000",
CACert: "CACert",
Key: "Key",
Cert: "Cert",
@@ -52,8 +52,8 @@ func TestNewClientCreation(t *testing.T) {
cfg: &NCMConfig{
Username: "user",
UsrPassword: "password",
- NcmSERVER: "https://working-url.com:3000",
- NcmSERVER2: "",
+ NCMServer: "https://working-url.com:3000",
+ NCMServer2: "",
CACert: "CACert",
Key: "Key",
Cert: "Cert",
@@ -102,8 +102,8 @@ func TestResponseValidation(t *testing.T) {
client, _ := NewClient(&NCMConfig{
Username: "user",
UsrPassword: "password",
- NcmSERVER: "https://working-url.com:3000",
- NcmSERVER2: "",
+ NCMServer: "https://working-url.com:3000",
+ NCMServer2: "",
CACert: "CACert",
Key: "Key",
Cert: "Cert",
diff --git a/pkg/pkiutil/util.go b/pkg/pkiutil/util.go
index 61d38c2..ab233b1 100644
--- a/pkg/pkiutil/util.go
+++ b/pkg/pkiutil/util.go
@@ -43,7 +43,7 @@ func FindIfSecretExists(secretList v1.SecretList, secretName string) bool {
return false
}
-func GetSecretObject(namespace string, name string, certID string) v1.Secret {
+func GetSecretObject(namespace string, name string, certID string) *v1.Secret {
secret := v1.Secret{
ObjectMeta: v12.ObjectMeta{
Namespace: namespace,
@@ -54,7 +54,7 @@ func GetSecretObject(namespace string, name string, certID string) v1.Secret {
},
Type: v1.SecretTypeOpaque,
}
- return secret
+ return &secret
}
// MyCRDHasCondition will return true if the given MyCRD has a
diff --git a/release_notes.txt b/release_notes.txt
index 3f6e6e0..c2434e6 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -21,7 +21,11 @@ Version 1.0.2 (Build Version 1.0.1)
- Update go version to 1.17
Version 1.0.3 (Build Version 1.0.2)
-- Added possibility to specify secondary NCM EXTERNAL API server in case of lack of connection to the main one
+- Added possibility to specify secondary NCM EXTERNAL API server in case of lack of connection to the main one,
+ server is specified as a parameter "ncmSERVER2" in issuer or cluster issuer yaml file
- Fixed misinterpretation in case of manually triggering rotation of a private key
- Fixed bug related to getting certificate object when the certificate name is long
-- Added possibility to include certificate chain in ca.crt
\ No newline at end of file
+- Added possibility to include certificate chain in ca.crt by setting "chainInSigner" in issuer or cluster issuer
+ yaml file to "true"
+- Added possibility to include only end-entity certificate in tls.crt by setting "onlyEECert" in issuer or cluster
+ issuer yaml file to "true"
\ No newline at end of file
From 2eab746525fe1367e9c31a381cf88e9d83898c7b Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 16 Feb 2023 15:29:46 +0100
Subject: [PATCH 057/175] Updated README
---
README.md | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 22dca74..178477e 100644
--- a/README.md
+++ b/README.md
@@ -146,15 +146,14 @@ spec:
CASHREF: HREF_FROM_NCM
ncmSERVER: ADDR_TO_NCM
ncmSERVER2: ADDR_TO_NCM2
- chainInSigner: false (or true)
profileId: PROFILE_ID
+ chainInSigner: false (or true)
+ onlyEECert: false (or true)
reenrollmentOnRenew: false (or true)
useProfileIDForRenew: false (or true)
noRoot: false (or true)
```
-#### Issuer or cluster issuer fields
-
For **kind** variable use either Issuer for namespaced one or ClusterIssuer for cluster level issuer.
For **name** variable use some descriptive name of your choice for your issuing CA. This name will be used by your CNFs / applications.
@@ -171,9 +170,11 @@ For **ncmSERVER** specify your NCM REST API service URL.
If the **ncmSERVER2** field is defined, it will try to make the same query to the second provided NCM REST API service URL in case of lack of connection to the main one.
+If the **profileId** field is defined, then the profile ID will be set in enrollment requests, so it is included in the issued certificates.
+
Setting the **chainInSigner** field to "true" ensure that certificate chain will be included in **ca.crt** (intermediate certificates + issuing certificate + root CA).
-If the **profileId** field is defined, then the profile ID will be set in enrollment requests, so it is included in the issued certificates.
+Setting the **onlyEECert** field to "true" ensure that only end-entity certificate will be included in **tls.crt**
Setting the **useProfileIDForRenew** field to “true” is necessary to include the defined profileID value in the */update* request during the renewal process. Otherwise, certificate update operations won’t include it.
From c6d145c02f3e4b740d7b814bf145c92e8a187f46 Mon Sep 17 00:00:00 2001
From: raczu
Date: Tue, 21 Feb 2023 18:24:02 +0100
Subject: [PATCH 058/175] Bumped go from 1.17 to 1.19.6
---
Dockerfile | 2 +-
README.md | 2 +-
go.mod | 2 +-
main.go | 2 +-
pkg/controllers/certificaterequest_controller.go | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index b86f8f9..83da19a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Build the manager binary
-FROM golang:1.17 AS builder
+FROM golang:1.19.6 AS builder
WORKDIR /
# COPY . ./
diff --git a/README.md b/README.md
index 178477e..1650f5f 100644
--- a/README.md
+++ b/README.md
@@ -174,7 +174,7 @@ If the **profileId** field is defined, then the profile ID will be set in enroll
Setting the **chainInSigner** field to "true" ensure that certificate chain will be included in **ca.crt** (intermediate certificates + issuing certificate + root CA).
-Setting the **onlyEECert** field to "true" ensure that only end-entity certificate will be included in **tls.crt**
+Setting the **onlyEECert** field to "true" ensure that only end-entity certificate will be included in **tls.crt**.
Setting the **useProfileIDForRenew** field to “true” is necessary to include the defined profileID value in the */update* request during the renewal process. Otherwise, certificate update operations won’t include it.
diff --git a/go.mod b/go.mod
index 698b931..c6a6447 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/nokia/ncm-issuer
-go 1.17
+go 1.19
require (
github.com/go-logr/logr v0.4.0
diff --git a/main.go b/main.go
index e29062e..b1f9e0c 100644
--- a/main.go
+++ b/main.go
@@ -40,7 +40,7 @@ import (
var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
- NCMIssuerVersion = "1.0.2"
+ NCMIssuerVersion = "1.0.3"
)
const setupErrMsg = "unable to create controller"
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 164c3a5..61c284d 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -142,7 +142,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if cr.Spec.IssuerRef.Kind == "ClusterIssuer" {
if issuerSpec.AuthNamespace == "" {
- issuerSpec.AuthNamespace = "default"
+ issuerSpec.AuthNamespace = metav1.NamespaceDefault
}
secretNamespace = issuerSpec.AuthNamespace
}
From 523299d23e6322baa6148416e6e5db33fe25305e Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 12:58:31 +0100
Subject: [PATCH 059/175] Added provisioner for better handling CSR returned by
NCM
---
pkg/ncmapi/ncmapi.go | 4 +-
pkg/ncmapi/util.go | 59 ------
pkg/pkiutil/util.go | 73 -------
pkg/provisioner/ncm.go | 310 ++++++++++++++++++++++++++++++
pkg/provisioner/pendingcsr.go | 69 +++++++
pkg/provisioner/util.go | 44 +++++
pkg/{pkiutil => util}/csr.go | 0
pkg/{pkiutil => util}/decode.go | 0
pkg/util/file.go | 97 ++++++++++
pkg/{pkiutil => util}/validate.go | 0
10 files changed, 522 insertions(+), 134 deletions(-)
delete mode 100644 pkg/ncmapi/util.go
delete mode 100644 pkg/pkiutil/util.go
create mode 100644 pkg/provisioner/ncm.go
create mode 100644 pkg/provisioner/pendingcsr.go
create mode 100644 pkg/provisioner/util.go
rename pkg/{pkiutil => util}/csr.go (100%)
rename pkg/{pkiutil => util}/decode.go (100%)
create mode 100644 pkg/util/file.go
rename pkg/{pkiutil => util}/validate.go (100%)
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index f0d0355..0a37daa 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -121,7 +121,7 @@ type ClientError struct {
}
func (c *ClientError) Error() string {
- return fmt.Sprintf("NCM API Client Error reason=%s err=%v", c.Reason, c.ErrorMessage)
+ return fmt.Sprintf("NCM API Client Error reason: %s, err: %v", c.Reason, c.ErrorMessage)
}
type CAsResponse struct {
@@ -176,7 +176,7 @@ type APIError struct {
}
func (a *APIError) Error() string {
- return fmt.Sprintf("NCM EXTERNAL API Error status=%d, message=%s, statusMessage=%s", a.Status, a.Message, a.StatusMessage)
+ return fmt.Sprintf("NCM EXTERNAL API Error status: %d, message: %s, statusMessage: %s", a.Status, a.Message, a.StatusMessage)
}
// NewClient creates a new client used to perform requests to
diff --git a/pkg/ncmapi/util.go b/pkg/ncmapi/util.go
deleted file mode 100644
index 9f1cfc7..0000000
--- a/pkg/ncmapi/util.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package ncmapi
-
-import (
- "crypto/rand"
- "fmt"
- "io"
- "net/url"
- "os"
-)
-
-// Generates a random UUID according to RFC 4122
-func newUUID() (string, error) {
- uuid := make([]byte, 16)
- n, err := io.ReadFull(rand.Reader, uuid)
- if n != len(uuid) || err != nil {
- return "", err
- }
- // variant bits; see section 4.1.1
- uuid[8] = uuid[8]&^0xc0 | 0x80
- // version 4 (pseudo-random); see section 4.1.3
- uuid[6] = uuid[6]&^0xf0 | 0x40
- return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
-}
-
-// Writes PEM to temp file (dirprefix is dir prefix)
-func WritePemToTempFile(dirprefix string, pem []byte) (string, error) {
- myuuid, err := newUUID()
- if err != nil {
- return "", err
- }
-
- // path := "/tmp/ncm_new.pem"
- path := dirprefix + myuuid + ".pem"
-
- // write CSRPEM into csrfile
- csrfile, err := os.Create(path)
- if err != nil {
- // return nil, err, "no such file"
- return path, err
- }
- _, err = csrfile.Write(pem)
- if err != nil {
- // return nil, err, "err to write file"
- return path, err
- }
- csrfile.Sync()
- csrfile.Close()
-
- return path, err
-}
-
-func GetPathFromCertURL(certURL string) (string, error) {
- parsedURL, err := url.Parse(certURL)
- if err != nil {
- return "", fmt.Errorf("cannot parsed given URL: url=%s", certURL)
- }
-
- return parsedURL.Path, nil
-}
diff --git a/pkg/pkiutil/util.go b/pkg/pkiutil/util.go
deleted file mode 100644
index ab233b1..0000000
--- a/pkg/pkiutil/util.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package pkiutil
-
-import (
- "fmt"
- cmv1 "github.com/nokia/ncm-issuer/api/v1"
- "k8s.io/api/core/v1"
- v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-func GetSpecAndStatus(issuer client.Object) (*cmv1.IssuerSpec, *cmv1.IssuerStatus, error) {
- switch t := issuer.(type) {
- case *cmv1.Issuer:
- return &t.Spec, &t.Status, nil
- case *cmv1.ClusterIssuer:
- return &t.Spec, &t.Status, nil
- default:
- return nil, nil, fmt.Errorf("not an issuer type: %t", t)
- }
-}
-
-func GetSecretNamespace(issuer client.Object, req ctrl.Request) (string, error) {
- switch t := issuer.(type) {
- case *cmv1.Issuer:
- return req.Namespace, nil
- case *cmv1.ClusterIssuer:
- if t.Spec.AuthNamespace == "" {
- t.Spec.AuthNamespace = "default"
- }
- return t.Spec.AuthNamespace, nil
- default:
- return "", fmt.Errorf("not an issuer type: %t", t)
- }
-}
-
-func FindIfSecretExists(secretList v1.SecretList, secretName string) bool {
- for _, secret := range secretList.Items {
- if secret.Name == secretName {
- return true
- }
- }
- return false
-}
-
-func GetSecretObject(namespace string, name string, certID string) *v1.Secret {
- secret := v1.Secret{
- ObjectMeta: v12.ObjectMeta{
- Namespace: namespace,
- Name: name,
- },
- StringData: map[string]string{
- "cert-id": certID,
- },
- Type: v1.SecretTypeOpaque,
- }
- return &secret
-}
-
-// MyCRDHasCondition will return true if the given MyCRD has a
-// condition matching the provided MyCRDCondition.
-// Only the Type and Status field will be used in the comparison, meaning that
-// this function will return 'true' even if the Reason, Message and
-// LastTransitionTime fields do not match.
-func MyCRDHasCondition(status cmv1.IssuerStatus, c cmv1.IssuerCondition) bool {
- existingConditions := status.Conditions
- for _, cond := range existingConditions {
- if c.Type == cond.Type && c.Status == cond.Status {
- return true
- }
- }
- return false
-}
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
new file mode 100644
index 0000000..b917859
--- /dev/null
+++ b/pkg/provisioner/ncm.go
@@ -0,0 +1,310 @@
+package provisioner
+
+import (
+ "errors"
+ "fmt"
+ "sync"
+
+ "github.com/go-logr/logr"
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+ "github.com/nokia/ncm-issuer/pkg/cfg"
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
+ "k8s.io/apimachinery/pkg/types"
+)
+
+const (
+ // SingleCSRCheckLimit defines limit for checking single CSR status returned by NCM.
+ // In case of need for manual approval ncm-issuer gives operator around 24h (1440m) to
+ // accept CSR manually in NCM before rejecting that request.
+ SingleCSRCheckLimit = 1440
+
+ CSRStatusAccepted = "accepted"
+ CSRStatusApproved = "approved"
+ CSRStatusPending = "pending"
+ CSRStatusPostponed = "postponed"
+ CSRStatusRejected = "rejected"
+)
+
+var (
+ ErrFailedGetCAs = errors.New("failed to get CAs")
+ ErrCSRNotAccepted = errors.New("CSR has not been accepted yet")
+ ErrCSRRejected = errors.New("CSR has been rejected")
+ ErrCSRCheckLimitExceeded = errors.New("CSR has not been accepted for too long")
+)
+
+// ProvisionersMap stores prepared (NCM API Client is configured) and ready to
+// use provisioner.
+type ProvisionersMap struct {
+ provisioners map[types.NamespacedName]*Provisioner
+ mu sync.RWMutex
+}
+
+func NewProvisionersMap() *ProvisionersMap {
+ return &ProvisionersMap{
+ provisioners: map[types.NamespacedName]*Provisioner{},
+ mu: sync.RWMutex{},
+ }
+}
+
+func (pm *ProvisionersMap) Get(NamespacedName types.NamespacedName) (*Provisioner, bool) {
+ pm.mu.RLock()
+ defer pm.mu.RUnlock()
+
+ p, ok := pm.provisioners[NamespacedName]
+ return p, ok
+}
+
+func (pm *ProvisionersMap) AddOrReplace(NamespacedName types.NamespacedName, provisioner *Provisioner) {
+ pm.mu.Lock()
+ defer pm.mu.Unlock()
+
+ if _, ok := pm.provisioners[NamespacedName]; !ok {
+ pm.provisioners[NamespacedName] = provisioner
+ } else {
+ // The existing provisioner has been found, but IssuerReconcile
+ // was triggered again, which may involve a change in configuration.
+ delete(pm.provisioners, NamespacedName)
+ pm.provisioners[NamespacedName] = provisioner
+ }
+}
+
+// Provisioner allows Sign or Renew certificate using NCMClient.
+type Provisioner struct {
+ NCMConfig *cfg.NCMConfig
+ NCMClient *ncmapi.Client
+ pendingCSRs *PendingCSRsMap
+ log logr.Logger
+}
+
+func NewProvisioner(NCMCfg *cfg.NCMConfig, log logr.Logger) (*Provisioner, error) {
+ c, err := ncmapi.NewClient(NCMCfg, log)
+ if err != nil {
+ return nil, err
+ }
+
+ p := &Provisioner{
+ NCMConfig: NCMCfg,
+ NCMClient: c,
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: log,
+ }
+
+ return p, nil
+}
+
+// Sign uses NCMClient to communicate with NCM API to sign CertificateRequest.
+// NCM policy defines few statuses for CSR, which must be correctly handled
+// by ncm-issuer. Thus, CSR status in NCM is checked every time to deduce current
+// state - Provisioner stores in pendingCSRs href to pending CSR if request has not been
+// accepted during first CertificateRequest.
+func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string, error) {
+ casResponse, err := p.NCMClient.GetCAs()
+ if err != nil {
+ return nil, nil, "", ErrFailedGetCAs
+ }
+
+ signingCA, found := findCA(casResponse, p.NCMConfig.CAsHref, p.NCMConfig.CAsName)
+ if !found {
+ return nil, nil, "", fmt.Errorf("CA certificate with the given HREF or NAME has not been found")
+ }
+
+ certChain, wantedCA, err := p.getChainAndWantedCA(signingCA)
+ if err != nil {
+ return nil, nil, "", err
+ }
+
+ if has := p.pendingCSRs.Has(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey]); has {
+ pendingCSR := p.pendingCSRs.Get(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ csrStatusResp, err := p.NCMClient.CheckCSRStatus(pendingCSR.href)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed checking CSR status in NCM, its href: %s, err: %v", pendingCSR.href, err)
+ }
+
+ switch status := csrStatusResp.Status; status {
+ case CSRStatusAccepted:
+ leafCertURLPath, _ := ncmapi.GetPathFromCertHref(csrStatusResp.Certificate)
+ leafCertInPEM, _ := p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s, err: %v", csrStatusResp.Certificate, err)
+ }
+
+ p.pendingCSRs.Delete(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ ca, tls := p.prepareCAAndTLS(wantedCA, leafCertInPEM, certChain)
+ return ca, tls, csrStatusResp.Certificate, nil
+ case CSRStatusApproved:
+ // CSRStatusApproved means that CSR has been approved (by operator) but NCM
+ // has yet to Sign generated certificate - this means that in the near future
+ // the status of CSR will be CSRStatusAccepted, and we will be able to
+ // download that certificate by using NCMClient. Thus, we need to
+ // return ErrCSRNotAccepted to requeue CertificateRequest and reset
+ // "checked" value in PendingCSR to avoid exceeding SingleCSRCheckLimit.
+
+ p.pendingCSRs.ResetCheckCounter(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ return nil, nil, "", ErrCSRNotAccepted
+ case CSRStatusPending:
+ if pendingCSR.checked <= SingleCSRCheckLimit {
+ p.pendingCSRs.Increment(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ return nil, nil, "", ErrCSRNotAccepted
+ }
+ // If the status of CSR for a long period of time was CSRStatusPending
+ // ncm-issuer will reject PendingCSR returning ErrCSRCheckLimitExceeded
+ // to avoid redundant requeuing CertificateRequest - further actions
+ // should be taken by operator (certificate re-enrollment in k8s cluster).
+
+ p.pendingCSRs.Delete(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ return nil, nil, "", ErrCSRCheckLimitExceeded
+ case CSRStatusPostponed:
+ // CSRStatusPostponed means that the previous status of CSR was CSRStatusPending.
+ // CSR in NCM still can be manipulated, but ncm-issuer is rejecting PendingCSR - further
+ // actions should be taken by operator (certificate re-enrollment in k8s cluster).
+
+ p.pendingCSRs.Delete(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ return nil, nil, "", ErrCSRRejected
+ case CSRStatusRejected:
+ p.pendingCSRs.Delete(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
+ return nil, nil, "", ErrCSRRejected
+ default:
+ return nil, nil, "", fmt.Errorf("got unexpected status: %s", status)
+ }
+ }
+
+ csrResp, err := p.NCMClient.SendCSR(cr.Spec.Request, signingCA, p.NCMConfig.ProfileID)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed to send CSR, err: %v", err)
+ }
+ p.log.Info("CSR in NCM", "CSR", csrResp, "href in CSR", csrResp.Href)
+
+ requestedCertURLPath, _ := ncmapi.GetPathFromCertHref(csrResp.Href)
+ csrStatusResp, err := p.NCMClient.CheckCSRStatus(requestedCertURLPath)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed checking CSR status in NCM, its href: %s, err: %v", csrResp.Href, err)
+ }
+
+ if status := csrStatusResp.Status; status == CSRStatusRejected {
+ return nil, nil, "", ErrCSRRejected
+ } else if status != CSRStatusAccepted {
+ p.pendingCSRs.Add(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey], csrResp.Href)
+ return nil, nil, "", ErrCSRNotAccepted
+ }
+
+ leafCertURLPath, _ := ncmapi.GetPathFromCertHref(csrStatusResp.Certificate)
+ leafCertInPEM, _ := p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s, err: %v", csrStatusResp.Certificate, err)
+ }
+
+ ca, tls := p.prepareCAAndTLS(wantedCA, leafCertInPEM, certChain)
+ return ca, tls, csrStatusResp.Certificate, nil
+}
+
+// Renew uses NCMClient to communicate with NCM API to renew existing
+// certificate.
+func (p *Provisioner) Renew(cr *cmapi.CertificateRequest, certID string) ([]byte, []byte, string, error) {
+ casResponse, err := p.NCMClient.GetCAs()
+ if err != nil {
+ return nil, nil, "", ErrFailedGetCAs
+ }
+
+ singingCA, found := findCA(casResponse, p.NCMConfig.CAsHref, p.NCMConfig.CAsName)
+ if !found {
+ return nil, nil, "", fmt.Errorf("CA certificate with the given HREF or NAME has not been found")
+ }
+
+ certChain, wantedCA, err := p.getChainAndWantedCA(singingCA)
+ if err != nil {
+ return nil, nil, "", err
+ }
+
+ certURLPath, _ := ncmapi.GetPathFromCertHref(certID)
+ renewCertResp, err := p.NCMClient.RenewCertificate(certURLPath, cr.Spec.Duration, p.NCMConfig.ProfileID)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed to renew certificate, its href: %s, err: %v", certID, err)
+ }
+
+ renewedCertURLPath, _ := ncmapi.GetPathFromCertHref(renewCertResp.Certificate)
+ leafCertInPEM, err := p.NCMClient.DownloadCertificateInPEM(renewedCertURLPath)
+ if err != nil {
+ return nil, nil, "", fmt.Errorf("failed to download renewed certificate in PEM, its href: %s, err: %v", renewCertResp.Certificate, err)
+ }
+
+ ca, tls := p.prepareCAAndTLS(wantedCA, leafCertInPEM, certChain)
+ return ca, tls, renewCertResp.Certificate, nil
+}
+
+// getChainAndWantedCA gets PEM chain and CA certificate using NCMClient, those
+// values are needed for both Sign and Renew operations. The order of bytes
+// in PEM chain is defined by NCMConfig which also defines which CA certificate
+// should be taken into consideration when selecting proper ca.crt
+// (given CA certificate in NCMConfig or root CA certificate).
+func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte, []byte, error) {
+ var certChain []byte
+ wantedCA := &ncmapi.CAResponse{}
+ lastCheckedCA := signingCA
+
+ for {
+ p.log.Info("Last checked CA certificate in certificate chain", "href", lastCheckedCA.Href)
+
+ lastCheckedCAURLPath, _ := ncmapi.GetPathFromCertHref(lastCheckedCA.Certificates["active"])
+ currentCACert, err := p.NCMClient.DownloadCertificate(lastCheckedCAURLPath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to download CA certificate, its href: %s, err: %v", lastCheckedCA.Certificates["active"], err)
+ }
+
+ if lastCheckedCA.Href == currentCACert.IssuerCA || currentCACert.IssuerCA == "" {
+ break
+ }
+
+ currentCACertInPEM, err := p.NCMClient.DownloadCertificateInPEM(lastCheckedCAURLPath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to download CA certificate in PEM, its href: %s, err: %v", lastCheckedCA.Certificates["active"], err)
+ }
+ certChain = addCertToChain(currentCACertInPEM, certChain, p.NCMConfig.LittleEndian)
+
+ lastCheckedCAURLPath, _ = ncmapi.GetPathFromCertHref(currentCACert.IssuerCA)
+ lastCheckedCA, err = p.NCMClient.GetCA(lastCheckedCAURLPath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to get CA certificate, its href: %s, err: %v", currentCACert.IssuerCA, err)
+ }
+ }
+
+ if p.NCMConfig.NoRoot && !p.NCMConfig.ChainInSigner {
+ wantedCA = signingCA
+ } else {
+ wantedCA = lastCheckedCA
+ }
+ p.log.Info("Signing CA certificate was found and selected according to configuration", "isRootCA", !p.NCMConfig.NoRoot || p.NCMConfig.ChainInSigner, "Name", wantedCA.Name)
+
+ wantedCAURLPath, _ := ncmapi.GetPathFromCertHref(wantedCA.Certificates["active"])
+ wantedCAInPEM, err := p.NCMClient.DownloadCertificateInPEM(wantedCAURLPath)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to download signing (root) CA in PEM, its href: %s, err: %v", wantedCA.Certificates["active"], err)
+ }
+
+ return certChain, wantedCAInPEM, nil
+}
+
+// prepareCAAndTLS prepares values needed for certificate (ca.crt and tls.crt)
+// according to NCMConfig.
+func (p *Provisioner) prepareCAAndTLS(wantedCA, leafCert, certChain []byte) ([]byte, []byte) {
+ var ca, tls []byte
+ if p.NCMConfig.ChainInSigner {
+ var certChainWithRoot []byte
+ certChainWithRoot = append(certChainWithRoot, certChain...)
+ certChainWithRoot = addCertToChain(wantedCA, certChainWithRoot, p.NCMConfig.LittleEndian)
+ ca = certChainWithRoot
+ } else {
+ ca = wantedCA
+ }
+
+ if !p.NCMConfig.OnlyEECert {
+ certChain = addLeafCertToChain(leafCert, certChain, p.NCMConfig.LittleEndian)
+ tls = certChain
+ } else {
+ tls = leafCert
+ }
+
+ return ca, tls
+}
diff --git a/pkg/provisioner/pendingcsr.go b/pkg/provisioner/pendingcsr.go
new file mode 100644
index 0000000..8917a4e
--- /dev/null
+++ b/pkg/provisioner/pendingcsr.go
@@ -0,0 +1,69 @@
+package provisioner
+
+import (
+ "sync"
+)
+
+// PendingCSR stores pending CSR href and "checked" which means
+// how many times CSRStatusPending was encountered when checking
+// CSR status in NCM.
+type PendingCSR struct {
+ href string
+ checked int
+}
+
+// PendingCSRsMap stores pending CSRs which have not yet been accepted by NCM
+// as key-value pair where key is composed of namespace + certificate name
+// (e.g. ncm-issuer-ns.example-certificate) and value is PendingCSR.
+type PendingCSRsMap struct {
+ pendingCSRs map[string]*PendingCSR
+ mu sync.RWMutex
+}
+
+func (cm *PendingCSRsMap) Add(namespace, certName, href string) {
+ cm.mu.Lock()
+ defer cm.mu.Unlock()
+
+ if _, ok := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]; !ok {
+ cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)] = &PendingCSR{href: href, checked: 1}
+ }
+}
+
+func (cm *PendingCSRsMap) Has(namespace, certName string) bool {
+ cm.mu.RLock()
+ defer cm.mu.RUnlock()
+
+ _, ok := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ return ok
+}
+
+func (cm *PendingCSRsMap) Get(namespace, certName string) *PendingCSR {
+ cm.mu.RLock()
+ defer cm.mu.RUnlock()
+
+ pendingCSR, _ := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ return pendingCSR
+}
+
+func (cm *PendingCSRsMap) Increment(namespace, certName string) {
+ cm.mu.Lock()
+ defer cm.mu.Unlock()
+
+ pendingCSR, _ := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ pendingCSR.checked += 1
+}
+
+func (cm *PendingCSRsMap) ResetCheckCounter(namespace, certName string) {
+ cm.mu.Lock()
+ defer cm.mu.Unlock()
+
+ pendingCSR, _ := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ pendingCSR.checked = 1
+}
+
+func (cm *PendingCSRsMap) Delete(namespace, certName string) {
+ cm.mu.Lock()
+ defer cm.mu.Unlock()
+
+ delete(cm.pendingCSRs, prepareCSRsMapKey(namespace, certName))
+}
diff --git a/pkg/provisioner/util.go b/pkg/provisioner/util.go
new file mode 100644
index 0000000..a53ada5
--- /dev/null
+++ b/pkg/provisioner/util.go
@@ -0,0 +1,44 @@
+package provisioner
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
+)
+
+func findCA(casResponse *ncmapi.CAsResponse, CAsHref, CAsName string) (*ncmapi.CAResponse, bool) {
+ hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
+ for _, ca := range casResponse.CAList {
+ if strings.EqualFold(ca.Status, "active") {
+ if CAsHref != "" {
+ href := hrefRegex.Find([]byte(ca.Href))
+ if string(href) == CAsHref {
+ return &ca, true
+ }
+ } else if ca.Name == CAsName {
+ return &ca, true
+ }
+ }
+ }
+ return nil, false
+}
+
+func addCertToChain(crt, crtChain []byte, littleEndian bool) []byte {
+ if littleEndian {
+ return append(crt, crtChain...)
+ }
+ return append(crtChain, crt...)
+}
+
+func addLeafCertToChain(leafCrt, crtChain []byte, littleEndian bool) []byte {
+ if littleEndian {
+ return append(crtChain, leafCrt...)
+ }
+ return append(leafCrt, crtChain...)
+}
+
+func prepareCSRsMapKey(namespace, crtName string) string {
+ return fmt.Sprintf("%s.%s", namespace, crtName)
+}
diff --git a/pkg/pkiutil/csr.go b/pkg/util/csr.go
similarity index 100%
rename from pkg/pkiutil/csr.go
rename to pkg/util/csr.go
diff --git a/pkg/pkiutil/decode.go b/pkg/util/decode.go
similarity index 100%
rename from pkg/pkiutil/decode.go
rename to pkg/util/decode.go
diff --git a/pkg/util/file.go b/pkg/util/file.go
new file mode 100644
index 0000000..3e8ab5e
--- /dev/null
+++ b/pkg/util/file.go
@@ -0,0 +1,97 @@
+package util
+
+import (
+ "fmt"
+ "net/url"
+ "os"
+
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+func GetSpecAndStatus(issuer client.Object) (*ncmv1.IssuerSpec, *ncmv1.IssuerStatus, error) {
+ switch t := issuer.(type) {
+ case *ncmv1.Issuer:
+ return &t.Spec, &t.Status, nil
+ case *ncmv1.ClusterIssuer:
+ return &t.Spec, &t.Status, nil
+ default:
+ return nil, nil, fmt.Errorf("not an issuer type: %t", t)
+ }
+}
+
+func GetSecretNamespace(issuer client.Object, req ctrl.Request) (string, error) {
+ switch t := issuer.(type) {
+ case *ncmv1.Issuer:
+ return req.Namespace, nil
+ case *ncmv1.ClusterIssuer:
+ if t.Spec.AuthNamespace == "" {
+ t.Spec.AuthNamespace = metav1.NamespaceDefault
+ }
+ return t.Spec.AuthNamespace, nil
+ default:
+ return "", fmt.Errorf("not an issuer type: %t", t)
+ }
+}
+
+// IssuerHasCondition will return true if the given issuer has a
+// condition matching the provided IssuerCondition.
+// Only the Type and Status field will be used in the comparison, meaning that
+// this function will return 'true' even if the Reason, Message and
+// LastTransitionTime fields do not match.
+func IssuerHasCondition(status ncmv1.IssuerStatus, c ncmv1.IssuerCondition) bool {
+ existingConditions := status.Conditions
+ for _, cond := range existingConditions {
+ if c.Type == cond.Type && c.Status == cond.Status {
+ return true
+ }
+ }
+ return false
+}
+
+func GetCertIDSecret(namespace string, name string, certID string) *v1.Secret {
+ secret := v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: namespace,
+ Name: name,
+ },
+ StringData: map[string]string{
+ "cert-id": certID,
+ },
+ Type: v1.SecretTypeOpaque,
+ }
+ return &secret
+}
+
+// WritePEMToTempFile writes PEM to temporary file.
+func WritePEMToTempFile(pem []byte) (string, error) {
+ csrFile, err := os.CreateTemp("", "*.pem")
+ if err != nil {
+ return "", err
+ }
+
+ defer csrFile.Close()
+ path := csrFile.Name()
+
+ if _, err := csrFile.Write(pem); err != nil {
+ return path, err
+ }
+
+ if err = csrFile.Sync(); err != nil {
+ return path, err
+ }
+
+ return path, err
+}
+
+func GetPathFromCertHref(certHref string) (string, error) {
+ parsedURL, err := url.Parse(certHref)
+ if err != nil {
+ return "", fmt.Errorf("cannot parsed given href: %s", certHref)
+ }
+
+ return parsedURL.Path, nil
+}
diff --git a/pkg/pkiutil/validate.go b/pkg/util/validate.go
similarity index 100%
rename from pkg/pkiutil/validate.go
rename to pkg/util/validate.go
From a61511630c69d97aa4ef448c61a89c15b19c6371 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 12:59:46 +0100
Subject: [PATCH 060/175] Moved NCM config to its individual pkg
---
pkg/cfg/ncmcfg.go | 167 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 167 insertions(+)
create mode 100644 pkg/cfg/ncmcfg.go
diff --git a/pkg/cfg/ncmcfg.go b/pkg/cfg/ncmcfg.go
new file mode 100644
index 0000000..7ed6a81
--- /dev/null
+++ b/pkg/cfg/ncmcfg.go
@@ -0,0 +1,167 @@
+package cfg
+
+import (
+ "fmt"
+ "strings"
+
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ ncmutil "github.com/nokia/ncm-issuer/pkg/util"
+ core "k8s.io/api/core/v1"
+)
+
+// NCMConfig stores the configuration which defines the behaviour of ncm-issuer
+type NCMConfig struct {
+ // NCMServer is a main NCM API server address.
+ NCMServer string
+
+ // NCMServer2 is a secondary NCM API server address
+ // in case of the lack of connection to the main one (can be empty).
+ NCMServer2 string
+
+ // Username is a username used for authentication to NCM API.
+ Username string
+
+ // Password is a password used for authentication to NCM API.
+ Password string
+
+ // CAsName is a CA certificate name which will issue generated certificates.
+ CAsName string
+
+ // CAsHREF is a CA certificate href which will issue generated certificates.
+ CAsHref string
+
+ // ReenrollmentOnRenew determines whether during renewal certificate
+ // should be re-enrolled instead of renewed.
+ ReenrollmentOnRenew bool
+
+ // ProfileID is an entity profile ID
+ ProfileID string
+
+ // UseProfileIDForRenew determines whether the profile ID should be used
+ // during a certificate renewal operation
+ UseProfileIDForRenew bool
+
+ // LittleEndian determines bytes order.
+ LittleEndian bool
+
+ // NoRoot determines whether singing CA certificate should be included
+ // in ca.crt instead of root CA certificate.
+ NoRoot bool
+
+ // ChainInSigner determines whether certificate chain should be included in ca.crt
+ // (intermediate certificates + singing CA certificate + root CA certificate).
+ ChainInSigner bool
+
+ // OnlyEECert determines whether only end-entity certificate should be included
+ // in tls.crt.
+ OnlyEECert bool
+
+ // TLSSecretName is a secret which contains TLS configuration for the NCM API
+ TLSSecretName string
+
+ // CACert is a TLS CA certificate.
+ CACert string
+
+ // Key is a TLS client key.
+ Key string
+
+ // Cert is a TLS client certificate.
+ Cert string
+
+ // InsecureSkipVerify determines whether SSL certificate verification between client
+ // instance and NCM API should be enabled.
+ InsecureSkipVerify bool
+
+ // MTLS determines whether mTLS should be enabled.
+ MTLS bool
+}
+
+func Initialise(issuerSpec *ncmv1.IssuerSpec) *NCMConfig {
+ return &NCMConfig{
+ NCMServer: strings.TrimSuffix(issuerSpec.NCMServer, "/"),
+ NCMServer2: strings.TrimSuffix(issuerSpec.NCMServer2, "/"),
+ Username: "",
+ Password: "",
+ CAsName: issuerSpec.CAsName,
+ CAsHref: issuerSpec.CAsHREF,
+ ReenrollmentOnRenew: issuerSpec.ReenrollmentOnRenew,
+ ProfileID: issuerSpec.ProfileID,
+ UseProfileIDForRenew: issuerSpec.UseProfileIDForRenew,
+ LittleEndian: issuerSpec.LittleEndian,
+ NoRoot: issuerSpec.NoRoot,
+ ChainInSigner: issuerSpec.ChainInSigner,
+ OnlyEECert: issuerSpec.OnlyEECert,
+ TLSSecretName: issuerSpec.TLSSecretName,
+ CACert: "",
+ Key: "",
+ Cert: "",
+ InsecureSkipVerify: true,
+ MTLS: false,
+ }
+}
+
+func (cfg *NCMConfig) AddAuthenticationData(secret *core.Secret) {
+ if username, ok := secret.Data["username"]; ok {
+ cfg.Username = string(username)
+ } else {
+ cfg.Username = ""
+ }
+
+ if password, ok := secret.Data["usrPassword"]; ok {
+ cfg.Password = string(password)
+ } else {
+ cfg.Password = ""
+ }
+}
+
+func (cfg *NCMConfig) AddTLSData(secret *core.Secret) error {
+ if CACert, ok := secret.Data["cacert"]; ok {
+ cfg.CACert = string(CACert)
+ } else {
+ cfg.CACert = ""
+ }
+ cfg.InsecureSkipVerify = cfg.CACert == ""
+
+ if key, ok := secret.Data["key"]; ok {
+ keyPath, err := ncmutil.WritePEMToTempFile(key)
+ if err != nil {
+ return err
+ }
+ cfg.Key = keyPath
+ } else {
+ cfg.Key = ""
+ }
+
+ if cert, ok := secret.Data["cert"]; ok {
+ certPath, err := ncmutil.WritePEMToTempFile(cert)
+ if err != nil {
+ return err
+ }
+ cfg.Cert = certPath
+ } else {
+ cfg.Cert = ""
+ }
+ cfg.MTLS = cfg.Key != "" && cfg.Cert != ""
+
+ return nil
+}
+
+func (cfg *NCMConfig) Validate() error {
+ if cfg.NCMServer == "" {
+ return fmt.Errorf("incorrect NCM API address: missing ncmSERVER address")
+ }
+
+ if cfg.Username == "" || cfg.Password == "" {
+ return fmt.Errorf("incorrect authentication data: missing username or usrpassword")
+ }
+
+ if cfg.CAsName == "" && cfg.CAsHref == "" {
+ return fmt.Errorf("incorrect signing CA certificate data: missing CANAME or CAHREF")
+ }
+
+ if cfg.TLSSecretName != "" && cfg.CACert == "" && cfg.Key == "" && cfg.Cert == "" {
+ return fmt.Errorf("incorrect TLS data: missing cacert, key or cert in TLS secret")
+ }
+
+ return nil
+}
From cacd92f4f8484d4b627a46bfdfa30e072fe501f0 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 13:00:52 +0100
Subject: [PATCH 061/175] Refactored code in issuer controller & fixed data
races
---
main.go | 40 ++--
pkg/controllers/issuer_controller.go | 269 +++++++++------------------
2 files changed, 110 insertions(+), 199 deletions(-)
diff --git a/main.go b/main.go
index b1f9e0c..2c557ea 100644
--- a/main.go
+++ b/main.go
@@ -18,6 +18,7 @@ package main
import (
"flag"
+ "github.com/nokia/ncm-issuer/pkg/provisioner"
"k8s.io/utils/clock"
"os"
@@ -90,13 +91,16 @@ func main() {
os.Exit(1)
}
+ provisioners := provisioner.NewProvisionersMap()
+
if err = (&controllers.IssuerReconciler{
- Kind: "ClusterIssuer",
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
- Clock: clock.RealClock{},
- Recorder: mgr.GetEventRecorderFor("external-clusterIssuer-controller"),
- Log: ctrl.Log.WithName("controllers").WithName("ClusterIssuer"),
+ Kind: "ClusterIssuer",
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Clock: clock.RealClock{},
+ Recorder: mgr.GetEventRecorderFor("external-clusterIssuer-controller"),
+ Provisioners: provisioners,
+ Log: ctrl.Log.WithName("controllers").WithName("ClusterIssuer"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, setupErrMsg, "controller", "ClusterIssuer")
os.Exit(1)
@@ -105,23 +109,25 @@ func main() {
}
if err = (&controllers.IssuerReconciler{
- Kind: "Issuer",
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
- Clock: clock.RealClock{},
- Recorder: mgr.GetEventRecorderFor("external-issuer-controller"),
- Log: ctrl.Log.WithName("controllers").WithName("Issuer"),
+ Kind: "Issuer",
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Clock: clock.RealClock{},
+ Recorder: mgr.GetEventRecorderFor("external-issuer-controller"),
+ Provisioners: provisioners,
+ Log: ctrl.Log.WithName("controllers").WithName("Issuer"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, setupErrMsg, "controller", "Issuer")
os.Exit(1)
}
if err = (&controllers.CertificateRequestReconciler{
- Client: mgr.GetClient(),
- Log: ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
- Clock: clock.RealClock{},
- Recorder: mgr.GetEventRecorderFor("certificateRequests-controller"),
- Scheme: mgr.GetScheme(),
+ Client: mgr.GetClient(),
+ Log: ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
+ Clock: clock.RealClock{},
+ Recorder: mgr.GetEventRecorderFor("certificateRequests-controller"),
+ Provisioners: provisioners,
+ Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, setupErrMsg, "controller", "CertificateRequest")
os.Exit(1)
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index b571f92..f3f5bb8 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -18,19 +18,18 @@ package controllers
import (
"context"
- "errors"
"fmt"
- "strings"
+ "github.com/nokia/ncm-issuer/pkg/cfg"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ utilerrors "k8s.io/apimachinery/pkg/util/errors"
"github.com/go-logr/logr"
- certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
- "github.com/nokia/ncm-issuer/pkg/ncmapi"
- "github.com/nokia/ncm-issuer/pkg/pkiutil"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/provisioner"
core "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
- utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/record"
"k8s.io/utils/clock"
ctrl "sigs.k8s.io/controller-runtime"
@@ -40,15 +39,16 @@ import (
// IssuerReconciler reconciles a Issuer object
type IssuerReconciler struct {
client.Client
- Kind string
- Scheme *runtime.Scheme
- Clock clock.Clock
- Recorder record.EventRecorder
- Log logr.Logger
+ Kind string
+ Scheme *runtime.Scheme
+ Clock clock.Clock
+ Recorder record.EventRecorder
+ Provisioners *provisioner.ProvisionersMap
+ Log logr.Logger
}
func (r *IssuerReconciler) newIssuer() (client.Object, error) {
- issuerGVK := certmanagerv1.GroupVersion.WithKind(r.Kind)
+ issuerGVK := ncmv1.GroupVersion.WithKind(r.Kind)
ro, err := r.Scheme.New(issuerGVK)
if err != nil {
return nil, err
@@ -56,11 +56,6 @@ func (r *IssuerReconciler) newIssuer() (client.Object, error) {
return ro.(client.Object), nil
}
-var (
- // NCMConfigMap : for each certifier, NCM config set up with the secret
- NCMConfigMap = make(map[ncmapi.NCMConfigKey]*ncmapi.NCMConfig)
-)
-
//+kubebuilder:rbac:groups=certmanager.ncm.nokia.com,resources=issuers;clusterissuers,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=certmanager.ncm.nokia.com,resources=issuers/status;clusterissuers/status,verbs=get;update;patch
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
@@ -74,104 +69,88 @@ var (
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile
func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- log := r.Log.WithValues("Name", req.NamespacedName)
+ log := r.Log.WithValues("ncmissuer", req.NamespacedName)
+
issuer, err := r.newIssuer()
if err != nil {
log.Error(err, "Unrecognised issuer type")
- return ctrl.Result{}, err
+ return ctrl.Result{}, nil
}
+
if err := r.Get(ctx, req.NamespacedName, issuer); err != nil {
- log.Error(err, "Issuer not found")
- return ctrl.Result{}, err
+ if err := client.IgnoreNotFound(err); err != nil {
+ return ctrl.Result{}, fmt.Errorf("unexpected get error: %v", err)
+ }
+ log.Info("Issuer resource not found, ignoring...")
+ return ctrl.Result{}, nil
}
- issuerSpec, _, err := pkiutil.GetSpecAndStatus(issuer)
+
+ issuerSpec, _, err := GetSpecAndStatus(issuer)
if err != nil {
log.Error(err, "Unexpected error while getting issuer spec and status. Not retrying.")
- return ctrl.Result{}, err
- }
- var reason, completeMessage string
- condition := certmanagerv1.ConditionFalse
-
- // Always attempt to update the Ready condition
- defer func() {
- _ = r.setMyCRDStatus(ctx, issuer, condition, reason, completeMessage)
- }()
-
- // check Spec
- if invalidStr := checkIssuerSpec(issuerSpec); len(invalidStr) != 0 {
- reason = "incorrect setting"
- err = errors.New(reason)
- completeMessage = fmt.Sprintf("Incorrect Spec config: %v", invalidStr)
- log.Error(err, "Incorrect Spec config setting")
- return ctrl.Result{}, err
+ return ctrl.Result{}, nil
}
- // Fetch the ncm Secret
secretName := types.NamespacedName{
Name: issuerSpec.AuthSecretName,
}
- // ignore err before GetSpecAndStatus already check issuer.(type)
- secretName.Namespace, _ = pkiutil.GetSecretNamespace(issuer, req)
- caSecret := core.Secret{}
- if err := r.Client.Get(ctx, secretName, &caSecret); err != nil {
- reason = "NotFound"
- completeMessage = fmt.Sprintf("Failed to retrieve the Auth Secret: %v", err)
- log.Error(err, "failed to retrieve Auth Secret")
- return ctrl.Result{}, err
+ secretName.Namespace, err = GetSecretNamespace(issuer, req)
+ if err != nil {
+ log.Error(err, "Unexpected issuer type. Not retrying.")
+ return ctrl.Result{}, nil
}
- if err = checkNCMSecretData(&caSecret); err != nil {
- reason = "incorrect setting"
- completeMessage = fmt.Sprintf("incorrect Auth Secret setting: %v", err)
- log.Error(err, "incorrect Auth Secret setting")
+ authSecret := &core.Secret{}
+ if err := r.Client.Get(ctx, secretName, authSecret); err != nil {
+ log.Error(err, "Failed to retrieve auth secret", "namespace", secretName.Namespace, "name", secretName.Name)
+ if apierrors.IsNotFound(err) {
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "failed to retrieve auth secret err: %v", err)
+ } else {
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to retrieve auth secret err: %v", err)
+ }
+
return ctrl.Result{}, err
}
- cfg := ncmapi.NCMConfig{}
- populateNCMConfData(&caSecret, &cfg)
-
- // in case suffix "/" is present removes it
- cfg.NCMServer = strings.TrimSuffix(issuerSpec.NCMServer, "/")
- cfg.NCMServer2 = strings.TrimSuffix(issuerSpec.NCMServer2, "/")
- cfg.CAsName = issuerSpec.CAsName
- cfg.CAsHREF = issuerSpec.CAsHREF
- cfg.InstaCA = issuerSpec.CAsName
- cfg.LittleEndianPem = issuerSpec.LittleEndian
- cfg.ReenrollmentOnRenew = issuerSpec.ReenrollmentOnRenew
- cfg.UseProfileIDForRenew = issuerSpec.UseProfileIDForRenew
- cfg.NoRoot = issuerSpec.NoRoot
- cfg.ChainInSigner = issuerSpec.ChainInSigner
- cfg.OnlyEECert = issuerSpec.OnlyEECert
-
- ///////////////////////
- cfg.InsecureSkipVerify = true
- if issuerSpec.TLSSecretName != "" {
- // Fetch the NCM TLS secret
- tlsConfSecret := core.Secret{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: issuerSpec.TLSSecretName}, &tlsConfSecret); err != nil {
- reason = "NotFound"
- completeMessage = fmt.Sprintf("Failed to retrieve tls Secret: %v", err)
- log.Error(err, "failed to retrieve tls Secret")
+ NCMCfg := cfg.Initialise(issuerSpec)
+ NCMCfg.AddAuthenticationData(authSecret)
+ if NCMCfg.TLSSecretName != "" {
+ tlsSecret := &core.Secret{}
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: NCMCfg.TLSSecretName}, tlsSecret); err != nil {
+ log.Error(err, "Failed to retrieve TLS secret", "namespace", secretName.Namespace, "name", NCMCfg.TLSSecretName)
+ if apierrors.IsNotFound(err) {
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "failed to retrieve auth secret err: %v", err)
+ } else {
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to retrieve auth secret err: %v", err)
+ }
+
return ctrl.Result{}, err
}
- if err = populateNCMTLSConfData(&tlsConfSecret, &cfg); err != nil {
- reason = "incorrect TLS setting"
- completeMessage = fmt.Sprintf("TLS secret config setting population is incorrect: %v", err)
- log.Error(err, "TLS secret config setting population is incorrect")
+ if err := NCMCfg.AddTLSData(tlsSecret); err != nil {
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to add TLS secret data to config err: %v", err)
return ctrl.Result{}, err
}
}
- cfgKey := ncmapi.NCMConfigKey{Namespace: secretName.Namespace, Name: req.NamespacedName.Name}
- NCMConfigMap[cfgKey] = &cfg
- reason = "Verified"
- completeMessage = "Signing CA verified and ready to issue certificates"
- condition = certmanagerv1.ConditionTrue
+ if err := NCMCfg.Validate(); err != nil {
+ log.Error(err, "Failed to validate config provided in spec")
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to validate config provided in spec: %v", err)
+ return ctrl.Result{}, err
+ }
+
+ p, err := provisioner.NewProvisioner(NCMCfg, log)
+ if err != nil {
+ log.Error(err, "Failed to create new provisioner")
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to create new provisioner err: %v", err)
+ return ctrl.Result{}, err
+ }
- return ctrl.Result{}, nil
+ r.Provisioners.AddOrReplace(req.NamespacedName, p)
+
+ return ctrl.Result{}, r.SetStatus(ctx, issuer, ncmv1.ConditionTrue, "Verified", "Signing CA verified and ready to sign certificates")
}
-// setMyCRDCondition will set a 'condition' on the given MyCRD.
+// SetCondition will set a 'condition' on the given issuer.
// - If no condition of the same type already exists, the condition will be
// inserted with the LastTransitionTime set to the current time.
// - If a condition of the same type and state already exists, the condition
@@ -179,9 +158,9 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
// - If a condition of the same type and different state already exists, the
// condition will be updated and the LastTransitionTime set to the current
// time.
-func (r *IssuerReconciler) setMyCRDCondition(issuerStatus *certmanagerv1.IssuerStatus, status certmanagerv1.ConditionStatus, reason, message string) {
- newCondition := &certmanagerv1.IssuerCondition{
- Type: certmanagerv1.IssuerConditionReady,
+func (r *IssuerReconciler) SetCondition(issuerStatus *ncmv1.IssuerStatus, status ncmv1.ConditionStatus, reason, message string) {
+ newCondition := &ncmv1.IssuerCondition{
+ Type: ncmv1.IssuerConditionReady,
Status: status,
Reason: reason,
Message: message,
@@ -191,16 +170,18 @@ func (r *IssuerReconciler) setMyCRDCondition(issuerStatus *certmanagerv1.IssuerS
newCondition.LastTransitionTime = &nowTime
for idx, cond := range issuerStatus.Conditions {
// Skip unrelated conditions
- if cond.Type != certmanagerv1.IssuerConditionReady {
+ if cond.Type != ncmv1.IssuerConditionReady {
continue
}
+
// If this update doesn't contain a state transition, we don't update
// the conditions LastTransitionTime to Now()
if cond.Status == status {
newCondition.LastTransitionTime = cond.LastTransitionTime
} else {
- r.Log.Info("found status change for condition; setting lastTransitionTime", "condition", certmanagerv1.IssuerConditionReady, "old_status", cond.Status, "new_status", status, "time", nowTime.Time)
+ r.Log.Info("found status change for condition; setting lastTransitionTime", "condition", cond.Type, "old_status", cond.Status, "new_status", status, "time", nowTime.Time)
}
+
// Overwrite the existing condition
issuerStatus.Conditions[idx] = *newCondition
return
@@ -209,118 +190,42 @@ func (r *IssuerReconciler) setMyCRDCondition(issuerStatus *certmanagerv1.IssuerS
// If we've not found an existing condition of this type, we simply insert
// the new condition into the slice.
issuerStatus.Conditions = append(issuerStatus.Conditions, *newCondition)
- r.Log.Info("setting lastTransitionTime for MyCRD condition", "condition", certmanagerv1.IssuerConditionReady, "time", nowTime.Time)
+ r.Log.Info("setting lastTransitionTime for issuer condition", "condition", ncmv1.IssuerConditionReady, "time", nowTime.Time)
}
-func (r *IssuerReconciler) setMyCRDStatus(ctx context.Context, issuer client.Object, conditionStatus certmanagerv1.ConditionStatus, reason, message string, args ...interface{}) error {
- // Format the message and update the myCRD variable with the new Condition
- var err error
- completeMessage := fmt.Sprintf(message, args...)
- var issuerStatus *certmanagerv1.IssuerStatus
+func (r *IssuerReconciler) SetStatus(ctx context.Context, issuer client.Object, conditionStatus ncmv1.ConditionStatus, reason, message string, args ...interface{}) error {
+ // Format the message and update the issuer variable with the new Condition
+ var issuerStatus *ncmv1.IssuerStatus
switch t := issuer.(type) {
- case *certmanagerv1.Issuer:
+ case *ncmv1.Issuer:
issuerStatus = &t.Status
- case *certmanagerv1.ClusterIssuer:
+ case *ncmv1.ClusterIssuer:
issuerStatus = &t.Status
default:
r.Log.Info("Foreign type ", t)
}
- r.setMyCRDCondition(issuerStatus, conditionStatus, reason, completeMessage)
+ completeMessage := fmt.Sprintf(message, args...)
+ r.SetCondition(issuerStatus, conditionStatus, reason, completeMessage)
// Fire an Event to additionally inform users of the change
eventType := core.EventTypeNormal
- if conditionStatus == certmanagerv1.ConditionFalse {
+ if conditionStatus == ncmv1.ConditionFalse {
eventType = core.EventTypeWarning
}
r.Recorder.Event(issuer, eventType, reason, completeMessage)
- // Actually update the MyCRD resource
+ // Actually update the issuer resource
+ var err error
if updateErr := r.Status().Update(ctx, issuer); updateErr != nil {
err = utilerrors.NewAggregate([]error{err, updateErr})
- }
- return err
-}
-
-// Checks if all the needed data are configured correctly
-func checkNCMSecretData(s *core.Secret) error {
- if s.Data == nil {
- return fmt.Errorf("no setting found in secret %s/%s", s.Namespace, s.Name)
- }
-
- errMsg := ""
- // Checks the setting
- if s.Data["username"] == nil {
- errMsg += "username is needed; "
- }
-
- if s.Data["usrPassword"] == nil {
- errMsg += "usrPassword is needed"
- }
-
- if errMsg != "" {
- return fmt.Errorf("wrong auth secret %s/%s setting, error: %s", s.Namespace, s.Name, errMsg)
- }
-
- return nil
-}
-
-// populate all the needed config data from the secret
-func populateNCMConfData(s *core.Secret, cfg *ncmapi.NCMConfig) {
- if s.Data["username"] != nil {
- cfg.Username = string(s.Data["username"])
- }
-
- if s.Data["usrPassword"] != nil {
- cfg.UsrPassword = string(s.Data["usrPassword"])
- }
-}
-
-// populate all the needed tls configure data from the tlsConfSecret
-func populateNCMTLSConfData(tlsConfSecret *core.Secret, cfg *ncmapi.NCMConfig) error {
-
- cfg.CACert = string(tlsConfSecret.Data["cacert"])
-
- if string(tlsConfSecret.Data["key"]) != "" {
- keyPath, err := ncmapi.WritePemToTempFile("/tmp/clientkey", tlsConfSecret.Data["key"])
- if err != nil {
- return err
- }
- cfg.Key = keyPath
- }
-
- if string(tlsConfSecret.Data["cert"]) != "" {
- certPath, err := ncmapi.WritePemToTempFile("/tmp/clientcert", tlsConfSecret.Data["cert"])
- if err != nil {
- return err
- }
- cfg.Cert = certPath
- }
-
- cfg.InsecureSkipVerify = cfg.CACert == ""
- cfg.MTLS = cfg.Key != "" && cfg.Cert != ""
-
- if cfg.CACert == "" && cfg.Key == "" && cfg.Cert == "" {
- return fmt.Errorf("no useful data cacert, key or cert in Ttls secret")
+ return err
}
return nil
}
-func checkIssuerSpec(issuerSpec *certmanagerv1.IssuerSpec) string {
- invalidStr := ""
- if len(issuerSpec.NCMServer) == 0 {
- invalidStr = "The ncmSERVER should not be empty. "
- }
-
- if len(issuerSpec.CAsName) == 0 && len(issuerSpec.CAsHREF) == 0 {
- invalidStr += "The CAsNAME or CAsHREF should not be empty."
- }
-
- return invalidStr
-}
-
// SetupWithManager sets up the controller with the Manager.
func (r *IssuerReconciler) SetupWithManager(mgr ctrl.Manager) error {
issuerType, err := r.newIssuer()
From 03c0a267ba11c83baf4be37d786b0f0ea4812f00 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 13:01:57 +0100
Subject: [PATCH 062/175] Refactored code in certificate request controller to
match new funcionality
---
.../certificaterequest_controller.go | 571 +++++-------------
1 file changed, 150 insertions(+), 421 deletions(-)
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 61c284d..a83401b 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -18,18 +18,18 @@ package controllers
import (
"context"
+ "errors"
"fmt"
- "strings"
"time"
"github.com/go-logr/logr"
apiutil "github.com/jetstack/cert-manager/pkg/api/util"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
- certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
- "github.com/nokia/ncm-issuer/pkg/ncmapi"
- "github.com/nokia/ncm-issuer/pkg/pkiutil"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/provisioner"
core "k8s.io/api/core/v1"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
@@ -40,35 +40,27 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)
-// CertificateRequestReconciler reconciles a MyCRD object
-type CertificateRequestReconciler struct {
- client.Client
- Scheme *runtime.Scheme
- Log logr.Logger
- Clock clock.Clock
- Recorder record.EventRecorder
-}
+const (
+ GetCAsRequeueTime = time.Second * 30
+ CSRRequeueTime = time.Minute
+)
var (
- // CertificateRequestPendingList CertificateRequest pending list, only one should be queued
- CertificateRequestPendingList = make(map[CertificateRequestPendingKey]*CertificateRequestPendingState)
+ errIssuerNotReady = errors.New("issuer is not ready yet")
+ errFailedGetIssuer = errors.New("failed to get issuer resource")
+ errFailedGetProvisioner = errors.New("failed to get provisioner")
)
-// CertificateRequestPendingKey key to CSRPendingList
-type CertificateRequestPendingKey struct {
- UsedNamespace string
- UserCrName string
-}
-
-// CertificateRequestPendingState Certificate Request Pending State
-type CertificateRequestPendingState struct {
- InState string
+// CertificateRequestReconciler reconciles a CertificateRequest object
+type CertificateRequestReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+ Clock clock.Clock
+ Recorder record.EventRecorder
+ Provisioners *provisioner.ProvisionersMap
+ Log logr.Logger
}
-const (
- SleepTime = 20000 // in time.Millisecond, 20s
-)
-
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=get;list;watch;update
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests/status,verbs=get;update;patch
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
@@ -81,62 +73,78 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log := r.Log.WithValues("CertificateRequest", req.NamespacedName)
// Fetch the CertificateRequest resource being reconciled
- cr := cmapi.CertificateRequest{}
+ cr := &cmapi.CertificateRequest{}
+ if err := r.Client.Get(ctx, req.NamespacedName, cr); err != nil {
+ if apierrors.IsNotFound(err) {
+ return ctrl.Result{}, client.IgnoreNotFound(err)
+ }
- if err := r.Client.Get(ctx, req.NamespacedName, &cr); err != nil {
- return ctrl.Result{}, client.IgnoreNotFound(err)
+ return ctrl.Result{}, err
}
// Checks the CertificateRequest's issuerRef and if it does not match the
// cert-manager group name, log a message at a debug level and stop processing.
- if cr.Spec.IssuerRef.Group != certmanagerv1.GroupVersion.Group {
+ if cr.Spec.IssuerRef.Group != ncmv1.GroupVersion.Group {
log.V(4).Info("resource does not specify an issuerRef group name that we are responsible for", "group", cr.Spec.IssuerRef.Group)
+ return ctrl.Result{}, nil
+ }
+
+ if apiutil.CertificateRequestHasCondition(cr, cmapi.CertificateRequestCondition{
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionFalse,
+ Reason: cmapi.CertificateRequestReasonFailed,
+ }) {
+ log.V(4).Info("CertificateRequest has been marked as failed")
+ return ctrl.Result{}, nil
+ }
+
+ if apiutil.CertificateRequestIsDenied(cr) {
+ log.V(4).Info("CertificateRequest has been denied")
+ return ctrl.Result{}, nil
+ }
+ if !apiutil.CertificateRequestIsApproved(cr) {
+ log.V(4).Info("CertificateRequest has not been approved yet")
return ctrl.Result{}, nil
}
- // If the certificate data is already set then we skip this request as it
- // has already been completed in the past.
if len(cr.Status.Certificate) > 0 {
log.V(4).Info("existing certificate data found in status, skipping already completed CertificateRequest")
+ return ctrl.Result{}, nil
+ }
+ if err := validateCertificateRequest(cr); err != nil {
+ log.Error(err, "Certificate request has issues", "cr", req.NamespacedName)
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "certificate request has issues: %v", err)
return ctrl.Result{}, nil
}
- // Unrecognised issuerRef.Kind
- issuerGVK := certmanagerv1.GroupVersion.WithKind(cr.Spec.IssuerRef.Kind)
+ issuerGVK := ncmv1.GroupVersion.WithKind(cr.Spec.IssuerRef.Kind)
issuerRO, err := r.Scheme.New(issuerGVK)
if err != nil {
log.Error(err, "Unrecognised kind. Ignoring.")
-
return ctrl.Result{}, nil
}
- // Get Issuer or ClusterIssuer resource
issuer := issuerRO.(client.Object)
- var secretNamespace string
-
- // Create a Namespaced name for Issuer and a non-Namespaced name for ClusterIssuer
issuerName := types.NamespacedName{
Name: cr.Spec.IssuerRef.Name,
}
if cr.Spec.IssuerRef.Kind == "Issuer" {
issuerName.Namespace = req.Namespace
- secretNamespace = req.Namespace
}
- // Get the Issuer or ClusterIssuer
if err := r.Client.Get(ctx, issuerName, issuer); err != nil {
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Issuer is not existing yet")
- log.Error(err, "fail to get "+issuerName.Name)
-
- return ctrl.Result{}, nil
+ log.Error(err, "Failed to get issuer")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "issuer is not existing yet")
+ return ctrl.Result{}, errFailedGetIssuer
}
- issuerSpec, issuerStatus, err := pkiutil.GetSpecAndStatus(issuer)
+ issuerSpec, issuerStatus, err := GetSpecAndStatus(issuer)
if err != nil {
- log.Error(err, "Fail to get spec and status for the issuer")
+ log.Error(err, "Failed to get spec and status for the issuer")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "failed to get spec and status for issuer")
return ctrl.Result{}, nil
}
@@ -144,289 +152,134 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if issuerSpec.AuthNamespace == "" {
issuerSpec.AuthNamespace = metav1.NamespaceDefault
}
- secretNamespace = issuerSpec.AuthNamespace
}
- // Checks if the MyCRD resource has been marked Ready
- if !pkiutil.MyCRDHasCondition(*issuerStatus, certmanagerv1.IssuerCondition{
- Type: certmanagerv1.IssuerConditionReady,
- Status: certmanagerv1.ConditionTrue,
+ if !IssuerHasCondition(*issuerStatus, ncmv1.IssuerCondition{
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
}) {
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
- "Failed: (Cluster)Issuer %s is not Ready; its condition is %s", issuerName, issuerStatus.Conditions)
- return ctrl.Result{}, err
- }
-
- // Once CRD resource is ready, the config data should be ready
- if NCMConfigMap == nil || NCMConfigMap[ncmapi.NCMConfigKey{
- Namespace: secretNamespace,
- Name: issuerName.Name}] == nil {
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending,
- "Failed: CRD configuration %s/%s is not Ready; type,status in myCRD.Status.Conditions=%s, cfg is nil=%v", secretNamespace, issuerName.Name, issuerStatus.Conditions, NCMConfigMap)
- return ctrl.Result{}, err
- }
-
- if apiutil.CertificateRequestIsDenied(&cr) {
- log.V(4).Info("certificate request has been denied")
- err := r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CSR has been denied")
- return ctrl.Result{}, err
- }
-
- if !apiutil.CertificateRequestIsApproved(&cr) {
- log.V(4).Info("certificate request has not been approved")
- return ctrl.Result{}, nil
- }
-
- if err = validateCertificateRequest(&cr); err != nil {
- log.Error(err, "certificate request has issues", "cr", req.NamespacedName)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Certificate request has issues: %v", err)
- return ctrl.Result{}, nil
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get (cluster) issuer %s is not Ready, its condition: %s", issuerName, issuerStatus.Conditions)
+ return ctrl.Result{}, errIssuerNotReady
}
- NCMCfg := NCMConfigMap[ncmapi.NCMConfigKey{Namespace: secretNamespace, Name: issuerName.Name}]
- NCMClient, err := ncmapi.NewClient(NCMCfg, log)
- if err != nil {
- log.Error(err, "failed to create NCM API Client")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create NCM API Client, make sure the config is set up correctly; %v", err)
- return ctrl.Result{}, nil
- }
-
- casResponse, err := NCMClient.GetCAs()
- if err != nil {
- log.Error(err, "failed to get CAs")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Please, check your external NCM server. Failed to get CAs; %v", err)
- go r.waitAndGetCAs(ctx, req, &cr, NCMClient, log)
- return ctrl.Result{}, nil
+ p, ok := r.Provisioners.Get(issuerName)
+ if !ok {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get provisioner for resource: %s", issuerName)
+ return ctrl.Result{}, errFailedGetProvisioner
}
- // Finds the certificate for bcmtncm
- issuingCA, found := findCA(casResponse, NCMCfg.CAsHREF, NCMCfg.CAsName)
- if !found {
- log.Info("CA certificate has not been found, please check provided CAsHREF/CAsNAME", "CAsHREF", NCMCfg.CAsHREF, "CAsNAME", NCMCfg.CAsName)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CA certificate has not been found, please check provided CAsHREF/CAsNAME URL=%s, CAsNAME=%s, CAsHREF=%s", NCMCfg.NCMServer+ncmapi.CAsURL, NCMCfg.CAsName, NCMCfg.CAsHREF)
+ crt := &cmapi.Certificate{}
+ if err := r.Client.Get(ctx, client.ObjectKey{
+ Namespace: req.Namespace, Name: cr.Annotations[cmapi.CertificateNameKey]}, crt); err != nil {
+ log.Error(err, "Certificate object not found")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "certificate object not found")
return ctrl.Result{}, nil
}
- var certChain []byte
- // Finds the root CA
- instaCA := &ncmapi.CAResponse{}
- lastCA := issuingCA
+ secretName := cr.Annotations[cmapi.CertificateNameKey] + "-details"
- for {
- log.Info("lastCA href: ", "href", lastCA.Href)
+ // At the very beginning we should check the basic conditions that determines
+ // whether the operation of certificate renewal should take place
+ isRevision := crt.Status.Revision != nil && *crt.Status.Revision >= 1
+ isRenewal := (isRevision && !p.NCMConfig.ReenrollmentOnRenew) ||
+ (isRevision && crt.Spec.PrivateKey != nil && crt.Spec.PrivateKey.RotationPolicy != "Always")
- lastCAURLPath, _ := ncmapi.GetPathFromCertURL(lastCA.Certificates["active"])
- currentCert, err := NCMClient.DownloadCertificate(lastCAURLPath)
- if err != nil {
- log.Error(err, "failed to download certificate", "certURL", lastCA.Certificates["active"])
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
- return ctrl.Result{}, nil
+ isSecretWithCertID := false
+ secretCertID := &core.Secret{}
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
+ if apierrors.IsNotFound(err) {
+ // This means that secret needed for renewal operations does not exist,
+ // and we should perform re-enrollment operation instead
+ isRenewal = false
+ } else {
+ return ctrl.Result{}, err
}
+ } else {
+ // This will prevent unnecessary checking to make sure that secret already
+ // exists when creating this secret, instead we will know that we
+ // have to update it
+ isSecretWithCertID = true
+ }
+
+ // We also need to check if the certificate's TLS secret has been deleted,
+ // which involves triggering a manual rotation of a private key
+ if isRenewal {
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: crt.Spec.SecretName}, &core.Secret{}); err != nil {
+ if apierrors.IsNotFound(err) {
+ isRenewal = false
+ } else {
+ return ctrl.Result{}, err
+ }
- if lastCA.Href == currentCert.IssuerCA || currentCert.IssuerCA == "" {
- break
}
+ }
- currentCertInPEM, err := NCMClient.DownloadCertificateInPEM(lastCAURLPath)
+ if isRenewal {
+ log.Info("Renewing", "certificate", cr.Annotations[cmapi.CertificateNameKey])
+ ca, tls, certID, err := p.Renew(cr, string(secretCertID.Data["cert-id"]))
if err != nil {
- log.Error(err, "failed to download certificate in PEM", "certURL", lastCA.Certificates["active"])
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate in PEM; %v", err)
- return ctrl.Result{}, nil
+ if errors.Is(err, provisioner.ErrFailedGetCAs) {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get CAs during renewal, requeuing...")
+ return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, err
+ }
+ log.Error(err, "failed to renew certificate")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to renew certificate err: %v", err)
+ return ctrl.Result{}, err
}
- certChain = addCertToChain(currentCertInPEM, certChain, NCMCfg.LittleEndianPem)
- lastCAURLPATH, _ := ncmapi.GetPathFromCertURL(currentCert.IssuerCA)
- lastCA, err = NCMClient.GetCA(lastCAURLPATH)
- if err != nil {
- log.Error(err, "failed to download CA certificate", "caURL", currentCert.IssuerCA)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download CA certificate; %v", err)
- return ctrl.Result{}, nil
+ secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
+ if err := r.Client.Update(ctx, secretCertID); err != nil {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to update secret err: %v", err)
+ return ctrl.Result{}, err
}
- }
-
- if NCMCfg.NoRoot && !NCMCfg.ChainInSigner {
- instaCA = issuingCA
- log.Info("Issuing CA certificate was found: ", "issuingCA", instaCA.Name)
- } else {
- instaCA = lastCA
- log.Info("Root CA certificate was found: ", "rootCA", instaCA.Name)
- }
-
- // Downloads root CA certificate or issuing CA certificate
- instaCAURLPath, _ := ncmapi.GetPathFromCertURL(instaCA.Certificates["active"])
- instaCAInPEM, err := NCMClient.DownloadCertificateInPEM(instaCAURLPath)
- if err != nil {
- log.Error(err, "failed to download root CA certificate or issuing CA certificate")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download root CA certificate or issuing CA certificate; %v", err)
- return ctrl.Result{}, nil
- }
-
- crt := cmapi.Certificate{}
- if err := r.Client.Get(ctx, client.ObjectKey{
- Namespace: req.Namespace, Name: cr.Annotations[cmapi.CertificateNameKey]}, &crt); err != nil {
- log.Error(err, "certificate object not found!")
- return ctrl.Result{}, nil
- }
-
- var leafCertInPEM []byte
- var secretName = cr.Annotations[cmapi.CertificateNameKey] + "-details"
- if crt.Status.Revision != nil {
- log.Info("Revision value was fetched", "revision", crt.Status.Revision)
+ cr.Status.CA = ca
+ cr.Status.Certificate = tls
} else {
- log.Info("Revision value is set to nil")
- }
-
- secretList, err := r.getSecretList(ctx, req)
- if err != nil {
- log.Error(err, "failed to list certificates resources")
- return ctrl.Result{}, nil
- }
-
- switch {
- case crt.Status.Revision != nil && *crt.Status.Revision >= 1 &&
- !NCMCfg.ReenrollmentOnRenew && crt.Spec.PrivateKey.RotationPolicy != "Always":
- if pkiutil.FindIfSecretExists(secretList, secretName) && pkiutil.FindIfSecretExists(secretList, crt.Spec.SecretName) {
- log.Info("Secret with cert-id will be updated")
- secretCertID := &core.Secret{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
- log.Error(err, "failed to get a secret with cert-id", "secretName", secretName)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to download secret err=%v", err)
- return ctrl.Result{}, nil
- }
-
- log.Info("Certificate href has been fetched", "href", string(secretCertID.Data["cert-id"]))
-
- certURLPath, _ := ncmapi.GetPathFromCertURL(string(secretCertID.Data["cert-id"]))
- renewCertResp, err := NCMClient.RenewCertificate(certURLPath, *cr.Spec.Duration, issuerSpec.ProfileId)
- if err != nil {
- log.Error(err, "failed to renew certificate")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate; %v", err)
+ log.Info("Singing", "certificate", cr.Annotations[cmapi.CertificateNameKey])
+ ca, tls, certID, err := p.Sign(cr)
+ if err != nil {
+ switch {
+ case errors.Is(err, provisioner.ErrFailedGetCAs):
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get CAs during signing, requeuing...")
+ return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, err
+ case errors.Is(err, provisioner.ErrCSRNotAccepted):
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CSR in NCM has not yet been approved, requeing...")
+ return ctrl.Result{RequeueAfter: CSRRequeueTime}, err
+ case errors.Is(err, provisioner.ErrCSRRejected):
+ log.Error(err, "CSR has been rejected, further actions should be taken manually")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "CSR has been rejected by NCM")
return ctrl.Result{}, nil
- }
-
- // Downloads the renewed certificate
- renewedCertURLPath, _ := ncmapi.GetPathFromCertURL(renewCertResp.Certificate)
- leafCertInPEM, err = NCMClient.DownloadCertificateInPEM(renewedCertURLPath)
- if err != nil {
- log.Error(err, "failed to download certificate", "certURL", renewCertResp.Certificate)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download certificate; %v", err)
+ case errors.Is(err, provisioner.ErrCSRCheckLimitExceeded):
+ log.Error(err, "CSR has not been accepted for too long time, further actions should be taken manually")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "CSR has not been accepted for too long time")
return ctrl.Result{}, nil
+ default:
+ log.Error(err, "unexpected error during certificate signing")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to sign certificate err: %v", err)
+ return ctrl.Result{}, err
}
+ }
- secretCertID = pkiutil.GetSecretObject(req.Namespace, secretName, renewCertResp.Certificate)
+ secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
+ if isSecretWithCertID {
if err := r.Client.Update(ctx, secretCertID); err != nil {
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update a secret err=%v", err)
- return ctrl.Result{}, nil
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to update secret err: %v", err)
+ return ctrl.Result{}, err
}
- break
- } else if !pkiutil.FindIfSecretExists(secretList, crt.Spec.SecretName) {
- log.Info("Manually rotation of a private key has been triggered")
- }
- fallthrough
- default:
- csrResp, err := NCMClient.SendCSR(cr.Spec.Request, issuingCA, issuerSpec.ProfileId)
- if err != nil {
- log.Error(err, "failed send CSR")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to send CSR cr.ObjectMeta.name=%s/%s; %v", cr.ObjectMeta.Name, cr.ObjectMeta.Namespace, err)
- return ctrl.Result{}, nil
- }
-
- requestedCertURLPath, _ := ncmapi.GetPathFromCertURL(csrResp.Href)
- csrStatusResp, err := NCMClient.CheckCSRStatus(requestedCertURLPath)
- if err != nil {
- log.Error(err, "failed to check CSR status")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
- return ctrl.Result{}, nil
- }
-
- validCSRStatus := checkCSRStatus(csrStatusResp)
- if strings.EqualFold(csrStatusResp.Status, "pending") {
- // Saves context: enqueues ( req, cr ) into job
- // Starts a new go route to:
- // 1. Checks CSR status
- // 2. Download Certificate if it is accepted
- // 3. Takes once again if it is pending
- validCSRStatus = true
-
- log.Error(err, "CSR status is pending")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to check CSR status; %v", err)
-
- go r.waitAndCheckCSRStatus(ctx, req, &cr, NCMClient, requestedCertURLPath, log)
-
- return ctrl.Result{}, nil
- }
-
- if !validCSRStatus {
- log.Error(err, "Invalid CSR status")
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Invalid CSR Status status=%s, cr.meta=%v; %v", csrStatusResp.Status, cr.ObjectMeta, err)
- return ctrl.Result{}, nil
- }
-
- // Downloads end-entity (leaf) certificate
- leafCertURLPath, _ := ncmapi.GetPathFromCertURL(csrStatusResp.Certificate)
- leafCertInPEM, err = NCMClient.DownloadCertificateInPEM(leafCertURLPath)
- if err != nil {
- log.Error(err, "failed to download end-entity certificate", "certURL", csrStatusResp.Certificate)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to download end-entity certificate tmp_endentity_ca_InPEM=%v; %v", leafCertInPEM, err)
- return ctrl.Result{}, nil
- }
-
- // Saves cert-id to secret
- if pkiutil.FindIfSecretExists(secretList, secretName) {
- log.Info("Secret with cert-id will be updated")
- secretCertID := pkiutil.GetSecretObject(req.Namespace, secretName, csrStatusResp.Certificate)
- err = r.Client.Update(ctx, secretCertID)
} else {
- log.Info("New secret with cert-id will be created")
- err = r.createSecret(ctx, req.Namespace, secretName, csrStatusResp.Certificate)
- }
-
- if err != nil {
- log.Error(err, "failed to create/update a secret with cert-id", "secretName", secretName)
- _ = r.setStatus(ctx, &cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create/update secret err=%v", err)
- return ctrl.Result{}, nil
+ if err := r.Client.Create(ctx, secretCertID); err != nil {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to create secret err: %v", err)
+ return ctrl.Result{}, err
+ }
}
- }
-
- // Stores the signed certificate data in the PEM chain
- log.Info("Storing PEM...")
-
- // Set PEMs
- if NCMCfg.ChainInSigner {
- var certChainWithRoot []byte
- certChainWithRoot = append(certChainWithRoot, certChain...)
- certChainWithRoot = addCertToChain(instaCAInPEM, certChainWithRoot, NCMCfg.LittleEndianPem)
- cr.Status.CA = certChainWithRoot
- } else {
- cr.Status.CA = instaCAInPEM
- }
-
- if !NCMCfg.OnlyEECert {
- certChain = addLeafCertToChain(leafCertInPEM, certChain, NCMCfg.LittleEndianPem)
- cr.Status.Certificate = certChain
- } else {
- cr.Status.Certificate = leafCertInPEM
+ cr.Status.CA = ca
+ cr.Status.Certificate = tls
}
// Finally, update the status
- return ctrl.Result{}, r.setStatus(ctx, &cr, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Successfully issued certificate")
-}
-
-func (r *CertificateRequestReconciler) getSecretList(ctx context.Context, req ctrl.Request) (core.SecretList, error) {
- secretList := core.SecretList{}
- options := client.ListOptions{Namespace: req.Namespace}
- err := r.Client.List(ctx, &secretList, &options)
-
- return secretList, err
-}
-
-func (r *CertificateRequestReconciler) createSecret(ctx context.Context, namespace string, name string, certID string) error {
- secret := pkiutil.GetSecretObject(namespace, name, certID)
- err := r.Client.Create(ctx, secret)
-
- return err
+ return ctrl.Result{}, r.setStatus(ctx, cr, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Successfully issued certificate")
}
func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.CertificateRequest, status cmmeta.ConditionStatus, reason, message string, args ...interface{}) error {
@@ -441,7 +294,6 @@ func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.
}
r.Recorder.Event(cr, eventType, reason, completeMessage)
- r.Log.Info(completeMessage)
// Updates the status
var err error
@@ -454,131 +306,8 @@ func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.
return nil
}
-// waitAndGetCAs waits and frequently checks to see if the NCM server is responding (NCM API client tries to get CAs).
-// When the server responds to a request for CAs triggers new round of reconcile
-func (r *CertificateRequestReconciler) waitAndGetCAs(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, client *ncmapi.Client, log logr.Logger) {
- CrPendingKey := CertificateRequestPendingKey{cr.ObjectMeta.Namespace, cr.ObjectMeta.Name}
-
- inFuncStr := "waitAndGetCAs"
- if CertificateRequestPendingList != nil && CertificateRequestPendingList[CrPendingKey] != nil {
- nowTime := metav1.NewTime(r.Clock.Now())
-
- if CertificateRequestPendingList[CrPendingKey].InState != inFuncStr {
- log.Info("!! multiple revoke CertificateRequestReconciler", "but status is", inFuncStr, "time", nowTime.Time)
- }
- // multiple revoke CertificateRequestReconciler, do nothing
- log.Info("multiple revoke CertificateRequestReconciler, do nothing ", "time", nowTime.Time)
-
- return
- }
-
- crPendingSt := CertificateRequestPendingState{}
- crPendingSt.InState = inFuncStr
-
- CertificateRequestPendingList[CrPendingKey] = &crPendingSt
-
- for {
- time.Sleep(SleepTime * time.Millisecond) // 20s
-
- nowTime := metav1.NewTime(r.Clock.Now())
- log.Info(inFuncStr, "time", nowTime.Time)
-
- // Fetch the CertificateRequest resource that was being synced
- newCr := cmapi.CertificateRequest{}
- if err := r.Client.Get(ctx, req.NamespacedName, &newCr); err != nil {
- log.Error(err, "failed to retrieve CertificateRequest resource while in waitAndGetCAs. Wait no longer")
- CertificateRequestPendingList[CrPendingKey] = nil
-
- return
- }
-
- // Checks if NCM server is responding to a request
- _, err := client.GetCAs()
- if err != nil {
- log.Error(err, "failed to get CAs")
- } else {
- log.Info(inFuncStr, "time", nowTime.Time, "OK", "NCM external server is responding")
-
- // Updates new Certifier status change, which triggers new round of reconcile
- // Status is updated from CertificateReasonPending to CertificateRequestReasonFailed
- CertificateRequestPendingList[CrPendingKey] = nil
-
- _ = r.setStatus(ctx, &newCr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now the external NCM server is ready to get CAs")
-
- break
- }
- }
-
-}
-
-// waitAndCheckCSRStatus waits and frequently checks if the CSR status is 'accepted'.
-// When CSR status is accepted triggers new round fo reconcile
-func (r *CertificateRequestReconciler) waitAndCheckCSRStatus(ctx context.Context, req ctrl.Request, cr *cmapi.CertificateRequest, c *ncmapi.Client, requestedCertURLPath string, log logr.Logger) {
- CrPendingKey := CertificateRequestPendingKey{cr.ObjectMeta.Namespace, cr.ObjectMeta.Name}
-
- inFuncStr := "waitAndCheckCSRStatus"
- if CertificateRequestPendingList != nil && CertificateRequestPendingList[CrPendingKey] != nil {
- nowTime := metav1.NewTime(r.Clock.Now())
- if CertificateRequestPendingList[CrPendingKey].InState != inFuncStr {
- log.Info("!! multiple revoke CertificateRequestReconciler but status is not waitAndCheckCSRStatus", "time", nowTime.Time)
- }
-
- // multiple revoke CertificateRequestReconciler, do nothing
- log.Info("multiple revoke CertificateRequestReconciler, do nothing ", "time", nowTime.Time)
-
- return
- }
-
- crPendingSt := CertificateRequestPendingState{}
- crPendingSt.InState = inFuncStr
-
- CertificateRequestPendingList[CrPendingKey] = &crPendingSt
-
- for {
- time.Sleep(SleepTime * time.Millisecond) // 20s
-
- nowTime := metav1.NewTime(r.Clock.Now())
- log.Info(inFuncStr, "time", nowTime.Time)
-
- // Fetch the CertificateRequest resource that was being synced
- newCr := cmapi.CertificateRequest{}
- if err := r.Client.Get(ctx, req.NamespacedName, &newCr); err != nil {
- CertificateRequestPendingList[CrPendingKey] = nil
- log.Error(err, "failed to retrieve CertificateRequest resource while in waitAndCheckCSRStatus. Wait no longer")
-
- return
- }
-
- // Checks the CSR status
- csrStatusResp, err := c.CheckCSRStatus(requestedCertURLPath)
- if err != nil {
- log.Error(err, "failed to check CSR status")
- } else {
- if strings.EqualFold(csrStatusResp.Status, "accepted") {
- // Continues to trigger new round CSR
- log.Info(inFuncStr, "time", nowTime.Time, "OK", "CSR status is accepted")
-
- // Updates new CertificateRequest status change, which trigger new round of reconcile
- // Status is updated from CertificateRequestReasonPending to CertificateRequestReasonFailed
- CertificateRequestPendingList[CrPendingKey] = nil
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Now CSR status is OK")
-
- break
- }
-
- if strings.EqualFold(csrStatusResp.Status, "pending") {
- log.Info("CSR status is still pending")
- }
- }
- }
-}
-
func (r *CertificateRequestReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&cmapi.CertificateRequest{}).
Complete(r)
}
-
-func checkCSRStatus(csrStatusResp *ncmapi.CSRStatusResponse) bool {
- return strings.EqualFold(csrStatusResp.Status, "accepted")
-}
From 803992c8eab8429d54667c33520fbe26878f9298 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 13:03:05 +0100
Subject: [PATCH 063/175] Organised utils in plugin
---
pkg/controllers/util.go | 97 ++++++++++++++++++++++++++---------------
pkg/util/csr.go | 2 +-
pkg/util/decode.go | 2 +-
pkg/util/file.go | 71 ------------------------------
pkg/util/validate.go | 2 +-
5 files changed, 64 insertions(+), 110 deletions(-)
diff --git a/pkg/controllers/util.go b/pkg/controllers/util.go
index f86c097..8ce81b7 100644
--- a/pkg/controllers/util.go
+++ b/pkg/controllers/util.go
@@ -2,20 +2,76 @@ package controllers
import (
"fmt"
- "github.com/nokia/ncm-issuer/pkg/ncmapi"
- "github.com/nokia/ncm-issuer/pkg/pkiutil"
- "regexp"
- "strings"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ ncmutil "github.com/nokia/ncm-issuer/pkg/util"
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
)
+func GetSpecAndStatus(issuer client.Object) (*ncmv1.IssuerSpec, *ncmv1.IssuerStatus, error) {
+ switch t := issuer.(type) {
+ case *ncmv1.Issuer:
+ return &t.Spec, &t.Status, nil
+ case *ncmv1.ClusterIssuer:
+ return &t.Spec, &t.Status, nil
+ default:
+ return nil, nil, fmt.Errorf("not an issuer type: %t", t)
+ }
+}
+
+func GetSecretNamespace(issuer client.Object, req ctrl.Request) (string, error) {
+ switch t := issuer.(type) {
+ case *ncmv1.Issuer:
+ return req.Namespace, nil
+ case *ncmv1.ClusterIssuer:
+ if t.Spec.AuthNamespace == "" {
+ t.Spec.AuthNamespace = metav1.NamespaceDefault
+ }
+ return t.Spec.AuthNamespace, nil
+ default:
+ return "", fmt.Errorf("not an issuer type: %t", t)
+ }
+}
+
+// IssuerHasCondition will return true if the given issuer has a
+// condition matching the provided IssuerCondition.
+// Only the Type and Status field will be used in the comparison, meaning that
+// this function will return 'true' even if the Reason, Message and
+// LastTransitionTime fields do not match.
+func IssuerHasCondition(status ncmv1.IssuerStatus, c ncmv1.IssuerCondition) bool {
+ existingConditions := status.Conditions
+ for _, cond := range existingConditions {
+ if c.Type == cond.Type && c.Status == cond.Status {
+ return true
+ }
+ }
+ return false
+}
+
+func GetCertIDSecret(namespace string, name string, certID string) *v1.Secret {
+ secret := v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: namespace,
+ Name: name,
+ },
+ StringData: map[string]string{
+ "cert-id": certID,
+ },
+ Type: v1.SecretTypeOpaque,
+ }
+ return &secret
+}
+
func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
if len(cr.Spec.Request) == 0 {
return fmt.Errorf("certificate request is empty")
}
- csr, err := pkiutil.DecodeX509CertificateRequestBytes(cr.Spec.Request)
+ csr, err := ncmutil.DecodeX509CertificateRequestBytes(cr.Spec.Request)
if err != nil {
return fmt.Errorf("failed to decode CSR for validation: %v", err)
}
@@ -26,34 +82,3 @@ func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
return nil
}
-
-func findCA(casResponse *ncmapi.CAsResponse, CAsHREF, CAsNAME string) (*ncmapi.CAResponse, bool) {
- hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
- for _, ca := range casResponse.CAList {
- if strings.EqualFold(ca.Status, "active") {
- if CAsHREF != "" {
- href := hrefRegex.Find([]byte(ca.Href))
- if string(href) == CAsHREF {
- return &ca, true
- }
- } else if ca.Name == CAsNAME {
- return &ca, true
- }
- }
- }
- return nil, false
-}
-
-func addCertToChain(crt, crtChain []byte, littleEndian bool) []byte {
- if littleEndian {
- return append(crt, crtChain...)
- }
- return append(crtChain, crt...)
-}
-
-func addLeafCertToChain(leafCrt, crtChain []byte, littleEndian bool) []byte {
- if littleEndian {
- return append(crtChain, leafCrt...)
- }
- return append(leafCrt, crtChain...)
-}
diff --git a/pkg/util/csr.go b/pkg/util/csr.go
index 4881842..66714c9 100644
--- a/pkg/util/csr.go
+++ b/pkg/util/csr.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package pkiutil
+package util
import (
"crypto/rand"
diff --git a/pkg/util/decode.go b/pkg/util/decode.go
index 84c48ac..2454b24 100644
--- a/pkg/util/decode.go
+++ b/pkg/util/decode.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package pkiutil
+package util
import (
"crypto"
diff --git a/pkg/util/file.go b/pkg/util/file.go
index 3e8ab5e..d8015dc 100644
--- a/pkg/util/file.go
+++ b/pkg/util/file.go
@@ -1,71 +1,9 @@
package util
import (
- "fmt"
- "net/url"
"os"
-
- ncmv1 "github.com/nokia/ncm-issuer/api/v1"
- "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
)
-func GetSpecAndStatus(issuer client.Object) (*ncmv1.IssuerSpec, *ncmv1.IssuerStatus, error) {
- switch t := issuer.(type) {
- case *ncmv1.Issuer:
- return &t.Spec, &t.Status, nil
- case *ncmv1.ClusterIssuer:
- return &t.Spec, &t.Status, nil
- default:
- return nil, nil, fmt.Errorf("not an issuer type: %t", t)
- }
-}
-
-func GetSecretNamespace(issuer client.Object, req ctrl.Request) (string, error) {
- switch t := issuer.(type) {
- case *ncmv1.Issuer:
- return req.Namespace, nil
- case *ncmv1.ClusterIssuer:
- if t.Spec.AuthNamespace == "" {
- t.Spec.AuthNamespace = metav1.NamespaceDefault
- }
- return t.Spec.AuthNamespace, nil
- default:
- return "", fmt.Errorf("not an issuer type: %t", t)
- }
-}
-
-// IssuerHasCondition will return true if the given issuer has a
-// condition matching the provided IssuerCondition.
-// Only the Type and Status field will be used in the comparison, meaning that
-// this function will return 'true' even if the Reason, Message and
-// LastTransitionTime fields do not match.
-func IssuerHasCondition(status ncmv1.IssuerStatus, c ncmv1.IssuerCondition) bool {
- existingConditions := status.Conditions
- for _, cond := range existingConditions {
- if c.Type == cond.Type && c.Status == cond.Status {
- return true
- }
- }
- return false
-}
-
-func GetCertIDSecret(namespace string, name string, certID string) *v1.Secret {
- secret := v1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Namespace: namespace,
- Name: name,
- },
- StringData: map[string]string{
- "cert-id": certID,
- },
- Type: v1.SecretTypeOpaque,
- }
- return &secret
-}
-
// WritePEMToTempFile writes PEM to temporary file.
func WritePEMToTempFile(pem []byte) (string, error) {
csrFile, err := os.CreateTemp("", "*.pem")
@@ -86,12 +24,3 @@ func WritePEMToTempFile(pem []byte) (string, error) {
return path, err
}
-
-func GetPathFromCertHref(certHref string) (string, error) {
- parsedURL, err := url.Parse(certHref)
- if err != nil {
- return "", fmt.Errorf("cannot parsed given href: %s", certHref)
- }
-
- return parsedURL.Path, nil
-}
diff --git a/pkg/util/validate.go b/pkg/util/validate.go
index 9ab9be8..6dbc1af 100644
--- a/pkg/util/validate.go
+++ b/pkg/util/validate.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package pkiutil
+package util
import (
"crypto"
From 306930151675cb90355caef8d7f8f5c6139e7a1f Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 13:04:05 +0100
Subject: [PATCH 064/175] Fixed nil pointer dereference during renewal
---
pkg/ncmapi/ncmapi.go | 117 +++++++++++---------------------------
pkg/ncmapi/ncmapi_test.go | 4 +-
pkg/ncmapi/util.go | 15 +++++
3 files changed, 49 insertions(+), 87 deletions(-)
create mode 100644 pkg/ncmapi/util.go
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 0a37daa..167ddc1 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -16,6 +16,9 @@ import (
"time"
"github.com/go-logr/logr"
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+ "github.com/nokia/ncm-issuer/pkg/cfg"
+ ncmutil "github.com/nokia/ncm-issuer/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -25,80 +28,19 @@ const (
CSRURL = "/v1/requests"
)
-// NCMConfig is a config set up with secret and used for NCM API Client configuration
-type NCMConfig struct {
- Username string
- UsrPassword string
- NCMServer string
- NCMServer2 string
-
- // CAsName is a CAs for bcmtncm
- CAsName string
-
- // CAsHREF is a HREF for bcmtncm
- CAsHREF string
-
- // ReenrollmentOnRenew determines whether during renewal certificate
- // should be re-enrolled instead of renewed
- ReenrollmentOnRenew bool
-
- UseProfileIDForRenew bool
-
- // InstaCA is a NCM root CA
- InstaCA string
-
- // LittleEndianPem determines
- LittleEndianPem bool // bigEndian or littleEndian: bE Cert -> Issuers; lE Issuers -> Cert
-
- // NoRoot determines whether issuing CA certificate should be included
- // in ca.crt instead of root CA certificate
- NoRoot bool
-
- // ChainInSigner determines whether certificate chain should be included in ca.crt
- // (intermediate certificates + issuing CA certificate + root CA certificate)
- ChainInSigner bool
-
- // OnlyEECert determines whether only end-entity certificate should be included
- // in tls.crt
- OnlyEECert bool
-
- // CACert is a TLS CA certificate
- CACert string
-
- // Key is a TLS client key
- Key string
-
- // Cert is a TLS client certificate
- Cert string
-
- // InsecureSkipVerify determines whether SSL certificate verification between client
- // instance and NCM EXTERNAL API should be enabled
- InsecureSkipVerify bool
-
- // MTLS determines whether mTLS should be enabled
- MTLS bool
-}
-
-// NCMConfigKey is a structure used to separate different configurations for
-// different namespaces
-type NCMConfigKey struct {
- Namespace string
- Name string
-}
-
-// Client is a client used to communicate with the NCM EXTERNAL API
+// Client is a client used to communicate with the NCM API
type Client struct {
- // NCMServer is a main NCM EXTERNAL API server address
+ // NCMServer is a main NCM API server address
NCMServer string
- // NCMServer2 is a secondary NCM EXTERNAL API server address
+ // NCMServer2 is a secondary NCM API server address
// in case of the lack of connection to the main one (can be empty)
NCMServer2 string
- // user is a user used for authentication to NCM EXTERNAL API
+ // user is a user used for authentication to NCM API
user string
- // password is a password used for authentication to NCM EXTERNAL API
+ // password is a password used for authentication to NCM API
password string
// allowRetry determines whether, in the case of lack of the connection
@@ -107,7 +49,7 @@ type Client struct {
// client can send the same request
allowRetry bool
- // userProfileIDForRenew determines whether the profile ID should be used
+ // useProfileIDForRenew determines whether the profile ID should be used
// during a certificate renewal operation
useProfileIDForRenew bool
@@ -176,12 +118,12 @@ type APIError struct {
}
func (a *APIError) Error() string {
- return fmt.Sprintf("NCM EXTERNAL API Error status: %d, message: %s, statusMessage: %s", a.Status, a.Message, a.StatusMessage)
+ return fmt.Sprintf("NCM API Error status: %d, message: %s, statusMessage: %s", a.Status, a.Message, a.StatusMessage)
}
// NewClient creates a new client used to perform requests to
-// the NCM EXTERNAL API
-func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
+// the NCM API
+func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
NCMServerURL, err := url.Parse(cfg.NCMServer)
if err != nil {
return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
@@ -202,7 +144,7 @@ func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
NCMServer2: NCMServer2URL.String(),
allowRetry: cfg.NCMServer2 != "",
user: cfg.Username,
- password: cfg.UsrPassword,
+ password: cfg.Password,
useProfileIDForRenew: cfg.UseProfileIDForRenew,
client: client,
log: log,
@@ -212,8 +154,8 @@ func NewClient(cfg *NCMConfig, log logr.Logger) (*Client, error) {
}
// configureHTTPClient configures http.Client used for connection
-// to NCM EXTERNAL API according to NCM config
-func configureHTTPClient(cfg *NCMConfig) (*http.Client, error) {
+// to NCM API according to NCM config
+func configureHTTPClient(cfg *cfg.NCMConfig) (*http.Client, error) {
if !strings.HasPrefix(cfg.NCMServer, "https") {
client := &http.Client{
Timeout: DefaultHTTPTimeout * time.Second,
@@ -277,7 +219,7 @@ func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request,
}
func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
- c.log.Info("retrying request to secondary NCM EXTERNAL API", "serverURL", c.NCMServer2)
+ c.log.Info("retrying request to secondary NCM API", "serverURL", c.NCMServer2)
NCMServer2URL, _ := url.Parse(c.NCMServer2)
req.URL.Host = NCMServer2URL.Host
@@ -285,7 +227,7 @@ func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
if err != nil {
return nil, &ClientError{Reason: "cannot perform request", ErrorMessage: err}
}
- c.log.Info("received response from secondary NCM EXTERNAL API", "serverURL", c.NCMServer2, "status", resp.StatusCode)
+ c.log.Info("received response from secondary NCM API", "serverURL", c.NCMServer2, "status", resp.StatusCode)
return resp, nil
}
@@ -314,7 +256,7 @@ func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
resp, err := c.client.Do(req)
if err != nil {
- c.log.Info("main NCM EXTERNAL API seems not responding", "serverURL", c.NCMServer, "err", err)
+ c.log.Info("main NCM API seems not responding", "serverURL", c.NCMServer, "err", err)
if c.allowRetry {
resp, err = c.retryRequest(req)
if err != nil {
@@ -326,7 +268,7 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
}
if c.allowRetry && resp.StatusCode >= 500 && resp.StatusCode < 600 {
- c.log.Info("main NCM EXTERNAL API returned server error status code", "serverURL", c.NCMServer, "status", resp.StatusCode)
+ c.log.Info("main NCM API returned server error status code", "serverURL", c.NCMServer, "status", resp.StatusCode)
resp, err = c.retryRequest(req)
if err != nil {
return nil, err
@@ -390,8 +332,8 @@ func (c *Client) GetCA(path string) (*CAResponse, error) {
return &ca, nil
}
-func (c *Client) SendCSR(pem []byte, CA *CAResponse, profileId string) (*CSRResponse, error) {
- filePath, err := WritePemToTempFile("/tmp/ncm", pem)
+func (c *Client) SendCSR(pem []byte, CA *CAResponse, profileID string) (*CSRResponse, error) {
+ filePath, err := ncmutil.WritePEMToTempFile(pem)
if err != nil {
return nil, &ClientError{Reason: "cannot write PEM to file", ErrorMessage: err}
}
@@ -400,8 +342,8 @@ func (c *Client) SendCSR(pem []byte, CA *CAResponse, profileId string) (*CSRResp
"ca": CA.Href,
}
- if profileId != "" {
- params["profileId"] = profileId
+ if profileID != "" {
+ params["profileId"] = profileID
}
file, err := os.Open(filePath)
@@ -534,17 +476,22 @@ func (c *Client) DownloadCertificateInPEM(path string) ([]byte, error) {
return body, nil
}
-func (c *Client) RenewCertificate(path string, certDuration metav1.Duration, profileId string) (*RenewCertificateResponse, error) {
+func (c *Client) RenewCertificate(path string, duration *metav1.Duration, profileID string) (*RenewCertificateResponse, error) {
+ certDuration := cmapi.DefaultCertificateDuration
+ if duration != nil {
+ certDuration = duration.Duration
+ }
+
notBefore := time.Now()
- notAfter := notBefore.Add(certDuration.Duration)
+ notAfter := notBefore.Add(certDuration)
newData := map[string]string{
"notBefore": notBefore.Format(time.RFC3339Nano),
"notAfter": notAfter.Format(time.RFC3339Nano),
}
- if profileId != "" && c.useProfileIDForRenew {
- newData["profileId"] = profileId
+ if profileID != "" && c.useProfileIDForRenew {
+ newData["profileId"] = profileID
}
jsonData, _ := json.Marshal(&newData)
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 27cebc2..541b9da 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -17,7 +17,7 @@ func TestNewClientCreation(t *testing.T) {
expectedError error
}{
{
- name: "invalid NCM EXTERNAL API URL",
+ name: "invalid NCM API URL",
cfg: &NCMConfig{
NCMServer: "https://malformed url.com:80",
},
@@ -25,7 +25,7 @@ func TestNewClientCreation(t *testing.T) {
expectedError: &ClientError{},
},
{
- name: "invalid 2nd NCM EXTERNAL API URL",
+ name: "invalid 2nd NCM API URL",
cfg: &NCMConfig{
NCMServer: "https://working-url.com:3000",
NCMServer2: "https://malformed url.com:-17",
diff --git a/pkg/ncmapi/util.go b/pkg/ncmapi/util.go
new file mode 100644
index 0000000..17988c6
--- /dev/null
+++ b/pkg/ncmapi/util.go
@@ -0,0 +1,15 @@
+package ncmapi
+
+import (
+ "fmt"
+ "net/url"
+)
+
+func GetPathFromCertHref(certHref string) (string, error) {
+ parsedURL, err := url.Parse(certHref)
+ if err != nil {
+ return "", fmt.Errorf("cannot parsed given href: %s", certHref)
+ }
+
+ return parsedURL.Path, nil
+}
From b0c3743fea3d19101dc3c284ab9e3b2f52e248a1 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 3 Mar 2023 13:05:31 +0100
Subject: [PATCH 065/175] Updated Dockerfile
---
Dockerfile | 6 ++++--
api/v1/issuer_types.go | 4 ++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 83da19a..71c8a06 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,9 +12,11 @@ COPY vendor/ vendor/
# Copy the go source
COPY main.go main.go
COPY api/ api/
-COPY pkg/pkiutil pkg/pkiutil/
-COPY pkg/controllers pkg/controllers/
+COPY pkg/cfg pkg/cfg/
+COPY pkg/util pkg/util/
COPY pkg/ncmapi pkg/ncmapi/
+COPY pkg/provisioner pkg/provisioner/
+COPY pkg/controllers pkg/controllers/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go
diff --git a/api/v1/issuer_types.go b/api/v1/issuer_types.go
index 18916ef..58a166b 100644
--- a/api/v1/issuer_types.go
+++ b/api/v1/issuer_types.go
@@ -45,8 +45,8 @@ type IssuerSpec struct {
AuthSecretName string `json:"secretName"`
// +optional
- // ProfileId API parameter
- ProfileId string `json:"profileId,omitempty"`
+ // ProfileID API parameter
+ ProfileID string `json:"profileId,omitempty"`
// +optional
// The secret which contains TLS configuration to external NCM server
From 0aa39ace24dc6c14d8d233b3dd394faeab2c2855 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 15 Mar 2023 21:56:23 +0100
Subject: [PATCH 066/175] Added unit tests for provisioner
---
.../certificaterequest_controller.go | 4 +-
pkg/ncmapi/external.go | 15 +
pkg/ncmapi/ncmapi.go | 10 +-
pkg/provisioner/ncm.go | 22 +-
pkg/provisioner/ncm_test.go | 718 ++++++++++++++++++
pkg/provisioner/util.go | 4 +
release_notes.txt | 11 +-
test/unit/ncmapi.go | 153 ++++
8 files changed, 919 insertions(+), 18 deletions(-)
create mode 100644 pkg/ncmapi/external.go
create mode 100644 pkg/provisioner/ncm_test.go
create mode 100644 test/unit/ncmapi.go
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index a83401b..99837c3 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -181,8 +181,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// At the very beginning we should check the basic conditions that determines
// whether the operation of certificate renewal should take place
isRevision := crt.Status.Revision != nil && *crt.Status.Revision >= 1
- isRenewal := (isRevision && !p.NCMConfig.ReenrollmentOnRenew) ||
- (isRevision && crt.Spec.PrivateKey != nil && crt.Spec.PrivateKey.RotationPolicy != "Always")
+ isPKRotationAlways := crt.Spec.PrivateKey != nil && crt.Spec.PrivateKey.RotationPolicy == "Always"
+ isRenewal := isRevision && !p.NCMConfig.ReenrollmentOnRenew && !isPKRotationAlways
isSecretWithCertID := false
secretCertID := &core.Secret{}
diff --git a/pkg/ncmapi/external.go b/pkg/ncmapi/external.go
new file mode 100644
index 0000000..d707d21
--- /dev/null
+++ b/pkg/ncmapi/external.go
@@ -0,0 +1,15 @@
+package ncmapi
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+type ExternalClient interface {
+ GetCAs() (*CAsResponse, error)
+ GetCA(path string) (*CAResponse, error)
+ SendCSR(pem []byte, CA *CAResponse, profileID string) (*CSRResponse, error)
+ CheckCSRStatus(path string) (*CSRStatusResponse, error)
+ DownloadCertificate(path string) (*CertificateDownloadResponse, error)
+ DownloadCertificateInPEM(path string) ([]byte, error)
+ RenewCertificate(path string, duration *metav1.Duration, profileID string) (*RenewCertificateResponse, error)
+}
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 167ddc1..0b2dd87 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -24,8 +24,8 @@ import (
const (
DefaultHTTPTimeout = 10
- CAsURL = "/v1/cas"
- CSRURL = "/v1/requests"
+ CAsPath = "/v1/cas"
+ CSRPath = "/v1/requests"
)
// Client is a client used to communicate with the NCM API
@@ -57,6 +57,8 @@ type Client struct {
log logr.Logger
}
+var _ ExternalClient = &Client{}
+
type ClientError struct {
Reason string
ErrorMessage error
@@ -281,7 +283,7 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
func (c *Client) GetCAs() (*CAsResponse, error) {
params := url.Values{}
- req, err := c.newRequest(http.MethodGet, CAsURL, strings.NewReader(params.Encode()))
+ req, err := c.newRequest(http.MethodGet, CAsPath, strings.NewReader(params.Encode()))
if err != nil {
return nil, err
}
@@ -371,7 +373,7 @@ func (c *Client) SendCSR(pem []byte, CA *CAResponse, profileID string) (*CSRResp
return nil, &ClientError{Reason: "cannot close writer", ErrorMessage: err}
}
- req, err := c.newRequest(http.MethodPost, CSRURL, body)
+ req, err := c.newRequest(http.MethodPost, CSRPath, body)
if err != nil {
return nil, err
}
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
index b917859..f75c49b 100644
--- a/pkg/provisioner/ncm.go
+++ b/pkg/provisioner/ncm.go
@@ -71,7 +71,7 @@ func (pm *ProvisionersMap) AddOrReplace(NamespacedName types.NamespacedName, pro
// Provisioner allows Sign or Renew certificate using NCMClient.
type Provisioner struct {
NCMConfig *cfg.NCMConfig
- NCMClient *ncmapi.Client
+ NCMClient ncmapi.ExternalClient
pendingCSRs *PendingCSRsMap
log logr.Logger
}
@@ -175,7 +175,6 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
if err != nil {
return nil, nil, "", fmt.Errorf("failed to send CSR, err: %v", err)
}
- p.log.Info("CSR in NCM", "CSR", csrResp, "href in CSR", csrResp.Href)
requestedCertURLPath, _ := ncmapi.GetPathFromCertHref(csrResp.Href)
csrStatusResp, err := p.NCMClient.CheckCSRStatus(requestedCertURLPath)
@@ -241,11 +240,10 @@ func (p *Provisioner) Renew(cr *cmapi.CertificateRequest, certID string) ([]byte
// (given CA certificate in NCMConfig or root CA certificate).
func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte, []byte, error) {
var certChain []byte
- wantedCA := &ncmapi.CAResponse{}
lastCheckedCA := signingCA
for {
- p.log.Info("Last checked CA certificate in certificate chain", "href", lastCheckedCA.Href)
+ p.log.Info("Last checked CA certificate in chain", "href", lastCheckedCA.Href)
lastCheckedCAURLPath, _ := ncmapi.GetPathFromCertHref(lastCheckedCA.Certificates["active"])
currentCACert, err := p.NCMClient.DownloadCertificate(lastCheckedCAURLPath)
@@ -253,7 +251,7 @@ func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte,
return nil, nil, fmt.Errorf("failed to download CA certificate, its href: %s, err: %v", lastCheckedCA.Certificates["active"], err)
}
- if lastCheckedCA.Href == currentCACert.IssuerCA || currentCACert.IssuerCA == "" {
+ if isRootCA(lastCheckedCA, currentCACert) {
break
}
@@ -270,13 +268,8 @@ func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte,
}
}
- if p.NCMConfig.NoRoot && !p.NCMConfig.ChainInSigner {
- wantedCA = signingCA
- } else {
- wantedCA = lastCheckedCA
- }
+ wantedCA := p.getWantedCA(signingCA, lastCheckedCA)
p.log.Info("Signing CA certificate was found and selected according to configuration", "isRootCA", !p.NCMConfig.NoRoot || p.NCMConfig.ChainInSigner, "Name", wantedCA.Name)
-
wantedCAURLPath, _ := ncmapi.GetPathFromCertHref(wantedCA.Certificates["active"])
wantedCAInPEM, err := p.NCMClient.DownloadCertificateInPEM(wantedCAURLPath)
if err != nil {
@@ -286,6 +279,13 @@ func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte,
return certChain, wantedCAInPEM, nil
}
+func (p *Provisioner) getWantedCA(signingCA, rootCA *ncmapi.CAResponse) *ncmapi.CAResponse {
+ if p.NCMConfig.NoRoot && !p.NCMConfig.ChainInSigner {
+ return signingCA
+ }
+ return rootCA
+}
+
// prepareCAAndTLS prepares values needed for certificate (ca.crt and tls.crt)
// according to NCMConfig.
func (p *Provisioner) prepareCAAndTLS(wantedCA, leafCert, certChain []byte) ([]byte, []byte) {
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
new file mode 100644
index 0000000..a28db05
--- /dev/null
+++ b/pkg/provisioner/ncm_test.go
@@ -0,0 +1,718 @@
+package provisioner
+
+import (
+ "errors"
+ "strings"
+ "sync"
+ "testing"
+
+ testr "github.com/go-logr/logr/testing"
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+ "github.com/nokia/ncm-issuer/pkg/cfg"
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
+ "github.com/nokia/ncm-issuer/test/unit"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+var (
+ crt1 = ncmapi.CAResponse{
+ Href: "https://ncm-server.local/cas/Mn012Se",
+ Name: "ncmCA",
+ Status: "active",
+ Certificates: map[string]string{
+ "active": "https://ncm-servver-local/certificate/Mn012Se",
+ },
+ }
+
+ crt2 = ncmapi.CAResponse{
+ Href: "https://ncm-server.local/cas/eS210nM",
+ Name: "ncmCA2",
+ Status: "active",
+ Certificates: map[string]string{
+ "active": "https://ncm-servver-local/certificate/eS210nM",
+ },
+ }
+
+ crt3 = ncmapi.CAResponse{
+ Href: "https://ncm-server.local/cas/efG312Ed",
+ Name: "ncmCA3",
+ Status: "expired",
+ Certificates: map[string]string{},
+ }
+
+ CAsResponse = &ncmapi.CAsResponse{
+ TotalCount: 3,
+ Href: "https://ncm-server.local/cas",
+ CAList: []ncmapi.CAResponse{crt1, crt2, crt3},
+ }
+
+ cr = cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ Request: []byte("-----BEGIN CERTIFICATE-----\nR3Qu3St...\n-----END CERTIFICATE-----\n"),
+ },
+ }
+)
+
+func TestFindCA(t *testing.T) {
+ type testCase struct {
+ name string
+ CAsHref string
+ CAsName string
+ CAsResponse *ncmapi.CAsResponse
+ isFindable bool
+ expectedCA *ncmapi.CAResponse
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ _, found := findCA(tc.CAsResponse, tc.CAsHref, tc.CAsName)
+
+ if tc.isFindable != found {
+ t.Fatalf("%s failed; expected (not) to find CA certificate; got %t; want %t", tc.name, found, tc.isFindable)
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "Findable by CAsName",
+ CAsHref: "",
+ CAsName: "ncmCA2",
+ CAsResponse: CAsResponse,
+ isFindable: true,
+ expectedCA: &crt2,
+ },
+ {
+ name: "Findable by CAsHref",
+ CAsHref: "Mn012Se",
+ CAsName: "",
+ CAsResponse: CAsResponse,
+ isFindable: true,
+ expectedCA: &crt1,
+ },
+ {
+ name: "CAsName case sensitive",
+ CAsHref: "",
+ CAsName: "NCMca2",
+ CAsResponse: CAsResponse,
+ isFindable: false,
+ expectedCA: &ncmapi.CAResponse{},
+ },
+ {
+ name: "CAsHref case sensitive",
+ CAsHref: "mN012sE",
+ CAsName: "",
+ CAsResponse: CAsResponse,
+ isFindable: false,
+ expectedCA: &ncmapi.CAResponse{},
+ },
+ {
+ name: "CA certificate findable but not active",
+ CAsHref: "efG312Ed",
+ CAsName: "ncmCA3",
+ CAsResponse: CAsResponse,
+ isFindable: false,
+ expectedCA: &ncmapi.CAResponse{},
+ },
+ {
+ name: "Empty CAsName & CAsHref",
+ CAsHref: "",
+ CAsName: "",
+ CAsResponse: CAsResponse,
+ isFindable: false,
+ expectedCA: &ncmapi.CAResponse{},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestGetChainAndWantedCA(t *testing.T) {
+ type testCase struct {
+ name string
+ fakeClient ncmapi.ExternalClient
+ err error
+ expectedChain []byte
+ expectedCA []byte
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ p := &Provisioner{
+ NCMConfig: &cfg.NCMConfig{},
+ NCMClient: tc.fakeClient,
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ }
+
+ chain, ca, err := p.getChainAndWantedCA(&crt1)
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; want %s", tc.name, err.Error(), tc.err.Error())
+ }
+
+ if string(tc.expectedCA) != string(ca) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ }
+
+ if string(tc.expectedChain) != string(chain) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(chain), string(tc.expectedChain))
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "Successfully get chain & CA",
+ fakeClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ err: nil,
+ expectedChain: []byte(""),
+ expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
+ },
+ {
+ name: "Failed to get chain & CA (cannot download certificate)",
+ fakeClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientDownloadCertificate(errors.New("failed to download CA certificate")),
+ unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ err: errors.New("failed to download CA certificate"),
+ expectedChain: []byte(""),
+ expectedCA: []byte(""),
+ },
+ {
+ name: "Failed to get chain & CA (cannot download certificate in PEM)",
+ fakeClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(errors.New("failed to download CA certificate in PEM")),
+ ),
+ err: errors.New("failed to download CA certificate in PEM"),
+ expectedChain: []byte(""),
+ expectedCA: []byte(""),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestPreparingCAAndTLS(t *testing.T) {
+ type testCase struct {
+ name string
+ config *cfg.NCMConfig
+ expectedCA []byte
+ expectedTLS []byte
+ }
+
+ rootCA := []byte("-----BEGIN CERTIFICATE-----\nR00TC4...\n-----END CERTIFICATE-----\n")
+ interCA := []byte("-----BEGIN CERTIFICATE-----\n1NT3RC4...\n-----END CERTIFICATE-----\n")
+ signingCA := []byte("-----BEGIN CERTIFICATE-----\n1SSU1NGC4...\n-----END CERTIFICATE-----\n")
+ leafCert := []byte("-----BEGIN CERTIFICATE-----\nL34FC4RT...\n-----END CERTIFICATE-----\n")
+
+ run := func(t *testing.T, tc testCase) {
+
+ p, _ := NewProvisioner(tc.config, &testr.TestLogger{T: t})
+ ca, tls := p.prepareCAAndTLS(rootCA, leafCert, func() []byte {
+ if tc.config.LittleEndian {
+ return append(interCA, signingCA...)
+ }
+ return append(signingCA, interCA...)
+ }())
+
+ if string(tc.expectedCA) != string(ca) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ }
+
+ if string(tc.expectedTLS) != string(tls) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "All CA and TLS manipulation options set to false",
+ config: &cfg.NCMConfig{},
+ expectedCA: rootCA,
+ expectedTLS: append(leafCert, append(signingCA, interCA...)...),
+ },
+ {
+ name: "littleEndian set to true",
+ config: &cfg.NCMConfig{
+ LittleEndian: true,
+ },
+ expectedCA: rootCA,
+ expectedTLS: append(interCA, append(signingCA, leafCert...)...),
+ },
+ {
+ name: "chainInSigner set to true",
+ config: &cfg.NCMConfig{
+ ChainInSigner: true,
+ },
+ expectedCA: append(signingCA, append(interCA, rootCA...)...),
+ expectedTLS: append(leafCert, append(signingCA, interCA...)...),
+ },
+ {
+ name: "littleEndian & chainInSigner set to true",
+ config: &cfg.NCMConfig{
+ LittleEndian: true,
+ ChainInSigner: true,
+ },
+ expectedCA: append(rootCA, append(interCA, signingCA...)...),
+ expectedTLS: append(interCA, append(signingCA, leafCert...)...),
+ },
+ {
+ name: "onlyEECert set to true",
+ config: &cfg.NCMConfig{
+ OnlyEECert: true,
+ },
+ expectedCA: rootCA,
+ expectedTLS: leafCert,
+ },
+ {
+ name: "chainInSigner & onlyEECert set to true",
+ config: &cfg.NCMConfig{
+ ChainInSigner: true,
+ OnlyEECert: true,
+ },
+ expectedCA: append(signingCA, append(interCA, rootCA...)...),
+ expectedTLS: leafCert,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestSign(t *testing.T) {
+ type testCase struct {
+ name string
+ cr *cmapi.CertificateRequest
+ p *Provisioner
+ err error
+ expectedCA []byte
+ expectedTLS []byte
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ ca, tls, _, err := tc.p.Sign(tc.cr)
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; want %s", tc.name, err.Error(), tc.err.Error())
+ }
+
+ if string(tc.expectedCA) != string(ca) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ }
+
+ if string(tc.expectedTLS) != string(tls) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
+ }
+ }
+
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-certificate",
+ }
+
+ testCases := []testCase{
+ {
+ name: "Failed to get CAs",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, ErrFailedGetCAs),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("pending", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrFailedGetCAs,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Failed to send CSR",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(errors.New("cannot established connection")),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("pending", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: errors.New("failed to send CSR"),
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Failed to check CSR status",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("", errors.New("cannot established connection"))),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: errors.New("failed checking CSR status in NCM"),
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Approved CSR status in NCM API",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("approved", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRNotAccepted,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Pending CSR status in NCM API",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("pending", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRNotAccepted,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Pending CSR status in NCM API (pending CSR check limit exceeded)",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("pending", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: SingleCSRCheckLimit + 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRCheckLimitExceeded,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Postponed CSR status in NCM API",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("postponed", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRRejected,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Rejected CSR status in NCM API",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("rejected", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRRejected,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Successfully sign certificate",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("accepted", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: nil,
+ expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
+ expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ },
+ {
+ name: "Successfully sign certificate (after requeuing)",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("accepted", nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: nil,
+ expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
+ expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+
+}
+
+func TestRenew(t *testing.T) {
+ type testCase struct {
+ name string
+ cr *cmapi.CertificateRequest
+ p *Provisioner
+ err error
+ expectedCA []byte
+ expectedTLS []byte
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ ca, tls, _, err := tc.p.Renew(&cr, "cert-id")
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; want %s", tc.name, err.Error(), tc.err.Error())
+ }
+
+ if string(tc.expectedCA) != string(ca) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ }
+
+ if string(tc.expectedTLS) != string(tls) {
+ t.Errorf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "Failed to get CAs",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, ErrFailedGetCAs),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrFailedGetCAs,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Failed to renew certificate",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientRenewCertificate(errors.New("cannot established connection"))),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: errors.New("failed to renew certificate"),
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Successfully renew certificate",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientRenewCertificate(nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: nil,
+ expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
+ expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+
+}
diff --git a/pkg/provisioner/util.go b/pkg/provisioner/util.go
index a53ada5..bb06a1c 100644
--- a/pkg/provisioner/util.go
+++ b/pkg/provisioner/util.go
@@ -25,6 +25,10 @@ func findCA(casResponse *ncmapi.CAsResponse, CAsHref, CAsName string) (*ncmapi.C
return nil, false
}
+func isRootCA(lastCheckedCA *ncmapi.CAResponse, currentCACert *ncmapi.CertificateDownloadResponse) bool {
+ return lastCheckedCA.Href == currentCACert.IssuerCA || currentCACert.IssuerCA == ""
+}
+
func addCertToChain(crt, crtChain []byte, littleEndian bool) []byte {
if littleEndian {
return append(crt, crtChain...)
diff --git a/release_notes.txt b/release_notes.txt
index c2434e6..c112abf 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -28,4 +28,13 @@ Version 1.0.3 (Build Version 1.0.2)
- Added possibility to include certificate chain in ca.crt by setting "chainInSigner" in issuer or cluster issuer
yaml file to "true"
- Added possibility to include only end-entity certificate in tls.crt by setting "onlyEECert" in issuer or cluster
- issuer yaml file to "true"
\ No newline at end of file
+ issuer yaml file to "true"
+- Bumped go from 1.17 to 1.19.6
+- Fixed bugs during certificate renewal
+
+Version 1.0.3 (Build Version 1.0.3)
+- Fixed misinterpretation when PK rotation policy is set to "Always"
+
+Version 1.0.4 (Build version 1.0.4)
+- Fixed data races when getting NCM config defined in issuer spec
+- Improved handling CSR statuses returned by NCM
\ No newline at end of file
diff --git a/test/unit/ncmapi.go b/test/unit/ncmapi.go
new file mode 100644
index 0000000..31bb460
--- /dev/null
+++ b/test/unit/ncmapi.go
@@ -0,0 +1,153 @@
+package unit
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/nokia/ncm-issuer/pkg/ncmapi"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+type FakeClient struct {
+ GetCAsFn func() (*ncmapi.CAsResponse, error)
+ GetCAFn func(path string) (*ncmapi.CAResponse, error)
+ SendCSRFn func(pem []byte, CA *ncmapi.CAResponse, profileID string) (*ncmapi.CSRResponse, error)
+ CheckCSRStatusFn func(path string) (*ncmapi.CSRStatusResponse, error)
+ DownloadCertificateFn func(path string) (*ncmapi.CertificateDownloadResponse, error)
+ DownloadCertificateInPEMFn func(path string) ([]byte, error)
+ RenewCertificateFn func(path string, duration *metav1.Duration, profileID string) (*ncmapi.RenewCertificateResponse, error)
+}
+
+var _ ncmapi.ExternalClient = &FakeClient{}
+
+func NewFakeClient(mods ...func(*FakeClient)) *FakeClient {
+ fc := &FakeClient{}
+ for _, mod := range mods {
+ mod(fc)
+ }
+ return fc
+}
+
+func SetFakeClientGetCAs(r *ncmapi.CAsResponse, err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.GetCAsFn = func() (*ncmapi.CAsResponse, error) {
+ return r, err
+ }
+ }
+}
+
+func SetFakeClientGetCA(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.GetCAFn = func(path string) (*ncmapi.CAResponse, error) {
+ crtIdentifier := func() string {
+ s := strings.Split(path, "/")
+ return s[len(s)-1]
+ }()
+
+ return &ncmapi.CAResponse{
+ Href: fmt.Sprintf("https://ncm-server.local/cas/%s", crtIdentifier),
+ Name: crtIdentifier,
+ Status: "active",
+ Certificates: map[string]string{
+ "active": fmt.Sprintf("https://ncm-servver-local/certificate/%s", crtIdentifier),
+ },
+ }, err
+ }
+ }
+}
+
+func SetFakeClientSendCSR(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.SendCSRFn = func(pem []byte, CA *ncmapi.CAResponse, profileID string) (*ncmapi.CSRResponse, error) {
+ return &ncmapi.CSRResponse{
+ Href: "https://ncm-server.local/requests/SaVye12",
+ }, err
+ }
+ }
+}
+
+func SetFakeClientCSRStatus(status string, err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.CheckCSRStatusFn = func(path string) (*ncmapi.CSRStatusResponse, error) {
+ crtIdentifier := func() string {
+ s := strings.Split(path, "/")
+ return s[len(s)-1]
+ }()
+
+ return &ncmapi.CSRStatusResponse{
+ Href: fmt.Sprintf("https://ncm-server.local/requests/%s", crtIdentifier),
+ Certificate: "https://ncm-server.local/certificates/L34FC3RT",
+ Status: status,
+ }, err
+ }
+ }
+}
+
+func SetFakeClientDownloadCertificate(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.DownloadCertificateFn = func(path string) (*ncmapi.CertificateDownloadResponse, error) {
+ crtIdentifier := func() string {
+ s := strings.Split(path, "/")
+ return s[len(s)-1]
+ }()
+
+ return &ncmapi.CertificateDownloadResponse{
+ Href: fmt.Sprintf("https://ncm-server.local/certificates/%s", crtIdentifier),
+ IssuerCA: fmt.Sprintf("https://ncm-server.local/cas/%s", crtIdentifier),
+ Status: "active",
+ }, err
+ }
+ }
+}
+
+func SetFakeClientDownloadCertificateInPEM(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.DownloadCertificateInPEMFn = func(path string) ([]byte, error) {
+ crtIdentifier := func() string {
+ s := strings.Split(path, "/")
+ return s[len(s)-1]
+ }()
+
+ return []byte(fmt.Sprintf("-----BEGIN CERTIFICATE-----\n%s...\n-----END CERTIFICATE-----\n", crtIdentifier)), err
+ }
+ }
+
+}
+
+func SetFakeClientRenewCertificate(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.RenewCertificateFn = func(path string, duration *metav1.Duration, profileID string) (*ncmapi.RenewCertificateResponse, error) {
+ return &ncmapi.RenewCertificateResponse{
+ Certificate: "https://ncm-server.local/certificates/L34FC3RT",
+ }, err
+ }
+ }
+}
+
+func (fc *FakeClient) GetCAs() (*ncmapi.CAsResponse, error) {
+ return fc.GetCAsFn()
+}
+
+func (fc *FakeClient) GetCA(path string) (*ncmapi.CAResponse, error) {
+ return fc.GetCAFn(path)
+}
+
+func (fc *FakeClient) SendCSR(pem []byte, CA *ncmapi.CAResponse, profileID string) (*ncmapi.CSRResponse, error) {
+ return fc.SendCSRFn(pem, CA, profileID)
+}
+
+func (fc *FakeClient) CheckCSRStatus(path string) (*ncmapi.CSRStatusResponse, error) {
+ return fc.CheckCSRStatusFn(path)
+}
+
+func (fc *FakeClient) DownloadCertificate(path string) (*ncmapi.CertificateDownloadResponse, error) {
+ return fc.DownloadCertificateFn(path)
+}
+
+func (fc *FakeClient) DownloadCertificateInPEM(path string) ([]byte, error) {
+ return fc.DownloadCertificateInPEMFn(path)
+}
+
+func (fc *FakeClient) RenewCertificate(path string, duration *metav1.Duration, profileID string) (*ncmapi.RenewCertificateResponse, error) {
+ return fc.RenewCertificateFn(path, duration, profileID)
+}
From 064f28ae1f0c9edfdde6fa3826772e29d147bf8a Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 16 Mar 2023 18:04:03 +0100
Subject: [PATCH 067/175] Added more unit tests for provisioner & ncmapi
---
pkg/ncmapi/ncmapi_test.go | 552 +++++++++++++++++++++++++++++++-----
pkg/provisioner/ncm_test.go | 223 ++++++++++++---
2 files changed, 656 insertions(+), 119 deletions(-)
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 541b9da..126d315 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -2,115 +2,511 @@ package ncmapi
import (
"bytes"
- testr "github.com/go-logr/logr/testing"
- "github.com/stretchr/testify/assert"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/json"
+ "errors"
"io"
"net/http"
+ "net/http/httptest"
+ "os"
+ "reflect"
+ "strings"
"testing"
+ "time"
+
+ testr "github.com/go-logr/logr/testing"
+ "github.com/nokia/ncm-issuer/pkg/cfg"
+)
+
+var (
+ rootCA = "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n"
+
+ certPEM = `-----BEGIN CERTIFICATE-----
+MIIB2zCCAYWgAwIBAgIUKkV94DTD6al8iCukf+dVMUIzSFMwDQYJKoZIhvcNAQEL
+BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
+CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMzAzMTYxNDMyNTlaFw0yNDAzMTUx
+NDMyNTlaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa
+BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwXDANBgkqhkiG9w0BAQEFAANLADBI
+AkEAwjCvS9h8ADaBz7jUayWB1Lcy6fcGeSD2u1qFmjtit4jGPjZkTNRD4qH22VLj
+mqR43Cq4V++yTaEjT4HeetRDAwIDAQABo1MwUTAdBgNVHQ4EFgQU7feJQ8nAPPHw
+KCtHx+rRAfX/LKswHwYDVR0jBBgwFoAU7feJQ8nAPPHwKCtHx+rRAfX/LKswDwYD
+VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAANBAGqea1lWcEDRr7qrDGVKItJn
+m7fvrww42l2LTJJ4nP9h6UBAmoSor0yHn7Zks/CTb9A/VTINB1sbP7n8USeOIxA=
+-----END CERTIFICATE-----`
+
+ keyPEM = `-----BEGIN PRIVATE KEY-----
+MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAwjCvS9h8ADaBz7jU
+ayWB1Lcy6fcGeSD2u1qFmjtit4jGPjZkTNRD4qH22VLjmqR43Cq4V++yTaEjT4He
+etRDAwIDAQABAkA6CBSKxPIhmihm7CRGtNm8uNa1RoYfsrMpQB8G/VI96FNXDnew
+mWwruneVpm0DnRECEx4xO+DutB+mbSZv9WGJAiEA7XmFGZ+PlY31lXSKmsPWbDUQ
+tLBzXbWQze8AceT8Yb0CIQDRVsDCHu8osESn+g4/Ak4MPuVpg4NBiqbo0DBRqDyj
+vwIgIssFJ0XrgZv0+VrD2/0Jc30q325i2L37Y1C7HfTQzXkCIQCpobTdGJgPzpYz
+z8sPf9yiy6y2zZzk1WffLCSbZsqMnQIhAKjl/vE+ekVi2Hb/yYNeqyxE24XQ1QC4
+Fcw3AnfkJ3p2
+-----END PRIVATE KEY-----`
+
+ crt1 = CAResponse{
+ Href: "https://ncm-server.local/cas/Mn012Se",
+ Name: "ncmCA",
+ Status: "active",
+ Certificates: map[string]string{
+ "active": "https://ncm-servver-local/certificate/Mn012Se",
+ },
+ }
+
+ crt2 = CAResponse{
+ Href: "https://ncm-server.local/cas/eS210nM",
+ Name: "ncmCA2",
+ Status: "active",
+ Certificates: map[string]string{
+ "active": "https://ncm-servver-local/certificate/eS210nM",
+ },
+ }
+
+ crt3 = CAResponse{
+ Href: "https://ncm-server.local/cas/efG312Ed",
+ Name: "ncmCA3",
+ Status: "expired",
+ Certificates: map[string]string{},
+ }
+
+ cas = CAsResponse{
+ TotalCount: 3,
+ Href: "https://ncm-server.local/cas",
+ CAList: []CAResponse{crt1, crt2, crt3},
+ }
)
func TestNewClientCreation(t *testing.T) {
- tests := []struct {
+ type testCase struct {
name string
- cfg *NCMConfig
+ config *cfg.NCMConfig
+ err error
expectedClient *Client
- expectedError error
- }{
+ }
+
+ CACertPool := x509.NewCertPool()
+ CACertPool.AppendCertsFromPEM([]byte(rootCA))
+
+ dir := os.TempDir()
+ defer os.RemoveAll(dir)
+
+ certFile, err := os.CreateTemp(dir, "ncm-testing-cert.pem")
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ certFile.Write([]byte(certPEM))
+
+ certKey, err := os.CreateTemp(dir, "ncm-testing-cert-key.pem")
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ certKey.Write([]byte(keyPEM))
+
+ clientCert, _ := tls.LoadX509KeyPair(certFile.Name(), certKey.Name())
+
+ run := func(t *testing.T, tc testCase) {
+ c, err := NewClient(tc.config, &testr.TestLogger{})
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+
+ if tc.expectedClient != nil && !reflect.DeepEqual(tc.expectedClient, c) {
+ t.Errorf("%s failed; created and expected client is not the same", tc.name)
+ }
+ }
+
+ testCases := []testCase{
{
- name: "invalid NCM API URL",
- cfg: &NCMConfig{
- NCMServer: "https://malformed url.com:80",
+ name: "Malformed main NCM API address",
+ config: &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local:-8081",
},
+ err: errors.New("cannot create new API client"),
expectedClient: nil,
- expectedError: &ClientError{},
},
{
- name: "invalid 2nd NCM API URL",
- cfg: &NCMConfig{
- NCMServer: "https://working-url.com:3000",
- NCMServer2: "https://malformed url.com:-17",
+ name: "Malformed backup NCM API address",
+ config: &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ NCMServer2: "https://ncm-backup-server.local:-8081",
},
+ err: errors.New("cannot create new API client"),
expectedClient: nil,
- expectedError: &ClientError{},
- },
- {
- name: "invalid key pair",
- cfg: &NCMConfig{
- NCMServer: "https://working-url.com:3000",
- NCMServer2: "https://working-url2.com:3000",
- CACert: "CACert",
- Key: "Key",
- Cert: "Cert",
- InsecureSkipVerify: false,
- MTLS: true,
+ },
+ {
+ name: "Cert & key file dont exist (mTLS connection)",
+ config: &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ CACert: rootCA,
+ Key: "ncm-certificate-key.pem",
+ Cert: "ncm-certificate.pem",
},
+ err: errors.New("no such file or directory"),
expectedClient: nil,
- expectedError: &ClientError{},
- },
- {
- name: "proper client creation",
- cfg: &NCMConfig{
- Username: "user",
- UsrPassword: "password",
- NCMServer: "https://working-url.com:3000",
- NCMServer2: "",
- CACert: "CACert",
- Key: "Key",
- Cert: "Cert",
+ },
+ {
+ name: "Successfully new client creation (insecure connection)",
+ config: &cfg.NCMConfig{
+ NCMServer: "http://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ },
+ err: nil,
+ expectedClient: &Client{
+ NCMServer: "http://ncm-server.local",
+ user: "ncm-user",
+ password: "ncm-user-password",
+ client: &http.Client{
+ Timeout: DefaultHTTPTimeout * time.Second,
+ },
+ log: &testr.TestLogger{},
+ },
+ },
+ {
+ name: "Successfully new client creation (insecure skip verify)",
+ config: &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
InsecureSkipVerify: true,
- MTLS: false,
},
- expectedClient: &Client{},
- expectedError: nil,
+ err: nil,
+ expectedClient: &Client{
+ NCMServer: "https://ncm-server.local",
+ user: "ncm-user",
+ password: "ncm-user-password",
+ client: &http.Client{
+ Timeout: DefaultHTTPTimeout * time.Second,
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ },
+ log: &testr.TestLogger{},
+ },
+ },
+ {
+ name: "Successfully new client creation (TLS connection)",
+ config: &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ CACert: rootCA,
+ },
+ err: nil,
+ expectedClient: &Client{
+ NCMServer: "https://ncm-server.local",
+ user: "ncm-user",
+ password: "ncm-user-password",
+ client: &http.Client{
+ Timeout: DefaultHTTPTimeout * time.Second,
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{
+ RootCAs: CACertPool,
+ },
+ },
+ },
+ log: &testr.TestLogger{},
+ },
+ },
+ {
+ name: "Successfully new client creation (mTLS connection)",
+ config: &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ CACert: rootCA,
+ MTLS: true,
+ Cert: certFile.Name(),
+ Key: certKey.Name(),
+ },
+ err: nil,
+ expectedClient: &Client{
+ NCMServer: "https://ncm-server.local",
+ user: "ncm-user",
+ password: "ncm-user-password",
+ client: &http.Client{
+ Timeout: DefaultHTTPTimeout * time.Second,
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{
+ RootCAs: CACertPool,
+ Certificates: []tls.Certificate{clientCert},
+ },
+ },
+ },
+ log: &testr.TestLogger{},
+ },
},
}
- for _, tt := range tests {
- log := testr.TestLogger{T: t}
- client, err := NewClient(tt.cfg, log)
- assert.IsType(t, tt.expectedClient, client, "%s failed", tt.name)
- assert.IsType(t, tt.expectedError, err, "%s failed", tt.name)
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
}
}
-func TestResponseValidation(t *testing.T) {
- tests := []struct {
- name string
- resp *http.Response
- expectedError error
- }{
+func TestValidateResponse(t *testing.T) {
+ type testCase struct {
+ name string
+ resp *http.Response
+ err error
+ expectedBody []byte
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ config := &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+
+ c, _ := NewClient(config, testr.TestLogger{})
+ body, err := c.validateResponse(tc.resp)
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+
+ if tc.expectedBody != nil && !reflect.DeepEqual(tc.expectedBody, body) {
+ t.Errorf("%s failed; received and wanted body is not the same", tc.name)
+ }
+ }
+
+ testCases := []testCase{
{
- name: "not valid response",
+ name: "Successfully validate body returned by NCM API (status 200)",
resp: &http.Response{
- StatusCode: 400,
- Body: io.NopCloser(bytes.NewReader([]byte(`{"message": "", "status": 400, "statusMessage": "Bad Request"}`))),
+ StatusCode: 200,
+ Body: io.NopCloser(bytes.NewBuffer(
+ []byte(`{"name": "ncmCA", "status": "active"}`))),
},
- expectedError: &APIError{},
+ err: nil,
+ expectedBody: []byte(`{"name": "ncmCA", "status": "active"}`),
},
{
- name: "valid response",
+ name: "Successfully validate body returned by NCM API (status not 200)",
resp: &http.Response{
- StatusCode: 200,
- Body: io.NopCloser(bytes.NewReader([]byte(`{"random": "field"}`))),
+ StatusCode: 500,
+ Body: io.NopCloser(bytes.NewBuffer(
+ []byte(`{"message": "Internal Server Error", "status": 500, "statusMessage": "Internal Server Error"}`))),
+ },
+ err: errors.New("500"),
+ expectedBody: nil,
+ },
+ {
+ name: "Unmarshalling json error",
+ resp: &http.Response{
+ StatusCode: 500,
+ Body: io.NopCloser(bytes.NewBuffer(
+ []byte(`{"message": "Internal Server Error", "status": "500", "statusMessage": "Internal Server Error"}`))),
},
- expectedError: nil,
- },
- }
-
- for _, tt := range tests {
- log := testr.TestLogger{T: t}
- client, _ := NewClient(&NCMConfig{
- Username: "user",
- UsrPassword: "password",
- NCMServer: "https://working-url.com:3000",
- NCMServer2: "",
- CACert: "CACert",
- Key: "Key",
- Cert: "Cert",
- InsecureSkipVerify: true,
- MTLS: false,
- }, log)
- _, err := client.validateResponse(tt.resp)
- assert.IsType(t, tt.expectedError, err, "%s failed", tt.name)
+ err: errors.New("cannot unmarshal json"),
+ expectedBody: nil,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestGetCAs(t *testing.T) {
+ type testCase struct {
+ name string
+ handler http.HandlerFunc
+ err error
+ expectedCAs *CAsResponse
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ svr := httptest.NewServer(tc.handler)
+ defer svr.Close()
+
+ config := &cfg.NCMConfig{
+ NCMServer: svr.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+
+ c, _ := NewClient(config, testr.TestLogger{})
+ cas, err := c.GetCAs()
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+
+ if tc.expectedCAs != nil && !reflect.DeepEqual(tc.expectedCAs, cas) {
+ t.Errorf("%s failed; got %+v; want %+v", tc.name, cas, tc.expectedCAs)
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "Successfully get CAs from NCM API",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(cas)
+ }),
+ err: nil,
+ expectedCAs: &cas,
+ },
+ {
+ name: "NCM API returned internal server error",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ apiError := APIError{
+ Message: "Internal Server Error",
+ Status: 500,
+ StatusMessage: "Internal Server Error",
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ json.NewEncoder(w).Encode(apiError)
+ }),
+ err: errors.New("500"),
+ expectedCAs: nil,
+ },
+ {
+ name: "Unmarshalling json error",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ resp := map[string]string{
+ "status": "500",
+ }
+ jsonResp, _ := json.Marshal(resp)
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write(jsonResp)
+ }),
+ err: errors.New("cannot unmarshal json"),
+ expectedCAs: nil,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestGetCA(t *testing.T) {
+ type testCase struct {
+ name string
+ handler http.HandlerFunc
+ err error
+ expectedCA *CAResponse
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ svr := httptest.NewServer(tc.handler)
+ defer svr.Close()
+
+ config := &cfg.NCMConfig{
+ NCMServer: svr.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+
+ c, _ := NewClient(config, testr.TestLogger{})
+ ca, err := c.GetCA("random-path")
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+
+ if tc.expectedCA != nil && !reflect.DeepEqual(tc.expectedCA, ca) {
+ t.Errorf("%s failed; got %+v; want %+v", tc.name, ca, tc.expectedCA)
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "Successfully get CA from NCM API",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(crt1)
+ }),
+ err: nil,
+ expectedCA: &crt1,
+ },
+ {
+ name: "NCM API returned internal server error",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ apiError := APIError{
+ Message: "Internal Server Error",
+ Status: 500,
+ StatusMessage: "Internal Server Error",
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ json.NewEncoder(w).Encode(apiError)
+ }),
+ err: errors.New("500"),
+ expectedCA: nil,
+ },
+ {
+ name: "Unmarshalling json error",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ resp := map[string]string{
+ "status": "500",
+ }
+ jsonResp, _ := json.Marshal(resp)
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write(jsonResp)
+ }),
+ err: errors.New("cannot unmarshal json"),
+ expectedCA: nil,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestSendCSR(t *testing.T) {
+ type testCase struct {
+ name string
+ }
+}
+
+func TestCheckCSRStatus(t *testing.T) {
+ type testCase struct {
+ name string
+ }
+}
+
+func TestDownloadCertificate(t *testing.T) {
+ type testCase struct {
+ name string
+ }
+}
+
+func TestDownloadCertificateInPEM(t *testing.T) {
+ type testCase struct {
+ name string
+ }
+}
+
+func TestRenewCertificate(t *testing.T) {
+ type testCase struct {
+ name string
}
}
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index a28db05..e13a75f 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -312,7 +312,7 @@ func TestSign(t *testing.T) {
ca, tls, _, err := tc.p.Sign(tc.cr)
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
- t.Errorf("%s failed; expected error containing %s; want %s", tc.name, err.Error(), tc.err.Error())
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
if string(tc.expectedCA) != string(ca) {
@@ -339,10 +339,8 @@ func TestSign(t *testing.T) {
NCMClient: unit.NewFakeClient(
unit.SetFakeClientGetCAs(CAsResponse, ErrFailedGetCAs),
unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("pending", nil)),
+ unit.SetFakeClientDownloadCertificateInPEM(nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -353,6 +351,28 @@ func TestSign(t *testing.T) {
expectedCA: []byte(""),
expectedTLS: []byte(""),
},
+ {
+ name: "Failed to find CA",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "eFgEf12",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: errors.New("has not been found"),
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
{
name: "Failed to send CSR",
cr: &cr,
@@ -365,8 +385,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientGetCA(nil),
unit.SetFakeClientSendCSR(errors.New("cannot established connection")),
unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("pending", nil)),
+ unit.SetFakeClientDownloadCertificateInPEM(nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -402,7 +421,79 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Approved CSR status in NCM API",
+ name: "Pending CSR status in NCM API",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus(CSRStatusPending, nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRNotAccepted,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Rejected CSR status in NCM API",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus(CSRStatusRejected, nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: ErrCSRRejected,
+ expectedCA: []byte(""),
+ expectedTLS: []byte(""),
+ },
+ {
+ name: "Successfully sign certificate",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus(CSRStatusAccepted, nil)),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{},
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: nil,
+ expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
+ expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ },
+ {
+ name: "Successfully sign certificate (after requeuing)",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -414,7 +505,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("approved", nil)),
+ unit.SetFakeClientCSRStatus(CSRStatusAccepted, nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -426,9 +517,67 @@ func TestSign(t *testing.T) {
},
log: &testr.TestLogger{T: t},
},
- err: ErrCSRNotAccepted,
- expectedCA: []byte(""),
- expectedTLS: []byte(""),
+ err: nil,
+ expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
+ expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+
+}
+
+func TestHandlingCSR(t *testing.T) {
+ type testCase struct {
+ name string
+ cr *cmapi.CertificateRequest
+ p *Provisioner
+ err error
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ _, _, _, err := tc.p.Sign(tc.cr)
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+ }
+
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-certificate",
+ }
+
+ testCases := []testCase{
+ {
+ name: "Failed to check CSR status",
+ cr: &cr,
+ p: &Provisioner{
+ NCMConfig: &cfg.NCMConfig{
+ CAsHref: "Mn012Se",
+ },
+ NCMClient: unit.NewFakeClient(
+ unit.SetFakeClientGetCAs(CAsResponse, nil),
+ unit.SetFakeClientGetCA(nil),
+ unit.SetFakeClientSendCSR(nil),
+ unit.SetFakeClientDownloadCertificate(nil),
+ unit.SetFakeClientDownloadCertificateInPEM(nil),
+ unit.SetFakeClientCSRStatus("", errors.New("cannot established connection"))),
+ pendingCSRs: &PendingCSRsMap{
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
+ },
+ log: &testr.TestLogger{T: t},
+ },
+ err: errors.New("failed checking CSR status in NCM"),
},
{
name: "Pending CSR status in NCM API",
@@ -443,7 +592,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("pending", nil)),
+ unit.SetFakeClientCSRStatus(CSRStatusPending, nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -455,9 +604,7 @@ func TestSign(t *testing.T) {
},
log: &testr.TestLogger{T: t},
},
- err: ErrCSRNotAccepted,
- expectedCA: []byte(""),
- expectedTLS: []byte(""),
+ err: ErrCSRNotAccepted,
},
{
name: "Pending CSR status in NCM API (pending CSR check limit exceeded)",
@@ -472,7 +619,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("pending", nil)),
+ unit.SetFakeClientCSRStatus(CSRStatusPending, nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -484,9 +631,7 @@ func TestSign(t *testing.T) {
},
log: &testr.TestLogger{T: t},
},
- err: ErrCSRCheckLimitExceeded,
- expectedCA: []byte(""),
- expectedTLS: []byte(""),
+ err: ErrCSRCheckLimitExceeded,
},
{
name: "Postponed CSR status in NCM API",
@@ -501,7 +646,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("postponed", nil)),
+ unit.SetFakeClientCSRStatus(CSRStatusPostponed, nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -513,12 +658,10 @@ func TestSign(t *testing.T) {
},
log: &testr.TestLogger{T: t},
},
- err: ErrCSRRejected,
- expectedCA: []byte(""),
- expectedTLS: []byte(""),
+ err: ErrCSRRejected,
},
{
- name: "Rejected CSR status in NCM API",
+ name: "Approved CSR status in NCM API",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -530,7 +673,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("rejected", nil)),
+ unit.SetFakeClientCSRStatus(CSRStatusApproved, nil)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -542,12 +685,10 @@ func TestSign(t *testing.T) {
},
log: &testr.TestLogger{T: t},
},
- err: ErrCSRRejected,
- expectedCA: []byte(""),
- expectedTLS: []byte(""),
+ err: ErrCSRNotAccepted,
},
{
- name: "Successfully sign certificate",
+ name: "Rejected CSR status in NCM API",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -559,19 +700,22 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("accepted", nil)),
+ unit.SetFakeClientCSRStatus(CSRStatusRejected, nil)),
pendingCSRs: &PendingCSRsMap{
- pendingCSRs: map[string]*PendingCSR{},
- mu: sync.RWMutex{},
+ pendingCSRs: map[string]*PendingCSR{
+ "ncm-ns.ncm-certificate": {
+ href: "https://ncm-server.local/requests/EufA12",
+ checked: 1,
+ },
+ },
+ mu: sync.RWMutex{},
},
log: &testr.TestLogger{T: t},
},
- err: nil,
- expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
- expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ err: ErrCSRRejected,
},
{
- name: "Successfully sign certificate (after requeuing)",
+ name: "Unexpected status in NCM API",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -583,7 +727,7 @@ func TestSign(t *testing.T) {
unit.SetFakeClientSendCSR(nil),
unit.SetFakeClientDownloadCertificate(nil),
unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("accepted", nil)),
+ unit.SetFakeClientCSRStatus("unexpected", errors.New("unexpected"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -595,9 +739,7 @@ func TestSign(t *testing.T) {
},
log: &testr.TestLogger{T: t},
},
- err: nil,
- expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
- expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
+ err: errors.New("unexpected"),
},
}
@@ -606,7 +748,6 @@ func TestSign(t *testing.T) {
run(t, tc)
})
}
-
}
func TestRenew(t *testing.T) {
From e20684472aef68bd16a956e3dc005b35f4a5c139 Mon Sep 17 00:00:00 2001
From: raczu
Date: Tue, 21 Mar 2023 20:01:24 +0100
Subject: [PATCH 068/175] Added unit tests for issuer controller
---
pkg/controllers/issuer_controller.go | 10 +-
pkg/controllers/issuer_controller_test.go | 473 ++++++++++++++--------
pkg/ncmapi/ncmapi_test.go | 64 +--
pkg/provisioner/ncm_test.go | 80 ++--
4 files changed, 384 insertions(+), 243 deletions(-)
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index f3f5bb8..9acca27 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -19,17 +19,17 @@ package controllers
import (
"context"
"fmt"
- "github.com/nokia/ncm-issuer/pkg/cfg"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- utilerrors "k8s.io/apimachinery/pkg/util/errors"
"github.com/go-logr/logr"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/cfg"
"github.com/nokia/ncm-issuer/pkg/provisioner"
core "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
+ utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/record"
"k8s.io/utils/clock"
ctrl "sigs.k8s.io/controller-runtime"
@@ -69,7 +69,7 @@ func (r *IssuerReconciler) newIssuer() (client.Object, error) {
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile
func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- log := r.Log.WithValues("ncmissuer", req.NamespacedName)
+ log := r.Log.WithValues("ncm-issuer", req.NamespacedName)
issuer, err := r.newIssuer()
if err != nil {
@@ -79,7 +79,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
if err := r.Get(ctx, req.NamespacedName, issuer); err != nil {
if err := client.IgnoreNotFound(err); err != nil {
- return ctrl.Result{}, fmt.Errorf("unexpected get error: %v", err)
+ return ctrl.Result{}, fmt.Errorf("unexpected get err: %v", err)
}
log.Info("Issuer resource not found, ignoring...")
return ctrl.Result{}, nil
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 594edce..48b85be 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -2,8 +2,15 @@ package controllers
import (
"context"
+ "errors"
+ "strings"
+ "testing"
+ "time"
+
testr "github.com/go-logr/logr/testing"
- "github.com/stretchr/testify/assert"
+ "github.com/google/go-cmp/cmp"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/provisioner"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -15,237 +22,363 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- "strings"
- "testing"
-
- nokiaAPI "github.com/nokia/ncm-issuer/api/v1"
)
const (
- ClusterIssuer = "ClusterIssuer"
Issuer = "Issuer"
+ ClusterIssuer = "ClusterIssuer"
+ Unrecognised = "Unrecognised"
)
func TestIssuerReconcile(t *testing.T) {
-
type testCase struct {
- kind string
- name types.NamespacedName
- objects []client.Object
- expectedResult ctrl.Result
- expectedErrorMsg string
+ name string
+ kind string
+ namespacedName types.NamespacedName
+ objects []client.Object
+ err error
+ expectedResult ctrl.Result
+ expectedStatus *ncmv1.IssuerStatus
+ }
+
+ scheme := runtime.NewScheme()
+ require.NoError(t, ncmv1.AddToScheme(scheme))
+ require.NoError(t, v1.AddToScheme(scheme))
+
+ clk := clock.RealClock{}
+ now := metav1.NewTime(clk.Now().Truncate(time.Second))
+
+ run := func(t *testing.T, tc testCase) {
+ fakeClient := fake.NewClientBuilder().
+ WithScheme(scheme).
+ WithObjects(tc.objects...).
+ Build()
+
+ p := provisioner.NewProvisionersMap()
+ controller := &IssuerReconciler{
+ Client: fakeClient,
+ Kind: tc.kind,
+ Scheme: scheme,
+ Clock: clock.RealClock{},
+ Recorder: record.NewFakeRecorder(10),
+ Provisioners: p,
+ Log: testr.TestLogger{T: t},
+ }
+
+ _, err := controller.Reconcile(context.TODO(), reconcile.Request{NamespacedName: tc.namespacedName})
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+
+ if tc.expectedStatus != nil && len(tc.expectedStatus.Conditions) != 0 {
+ issuer, _ := controller.newIssuer()
+ if err := fakeClient.Get(context.TODO(), tc.namespacedName, issuer); err != nil {
+ t.Fatalf("%s failed; expected to retrieve issuer err: %s", tc.name, err.Error())
+ }
+ _, issuerStatus, _ := GetSpecAndStatus(issuer)
+
+ if diff := cmp.Diff(tc.expectedStatus, issuerStatus); diff != "" {
+ t.Fatalf("%s failed; returned and expected issuer status is not the same (-want +got)\n%s", tc.name, diff)
+ }
+
+ if tc.err == nil {
+ if _, ok := controller.Provisioners.Get(tc.namespacedName); !ok {
+ t.Fatalf("%s failed; expected to find ready to use ncm provisioner", tc.name)
+ }
+ }
+ }
}
- tests := map[string]testCase{
- "successIssuer": {
- name: types.NamespacedName{Namespace: "ncm-issuer", Name: "issuer"},
- kind: Issuer,
+ testCases := []testCase{
+ {
+ name: "issuer-kind-unrecognised",
+ kind: Unrecognised,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ },
+ {
+ name: "issuer-not-found",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ },
+ {
+ name: "issuer-auth-secret-not-found",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
objects: []client.Object{
- &nokiaAPI.Issuer{
- TypeMeta: metav1.TypeMeta{
- Kind: Issuer,
- APIVersion: "v1",
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ },
+ },
+ err: errors.New("secrets \"ncm-auth-secret\" not found"),
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionFalse,
+ LastTransitionTime: &now,
+ Reason: "NotFound",
+ Message: "failed to retrieve auth secret err: secrets \"ncm-auth-secret\" not found",
},
+ },
+ },
+ },
+ {
+ name: "issuer-auth-data-not-useful",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ &ncmv1.Issuer{
ObjectMeta: metav1.ObjectMeta{
- Name: "issuer",
- Namespace: "ncm-issuer",
- }, Spec: nokiaAPI.IssuerSpec{
- NCMServer: "127.0.0.1",
- NCMServer2: "",
- CAsName: "CA1",
- CAsHREF: "kdhu84hrjl",
- LittleEndian: true,
- ReenrollmentOnRenew: true,
- UseProfileIDForRenew: true,
- NoRoot: true,
- AuthSecretName: "secretName1",
- ProfileId: "100",
- TLSSecretName: "secretName2",
- },
- Status: nokiaAPI.IssuerStatus{Conditions: []nokiaAPI.IssuerCondition{
- {Type: "",
- Status: "",
- LastTransitionTime: nil,
- },
- }},
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "secretName1",
- Namespace: "ncm-issuer",
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
},
- Data: map[string][]byte{
- "username": []byte("green_user"),
- "usrPassword": []byte("green_password"),
+ Data: map[string][]byte{},
+ },
+ },
+ err: errors.New("incorrect authentication data: missing username or usrpassword"),
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionFalse,
+ LastTransitionTime: &now,
+ Reason: "Error",
+ Message: "failed to validate config provided in spec: incorrect authentication data: missing username or usrpassword",
+ },
+ },
+ },
+ },
+ {
+ name: "issuer-tls-secret-not-found",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ TLSSecretName: "ncm-tls-secret",
},
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "secretName2",
- Namespace: "ncm-issuer",
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
},
- Data: map[string][]byte{
- "key": []byte("randomkeyhere"),
- "cert": []byte("certpemhere"),
- "cacert": []byte("cacertpemhere"),
+ Data: map[string][]byte{},
+ },
+ },
+ err: errors.New("secrets \"ncm-tls-secret\" not found"),
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionFalse,
+ LastTransitionTime: &now,
+ Reason: "NotFound",
+ Message: "failed to retrieve auth secret err: secrets \"ncm-tls-secret\" not found",
},
},
},
- expectedErrorMsg: "",
- expectedResult: ctrl.Result{},
},
- "successClusterIssuer": {
- name: types.NamespacedName{Namespace: "ncm-issuer", Name: "clsissuer"},
- kind: ClusterIssuer,
+ {
+ name: "issuer-tls-data-not-useful",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
objects: []client.Object{
- &nokiaAPI.ClusterIssuer{
- TypeMeta: metav1.TypeMeta{
- Kind: ClusterIssuer,
- APIVersion: "v1",
- },
+ &ncmv1.Issuer{
ObjectMeta: metav1.ObjectMeta{
- Name: "clsissuer",
- Namespace: "ncm-issuer",
- }, Spec: nokiaAPI.IssuerSpec{
- NCMServer: "127.0.0.1",
- NCMServer2: "",
- CAsName: "CA1",
- CAsHREF: "kdhu84hrjl",
- LittleEndian: true,
- ReenrollmentOnRenew: true,
- UseProfileIDForRenew: true,
- NoRoot: true,
- AuthSecretName: "secretName1",
- ProfileId: "100",
- TLSSecretName: "secretName2",
- AuthNamespace: "namespaceAuth",
- },
- Status: nokiaAPI.IssuerStatus{Conditions: []nokiaAPI.IssuerCondition{
- {Type: "",
- Status: "",
- LastTransitionTime: nil,
- },
- }},
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ TLSSecretName: "ncm-tls-secret",
+ },
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "secretName1",
- Namespace: "namespaceAuth",
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
},
Data: map[string][]byte{
- "username": []byte("green_user"),
- "usrPassword": []byte("green_password"),
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
},
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "secretName2",
- Namespace: "namespaceAuth",
+ Namespace: "ncm-ns",
+ Name: "ncm-tls-secret",
},
- Data: map[string][]byte{
- "key": []byte("randomkeyhere"),
- "cert": []byte("certpemhere"),
- "cacert": []byte("cacertpemhere"),
+ Data: map[string][]byte{},
+ },
+ },
+ err: errors.New("incorrect TLS data: missing cacert, key or cert in TLS secret"),
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionFalse,
+ LastTransitionTime: &now,
+ Reason: "Error",
+ Message: "failed to validate config provided in spec: incorrect TLS data: missing cacert, key or cert in TLS secret",
},
},
},
- expectedErrorMsg: "",
- expectedResult: ctrl.Result{},
},
- "missingServerIssuer": {
- name: types.NamespacedName{Namespace: "ncm-issuer", Name: "issuer"},
- kind: Issuer,
+ {
+ name: "issuer-cannot-create-new-provisioner",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
objects: []client.Object{
- &nokiaAPI.Issuer{
- TypeMeta: metav1.TypeMeta{
- Kind: Issuer,
- APIVersion: "v1",
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:-8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ err: errors.New("NCM API Client Error reason: cannot create new API client, err: parse \"https://ncm-server.local:-8081\""),
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionFalse,
+ LastTransitionTime: &now,
+ Reason: "Error",
+ Message: "failed to create new provisioner err: NCM API Client Error reason: cannot create new API client, err: parse \"https://ncm-server.local:-8081\": invalid port \":-8081\" after host",
},
+ },
+ },
+ },
+ {
+ name: "issuer-success",
+ kind: Issuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ &ncmv1.Issuer{
ObjectMeta: metav1.ObjectMeta{
- Name: "issuer",
- Namespace: "ncm-issuer",
- }, Spec: nokiaAPI.IssuerSpec{
- NCMServer: "",
- NCMServer2: "",
- CAsName: "CA1",
- CAsHREF: "kdhu84hrjl",
- LittleEndian: true,
- ReenrollmentOnRenew: true,
- UseProfileIDForRenew: true,
- NoRoot: true,
- AuthSecretName: "secretName1",
- ProfileId: "100",
- TLSSecretName: "secretName2",
- },
- Status: nokiaAPI.IssuerStatus{Conditions: []nokiaAPI.IssuerCondition{
- {Type: "",
- Status: "",
- LastTransitionTime: nil,
- },
- }},
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "secretName1",
- Namespace: "namespaceAuth",
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
},
Data: map[string][]byte{
- "username": []byte("green_user"),
- "usrPassword": []byte("green_password"),
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ LastTransitionTime: &now,
+ Reason: "Verified",
+ Message: "Signing CA verified and ready to sign certificates",
+ },
+ },
+ },
+ },
+ {
+ name: "cluster-issuer-success",
+ kind: ClusterIssuer,
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-cluster-issuer"},
+ objects: []client.Object{
+ &ncmv1.ClusterIssuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cluster-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
},
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "secretName2",
- Namespace: "namespaceAuth",
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
},
Data: map[string][]byte{
- "key": []byte("randomkeyhere"),
- "cert": []byte("certpemhere"),
- "cacert": []byte("cacertpemhere"),
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ expectedStatus: &ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ LastTransitionTime: &now,
+ Reason: "Verified",
+ Message: "Signing CA verified and ready to sign certificates",
},
},
},
- expectedErrorMsg: "incorrect setting",
- expectedResult: ctrl.Result{},
},
}
- scheme := runtime.NewScheme()
- require.NoError(t, nokiaAPI.AddToScheme(scheme))
- require.NoError(t, v1.AddToScheme(scheme))
-
- for name, testCase := range tests {
- t.Run(name, func(t *testing.T) {
- fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(testCase.objects...).Build()
- issuerController := &IssuerReconciler{
- Client: fakeClient,
- Kind: testCase.kind,
- Scheme: scheme,
- Clock: clock.RealClock{},
- Recorder: record.NewFakeRecorder(10),
- Log: testr.TestLogger{T: t}}
-
- ctx := context.TODO()
- result, err := issuerController.Reconcile(ctx, reconcile.Request{NamespacedName: testCase.name})
- if testCase.expectedErrorMsg != "" {
- if !ErrorContains(err, testCase.expectedErrorMsg) {
- t.Errorf("Unexpected error: %v", err)
- }
- } else {
- assert.NoError(t, err)
- }
- assert.Equal(t, testCase.expectedResult, result, "Unexpected result")
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
})
}
}
-
-func ErrorContains(resultErr error, wantedErrMsg string) bool {
- if resultErr == nil {
- return wantedErrMsg == ""
- }
- if wantedErrMsg == "" {
- return false
- }
- return strings.Contains(resultErr.Error(), wantedErrMsg)
-}
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 126d315..f8c5bf3 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -10,12 +10,12 @@ import (
"net/http"
"net/http/httptest"
"os"
- "reflect"
"strings"
"testing"
"time"
testr "github.com/go-logr/logr/testing"
+ "github.com/google/go-cmp/cmp"
"github.com/nokia/ncm-issuer/pkg/cfg"
)
@@ -113,14 +113,16 @@ func TestNewClientCreation(t *testing.T) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
- if tc.expectedClient != nil && !reflect.DeepEqual(tc.expectedClient, c) {
- t.Errorf("%s failed; created and expected client is not the same", tc.name)
+ if tc.expectedClient != nil {
+ if diff := cmp.Diff(tc.expectedClient, c, cmp.AllowUnexported(Client{})); diff != "" {
+ t.Fatalf("%s failed; created and expected client is not the same (-want +got)\n%s", tc.name, diff)
+ }
}
}
testCases := []testCase{
{
- name: "Malformed main NCM API address",
+ name: "malformed-main-ncm-api-url",
config: &cfg.NCMConfig{
NCMServer: "https://ncm-server.local:-8081",
},
@@ -128,7 +130,7 @@ func TestNewClientCreation(t *testing.T) {
expectedClient: nil,
},
{
- name: "Malformed backup NCM API address",
+ name: "malformed-backup-ncm-api-url",
config: &cfg.NCMConfig{
NCMServer: "https://ncm-server.local",
NCMServer2: "https://ncm-backup-server.local:-8081",
@@ -137,7 +139,7 @@ func TestNewClientCreation(t *testing.T) {
expectedClient: nil,
},
{
- name: "Cert & key file dont exist (mTLS connection)",
+ name: "cert-and-key-for-mtls-do-not-exist",
config: &cfg.NCMConfig{
NCMServer: "https://ncm-server.local",
CACert: rootCA,
@@ -148,7 +150,7 @@ func TestNewClientCreation(t *testing.T) {
expectedClient: nil,
},
{
- name: "Successfully new client creation (insecure connection)",
+ name: "ncm-client-success-insecure-connection",
config: &cfg.NCMConfig{
NCMServer: "http://ncm-server.local",
Username: "ncm-user",
@@ -166,7 +168,7 @@ func TestNewClientCreation(t *testing.T) {
},
},
{
- name: "Successfully new client creation (insecure skip verify)",
+ name: "ncm-client-success-insecure-skip-verify",
config: &cfg.NCMConfig{
NCMServer: "https://ncm-server.local",
Username: "ncm-user",
@@ -188,7 +190,7 @@ func TestNewClientCreation(t *testing.T) {
},
},
{
- name: "Successfully new client creation (TLS connection)",
+ name: "ncm-client-success-tls-connection",
config: &cfg.NCMConfig{
NCMServer: "https://ncm-server.local",
Username: "ncm-user",
@@ -212,7 +214,7 @@ func TestNewClientCreation(t *testing.T) {
},
},
{
- name: "Successfully new client creation (mTLS connection)",
+ name: "ncm-client-success-mtls-connection",
config: &cfg.NCMConfig{
NCMServer: "https://ncm-server.local",
Username: "ncm-user",
@@ -263,21 +265,23 @@ func TestValidateResponse(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{})
+ c, _ := NewClient(config, testr.TestLogger{T: t})
body, err := c.validateResponse(tc.resp)
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
- if tc.expectedBody != nil && !reflect.DeepEqual(tc.expectedBody, body) {
- t.Errorf("%s failed; received and wanted body is not the same", tc.name)
+ if tc.expectedBody != nil {
+ if diff := cmp.Diff(tc.expectedBody, body); diff != "" {
+ t.Fatalf("%s failed; received and wanted body is not the same (-want +got)\n%s", tc.name, diff)
+ }
}
}
testCases := []testCase{
{
- name: "Successfully validate body returned by NCM API (status 200)",
+ name: "response-validation-success-status-200",
resp: &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBuffer(
@@ -287,7 +291,7 @@ func TestValidateResponse(t *testing.T) {
expectedBody: []byte(`{"name": "ncmCA", "status": "active"}`),
},
{
- name: "Successfully validate body returned by NCM API (status not 200)",
+ name: "response-validation-success-for-status-not-200",
resp: &http.Response{
StatusCode: 500,
Body: io.NopCloser(bytes.NewBuffer(
@@ -297,7 +301,7 @@ func TestValidateResponse(t *testing.T) {
expectedBody: nil,
},
{
- name: "Unmarshalling json error",
+ name: "response-validation-unmarshalling-json-error",
resp: &http.Response{
StatusCode: 500,
Body: io.NopCloser(bytes.NewBuffer(
@@ -333,21 +337,23 @@ func TestGetCAs(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{})
+ c, _ := NewClient(config, testr.TestLogger{T: t})
cas, err := c.GetCAs()
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
- if tc.expectedCAs != nil && !reflect.DeepEqual(tc.expectedCAs, cas) {
- t.Errorf("%s failed; got %+v; want %+v", tc.name, cas, tc.expectedCAs)
+ if tc.expectedCAs != nil {
+ if diff := cmp.Diff(tc.expectedCAs, cas); diff != "" {
+ t.Fatalf("%s failed; received and wanted CAs are not the same (-want +got)\n%s", tc.name, diff)
+ }
}
}
testCases := []testCase{
{
- name: "Successfully get CAs from NCM API",
+ name: "get-cas-success",
handler: http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
@@ -358,7 +364,7 @@ func TestGetCAs(t *testing.T) {
expectedCAs: &cas,
},
{
- name: "NCM API returned internal server error",
+ name: "get-cas-internal-server-error",
handler: http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
apiError := APIError{
@@ -374,7 +380,7 @@ func TestGetCAs(t *testing.T) {
expectedCAs: nil,
},
{
- name: "Unmarshalling json error",
+ name: "get-cas-unmarshalling-json-error",
handler: http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
resp := map[string]string{
@@ -416,21 +422,23 @@ func TestGetCA(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{})
+ c, _ := NewClient(config, testr.TestLogger{T: t})
ca, err := c.GetCA("random-path")
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
- if tc.expectedCA != nil && !reflect.DeepEqual(tc.expectedCA, ca) {
- t.Errorf("%s failed; got %+v; want %+v", tc.name, ca, tc.expectedCA)
+ if tc.expectedCA != nil {
+ if diff := cmp.Diff(tc.expectedCA, ca); diff != "" {
+ t.Fatalf("%s failed; received and wanted CA is not the same (-want +got)\n%s", tc.name, diff)
+ }
}
}
testCases := []testCase{
{
- name: "Successfully get CA from NCM API",
+ name: "get-ca-success",
handler: http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
@@ -441,7 +449,7 @@ func TestGetCA(t *testing.T) {
expectedCA: &crt1,
},
{
- name: "NCM API returned internal server error",
+ name: "get-ca-internal-server-error",
handler: http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
apiError := APIError{
@@ -457,7 +465,7 @@ func TestGetCA(t *testing.T) {
expectedCA: nil,
},
{
- name: "Unmarshalling json error",
+ name: "get-ca-unmarshalling-json-error",
handler: http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
resp := map[string]string{
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index e13a75f..f62115c 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -76,7 +76,7 @@ func TestFindCA(t *testing.T) {
testCases := []testCase{
{
- name: "Findable by CAsName",
+ name: "cas-name-success",
CAsHref: "",
CAsName: "ncmCA2",
CAsResponse: CAsResponse,
@@ -84,7 +84,7 @@ func TestFindCA(t *testing.T) {
expectedCA: &crt2,
},
{
- name: "Findable by CAsHref",
+ name: "cas-href-success",
CAsHref: "Mn012Se",
CAsName: "",
CAsResponse: CAsResponse,
@@ -92,7 +92,7 @@ func TestFindCA(t *testing.T) {
expectedCA: &crt1,
},
{
- name: "CAsName case sensitive",
+ name: "cas-name-case-sensitive",
CAsHref: "",
CAsName: "NCMca2",
CAsResponse: CAsResponse,
@@ -100,7 +100,7 @@ func TestFindCA(t *testing.T) {
expectedCA: &ncmapi.CAResponse{},
},
{
- name: "CAsHref case sensitive",
+ name: "cas-href-case-sensitive",
CAsHref: "mN012sE",
CAsName: "",
CAsResponse: CAsResponse,
@@ -108,7 +108,7 @@ func TestFindCA(t *testing.T) {
expectedCA: &ncmapi.CAResponse{},
},
{
- name: "CA certificate findable but not active",
+ name: "found-ca-not-active",
CAsHref: "efG312Ed",
CAsName: "ncmCA3",
CAsResponse: CAsResponse,
@@ -116,7 +116,7 @@ func TestFindCA(t *testing.T) {
expectedCA: &ncmapi.CAResponse{},
},
{
- name: "Empty CAsName & CAsHref",
+ name: "empty-cas-name-and-href",
CAsHref: "",
CAsName: "",
CAsResponse: CAsResponse,
@@ -159,17 +159,17 @@ func TestGetChainAndWantedCA(t *testing.T) {
}
if string(tc.expectedCA) != string(ca) {
- t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ t.Fatalf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
}
if string(tc.expectedChain) != string(chain) {
- t.Errorf("%s failed; got %s; want %s", tc.name, string(chain), string(tc.expectedChain))
+ t.Fatalf("%s failed; got %s; want %s", tc.name, string(chain), string(tc.expectedChain))
}
}
testCases := []testCase{
{
- name: "Successfully get chain & CA",
+ name: "get-chain-and-ca-success",
fakeClient: unit.NewFakeClient(
unit.SetFakeClientGetCA(nil),
unit.SetFakeClientDownloadCertificate(nil),
@@ -179,7 +179,7 @@ func TestGetChainAndWantedCA(t *testing.T) {
expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
},
{
- name: "Failed to get chain & CA (cannot download certificate)",
+ name: "cannot-download-certificate",
fakeClient: unit.NewFakeClient(
unit.SetFakeClientGetCA(nil),
unit.SetFakeClientDownloadCertificate(errors.New("failed to download CA certificate")),
@@ -189,7 +189,7 @@ func TestGetChainAndWantedCA(t *testing.T) {
expectedCA: []byte(""),
},
{
- name: "Failed to get chain & CA (cannot download certificate in PEM)",
+ name: "cannot-download-certificate-in-pem",
fakeClient: unit.NewFakeClient(
unit.SetFakeClientGetCA(nil),
unit.SetFakeClientDownloadCertificate(nil),
@@ -242,13 +242,13 @@ func TestPreparingCAAndTLS(t *testing.T) {
testCases := []testCase{
{
- name: "All CA and TLS manipulation options set to false",
+ name: "all-manipulation-data-set-to-false",
config: &cfg.NCMConfig{},
expectedCA: rootCA,
expectedTLS: append(leafCert, append(signingCA, interCA...)...),
},
{
- name: "littleEndian set to true",
+ name: "littleendian-set-to-true",
config: &cfg.NCMConfig{
LittleEndian: true,
},
@@ -256,7 +256,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
expectedTLS: append(interCA, append(signingCA, leafCert...)...),
},
{
- name: "chainInSigner set to true",
+ name: "chaininsigner-set-to-true",
config: &cfg.NCMConfig{
ChainInSigner: true,
},
@@ -264,7 +264,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
expectedTLS: append(leafCert, append(signingCA, interCA...)...),
},
{
- name: "littleEndian & chainInSigner set to true",
+ name: "littleendian-and-chaininsigner-set-to-true",
config: &cfg.NCMConfig{
LittleEndian: true,
ChainInSigner: true,
@@ -273,7 +273,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
expectedTLS: append(interCA, append(signingCA, leafCert...)...),
},
{
- name: "onlyEECert set to true",
+ name: "onlyeecert-set-to-true",
config: &cfg.NCMConfig{
OnlyEECert: true,
},
@@ -281,7 +281,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
expectedTLS: leafCert,
},
{
- name: "chainInSigner & onlyEECert set to true",
+ name: "chaininsigner-and-onlyeecert-set-to-true",
config: &cfg.NCMConfig{
ChainInSigner: true,
OnlyEECert: true,
@@ -316,11 +316,11 @@ func TestSign(t *testing.T) {
}
if string(tc.expectedCA) != string(ca) {
- t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ t.Fatalf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
}
if string(tc.expectedTLS) != string(tls) {
- t.Errorf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
+ t.Fatalf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
}
}
@@ -330,7 +330,7 @@ func TestSign(t *testing.T) {
testCases := []testCase{
{
- name: "Failed to get CAs",
+ name: "failed-get-cas",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -352,7 +352,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Failed to find CA",
+ name: "failed-find-ca",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -374,7 +374,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Failed to send CSR",
+ name: "failed-send-csr",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -397,7 +397,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Failed to check CSR status",
+ name: "failed-check-csr-status",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -421,7 +421,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Pending CSR status in NCM API",
+ name: "csr-status-pending",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -445,7 +445,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Rejected CSR status in NCM API",
+ name: "csr-status-rejected",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -469,7 +469,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Successfully sign certificate",
+ name: "sign-success",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -493,7 +493,7 @@ func TestSign(t *testing.T) {
expectedTLS: []byte("-----BEGIN CERTIFICATE-----\nL34FC3RT...\n-----END CERTIFICATE-----\n"),
},
{
- name: "Successfully sign certificate (after requeuing)",
+ name: "sign-success-after-requeuing",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -543,7 +543,7 @@ func TestHandlingCSR(t *testing.T) {
_, _, _, err := tc.p.Sign(tc.cr)
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
- t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ t.Fatalf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
}
@@ -553,7 +553,7 @@ func TestHandlingCSR(t *testing.T) {
testCases := []testCase{
{
- name: "Failed to check CSR status",
+ name: "csr-status-cannot-be-checked",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -580,7 +580,7 @@ func TestHandlingCSR(t *testing.T) {
err: errors.New("failed checking CSR status in NCM"),
},
{
- name: "Pending CSR status in NCM API",
+ name: "csr-status-pending",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -607,7 +607,7 @@ func TestHandlingCSR(t *testing.T) {
err: ErrCSRNotAccepted,
},
{
- name: "Pending CSR status in NCM API (pending CSR check limit exceeded)",
+ name: "csr-status-pending-but-exceeded-check-limit",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -634,7 +634,7 @@ func TestHandlingCSR(t *testing.T) {
err: ErrCSRCheckLimitExceeded,
},
{
- name: "Postponed CSR status in NCM API",
+ name: "csr-status-postponed",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -661,7 +661,7 @@ func TestHandlingCSR(t *testing.T) {
err: ErrCSRRejected,
},
{
- name: "Approved CSR status in NCM API",
+ name: "csr-status-approved",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -688,7 +688,7 @@ func TestHandlingCSR(t *testing.T) {
err: ErrCSRNotAccepted,
},
{
- name: "Rejected CSR status in NCM API",
+ name: "csr-status-rejected",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -715,7 +715,7 @@ func TestHandlingCSR(t *testing.T) {
err: ErrCSRRejected,
},
{
- name: "Unexpected status in NCM API",
+ name: "csr-status-unexpected",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -768,17 +768,17 @@ func TestRenew(t *testing.T) {
}
if string(tc.expectedCA) != string(ca) {
- t.Errorf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
+ t.Fatalf("%s failed; got %s; want %s", tc.name, string(ca), string(tc.expectedCA))
}
if string(tc.expectedTLS) != string(tls) {
- t.Errorf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
+ t.Fatalf("%s failed; got %s; want %s", tc.name, string(tls), string(tc.expectedTLS))
}
}
testCases := []testCase{
{
- name: "Failed to get CAs",
+ name: "failed-get-cas",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -801,7 +801,7 @@ func TestRenew(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Failed to renew certificate",
+ name: "failed-renew-certificate",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
@@ -825,7 +825,7 @@ func TestRenew(t *testing.T) {
expectedTLS: []byte(""),
},
{
- name: "Successfully renew certificate",
+ name: "renew-success",
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
From e6103e43c50ba708ce72ca1e43b277675d584a7f Mon Sep 17 00:00:00 2001
From: raczu
Date: Tue, 21 Mar 2023 22:53:45 +0100
Subject: [PATCH 069/175] Updated unit tests workflow
---
.github/workflows/unit-tests.yml | 42 ++++++++++++++++++++++++++++++++
.github/workflows/unit_test.yml | 24 ------------------
2 files changed, 42 insertions(+), 24 deletions(-)
create mode 100644 .github/workflows/unit-tests.yml
delete mode 100644 .github/workflows/unit_test.yml
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
new file mode 100644
index 0000000..bda43ff
--- /dev/null
+++ b/.github/workflows/unit-tests.yml
@@ -0,0 +1,42 @@
+name: Unit tests using different Go version
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go-version: ['1.16', '1.16.15', '1.17', '1.17.8', '1.18.9', '1.19.6']
+ steps:
+ - name: Checkout git
+ uses: actions/checkout@v3
+
+ - name: Setup Go ${{ matrix.go-version }}
+ uses: actions/setup-go@v3
+ with:
+ go-version: ${{ matrix.go-version }}
+
+ - name: Install dependencies
+ run: go get .
+
+ - name: Test with Go ${{ matrix.go-version }}
+ run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
+
+ - name: [ * ] Collecting unit test results
+ if: ${{ failure() }}
+ run: |
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp *.json ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -czf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
+
+ - name: [ * ] Uploading artifacts
+ uses: actions/upload-artifact@v3
+ if: ${{ failure() }}
+ with:
+ name: unit-test-results-${{ matrix.go-version }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
deleted file mode 100644
index 03fb8bc..0000000
--- a/.github/workflows/unit_test.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Tests
-
-on:
- push:
- branches: [ main ]
- pull_request:
- branches: [ main ]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
-
- - name: Set up Go
- uses: actions/setup-go@v2
- with:
- go-version: 1.17
-
- - name: Build
- run: go build -v ./...
-
- - name: Test
- run: go test -v ./...
From 39454ba298dc0d20b231e9e123258bd78052d79a Mon Sep 17 00:00:00 2001
From: raczu
Date: Tue, 21 Mar 2023 23:02:32 +0100
Subject: [PATCH 070/175] Fixed broken sytnax
---
.github/workflows/unit-tests.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index bda43ff..2427884 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -16,7 +16,7 @@ jobs:
- name: Checkout git
uses: actions/checkout@v3
- - name: Setup Go ${{ matrix.go-version }}
+ - name: Setup Go {{ matrix.go-version }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
@@ -24,17 +24,17 @@ jobs:
- name: Install dependencies
run: go get .
- - name: Test with Go ${{ matrix.go-version }}
+ - name: Test with Go {{ matrix.go-version }}
run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
- - name: [ * ] Collecting unit test results
+ - name: "[ * ] Collecting unit test results"
if: ${{ failure() }}
run: |
mkdir -p ${{ github.workspace }}/artifact/upload
sudo cp -rp *.json ${{ github.workspace }}/artifact/data/
sudo tar -C ${{ github.workspace }}/artifact/ -czf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
- - name: [ * ] Uploading artifacts
+ - name: "[ * ] Uploading artifacts"
uses: actions/upload-artifact@v3
if: ${{ failure() }}
with:
From 34114cf5eb931b52e19e822e0e1e609076e990b7 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 25 Mar 2023 21:15:27 +0100
Subject: [PATCH 071/175] Made few changes in previous tests & added tests for
CR reconcile
---
.github/workflows/unit-tests.yml | 10 +-
go.mod | 2 +-
go.sum | 5 +-
.../certificaterequest_controller.go | 26 +-
.../certificaterequest_controller_test.go | 2043 +++++++++++++++++
pkg/controllers/issuer_controller_test.go | 15 +-
pkg/ncmapi/{external.go => client.go} | 0
pkg/ncmapi/ncmapi.go | 2 -
pkg/ncmapi/ncmapi_test.go | 73 +-
pkg/provisioner/ncm.go | 18 +-
pkg/provisioner/ncm_test.go | 214 +-
pkg/provisioner/provisioner.go | 10 +
test/unit/ncm.go | 58 +
test/unit/ncmapi.go | 106 +-
14 files changed, 2399 insertions(+), 183 deletions(-)
create mode 100644 pkg/controllers/certificaterequest_controller_test.go
rename pkg/ncmapi/{external.go => client.go} (100%)
create mode 100644 pkg/provisioner/provisioner.go
create mode 100644 test/unit/ncm.go
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index 2427884..60f66a9 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -1,4 +1,4 @@
-name: Unit tests using different Go version
+name: unit tests using different go version
on:
push:
@@ -13,18 +13,18 @@ jobs:
matrix:
go-version: ['1.16', '1.16.15', '1.17', '1.17.8', '1.18.9', '1.19.6']
steps:
- - name: Checkout git
+ - name: "Checkout git"
uses: actions/checkout@v3
- - name: Setup Go {{ matrix.go-version }}
+ - name: "Setup Go"
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- - name: Install dependencies
+ - name: "Install dependencies"
run: go get .
- - name: Test with Go {{ matrix.go-version }}
+ - name: "Test with Go"
run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
- name: "[ * ] Collecting unit test results"
diff --git a/go.mod b/go.mod
index c6a6447..3068da0 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.19
require (
github.com/go-logr/logr v0.4.0
+ github.com/google/go-cmp v0.5.9
github.com/jetstack/cert-manager v1.6.3
github.com/stretchr/testify v1.7.0
k8s.io/api v0.22.2
@@ -23,7 +24,6 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
- github.com/google/go-cmp v0.5.6 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
diff --git a/go.sum b/go.sum
index 365a35d..48cd076 100644
--- a/go.sum
+++ b/go.sum
@@ -194,8 +194,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
@@ -678,7 +678,6 @@ golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 99837c3..3266772 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -78,7 +78,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if apierrors.IsNotFound(err) {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
-
return ctrl.Result{}, err
}
@@ -100,6 +99,12 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if apiutil.CertificateRequestIsDenied(cr) {
log.V(4).Info("CertificateRequest has been denied")
+ if cr.Status.FailureTime == nil {
+ nowTime := metav1.NewTime(r.Clock.Now())
+ cr.Status.FailureTime = &nowTime
+ }
+
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CertificateRequest has been denied")
return ctrl.Result{}, nil
}
@@ -123,6 +128,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerRO, err := r.Scheme.New(issuerGVK)
if err != nil {
log.Error(err, "Unrecognised kind. Ignoring.")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "unrecognised kind err: %v", err)
return ctrl.Result{}, nil
}
@@ -135,7 +141,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerName.Namespace = req.Namespace
}
- if err := r.Client.Get(ctx, issuerName, issuer); err != nil {
+ if err = r.Client.Get(ctx, issuerName, issuer); err != nil {
log.Error(err, "Failed to get issuer")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "issuer is not existing yet")
return ctrl.Result{}, errFailedGetIssuer
@@ -169,7 +175,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
crt := &cmapi.Certificate{}
- if err := r.Client.Get(ctx, client.ObjectKey{
+ if err = r.Client.Get(ctx, client.ObjectKey{
Namespace: req.Namespace, Name: cr.Annotations[cmapi.CertificateNameKey]}, crt); err != nil {
log.Error(err, "Certificate object not found")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "certificate object not found")
@@ -182,11 +188,13 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// whether the operation of certificate renewal should take place
isRevision := crt.Status.Revision != nil && *crt.Status.Revision >= 1
isPKRotationAlways := crt.Spec.PrivateKey != nil && crt.Spec.PrivateKey.RotationPolicy == "Always"
- isRenewal := isRevision && !p.NCMConfig.ReenrollmentOnRenew && !isPKRotationAlways
+ // TODO: Provisioner is no longer an individual struct, but implements interface, thus configuration option "ReenrollmentOnRenew" should be handled somehow
+ // isRenewal := isRevision && !p.NCMConfig.ReenrollmentOnRenew && !isPKRotationAlways
+ isRenewal := isRevision && !isPKRotationAlways
isSecretWithCertID := false
secretCertID := &core.Secret{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
+ if err = r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
if apierrors.IsNotFound(err) {
// This means that secret needed for renewal operations does not exist,
// and we should perform re-enrollment operation instead
@@ -204,7 +212,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// We also need to check if the certificate's TLS secret has been deleted,
// which involves triggering a manual rotation of a private key
if isRenewal {
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: crt.Spec.SecretName}, &core.Secret{}); err != nil {
+ if err = r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: crt.Spec.SecretName}, &core.Secret{}); err != nil {
if apierrors.IsNotFound(err) {
isRenewal = false
} else {
@@ -228,7 +236,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
- if err := r.Client.Update(ctx, secretCertID); err != nil {
+ if err = r.Client.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to update secret err: %v", err)
return ctrl.Result{}, err
}
@@ -263,12 +271,12 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
if isSecretWithCertID {
- if err := r.Client.Update(ctx, secretCertID); err != nil {
+ if err = r.Client.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to update secret err: %v", err)
return ctrl.Result{}, err
}
} else {
- if err := r.Client.Create(ctx, secretCertID); err != nil {
+ if err = r.Client.Create(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to create secret err: %v", err)
return ctrl.Result{}, err
}
diff --git a/pkg/controllers/certificaterequest_controller_test.go b/pkg/controllers/certificaterequest_controller_test.go
new file mode 100644
index 0000000..6a6cfe1
--- /dev/null
+++ b/pkg/controllers/certificaterequest_controller_test.go
@@ -0,0 +1,2043 @@
+package controllers
+
+import (
+ "context"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/pem"
+ "errors"
+ "strings"
+ "testing"
+
+ testr "github.com/go-logr/logr/testing"
+ "github.com/google/go-cmp/cmp"
+ apiutil "github.com/jetstack/cert-manager/pkg/api/util"
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+ cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/provisioner"
+ "github.com/nokia/ncm-issuer/test/unit"
+ "github.com/stretchr/testify/require"
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/client-go/tools/record"
+ "k8s.io/utils/clock"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+)
+
+func TestCertificateRequestReconcile(t *testing.T) {
+ type testCase struct {
+ name string
+ namespacedName types.NamespacedName
+ issuerName types.NamespacedName
+ provisioner *unit.FakeProvisioner
+ objects []client.Object
+ err error
+ expectedResult ctrl.Result
+ expectedConditionStatus cmmeta.ConditionStatus
+ expectedConditionReason string
+ }
+
+ scheme := runtime.NewScheme()
+ require.NoError(t, ncmv1.AddToScheme(scheme))
+ require.NoError(t, cmapi.AddToScheme(scheme))
+ require.NoError(t, v1.AddToScheme(scheme))
+
+ clk := clock.RealClock{}
+
+ injectProvisioner := func(name types.NamespacedName, p *unit.FakeProvisioner) *provisioner.ProvisionersMap {
+ pm := provisioner.NewProvisionersMap()
+ pm.AddOrReplace(name, p)
+ return pm
+ }
+
+ generateCSR := func() []byte {
+ keyBytes, _ := rsa.GenerateKey(rand.Reader, 2048)
+
+ subj := pkix.Name{
+ CommonName: "ncm-cert.local",
+ Country: []string{"PL"},
+ Organization: []string{"Nokia"},
+ }
+
+ template := &x509.CertificateRequest{
+ Subject: subj,
+ SignatureAlgorithm: x509.SHA256WithRSA,
+ }
+ csrBytes, _ := x509.CreateCertificateRequest(rand.Reader, template, keyBytes)
+ return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes})
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ fakeClient := fake.NewClientBuilder().
+ WithScheme(scheme).
+ WithObjects(tc.objects...).
+ Build()
+
+ controller := &CertificateRequestReconciler{
+ Client: fakeClient,
+ Scheme: scheme,
+ Clock: clk,
+ Recorder: record.NewFakeRecorder(10),
+ Provisioners: injectProvisioner(tc.issuerName, tc.provisioner),
+ Log: testr.TestLogger{T: t},
+ }
+
+ result, err := controller.Reconcile(context.TODO(), reconcile.Request{NamespacedName: tc.namespacedName})
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+
+ if diff := cmp.Diff(tc.expectedResult, result); diff != "" {
+ t.Errorf("%s failed; returned and expected result is not the same (-want +got)\n%s", tc.name, diff)
+ }
+
+ cr := &cmapi.CertificateRequest{}
+ err = fakeClient.Get(context.TODO(), tc.namespacedName, cr)
+ require.NoError(t, client.IgnoreNotFound(err), "unexpected error from fake client")
+ if err == nil {
+ condition := apiutil.GetCertificateRequestCondition(cr, cmapi.CertificateRequestConditionReady)
+ if tc.expectedConditionStatus != "" && condition != nil && tc.expectedConditionStatus != condition.Status {
+ t.Errorf("%s failed; returned and expected cr status is not the same; want %s; got %s", tc.name, tc.expectedConditionStatus, condition.Status)
+ }
+
+ if tc.expectedConditionReason != "" && condition != nil && tc.expectedConditionReason != condition.Reason {
+ t.Errorf("%s failed; returned and expected cr reason is not the same; want %s; got %s", tc.name, tc.expectedConditionReason, condition.Reason)
+ }
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "certificate-request-not-found",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ },
+ {
+ name: "issuer-ref-foreign-group",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Group: "foreign-issuer.ncm.nokia.com",
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "certificate-request-marked-as-failed",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionFalse,
+ Reason: cmapi.CertificateRequestReasonFailed,
+ },
+ },
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(),
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ },
+ {
+ name: "certificate-request-denied",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionDenied,
+ Status: cmmeta.ConditionTrue,
+ },
+ },
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(),
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonDenied,
+ },
+ {
+ name: "certificate-request-not-approved",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ },
+ {
+ name: "existing-certificate-found-in-data",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ Certificate: []byte("existing-data"),
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ },
+ {
+ name: "cr-with-issues",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ },
+ err: errors.New("certificate request has issues"),
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ },
+ {
+ name: "issuer-ref-unknown-kind",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Unrecognised,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ },
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ },
+ {
+ name: "issuer-not-found",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ },
+ err: errFailedGetIssuer,
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "cluster-issuer-not-found",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: ClusterIssuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ },
+ err: errFailedGetIssuer,
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "issuer-not-ready",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionFalse,
+ },
+ },
+ },
+ },
+ },
+ err: errIssuerNotReady,
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "provisioner-resource-missing",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ err: errFailedGetProvisioner,
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "certificate-object-not-found",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ },
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(),
+ err: errors.New("certificate object not found"),
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ },
+ {
+ name: "failed-get-cas-during-signing",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSignError(provisioner.ErrFailedGetCAs)),
+ err: provisioner.ErrFailedGetCAs,
+ expectedResult: ctrl.Result{
+ RequeueAfter: GetCAsRequeueTime,
+ },
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "csr-status-approved",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSignError(provisioner.ErrCSRNotAccepted)),
+ err: provisioner.ErrCSRNotAccepted,
+ expectedResult: ctrl.Result{
+ RequeueAfter: CSRRequeueTime,
+ },
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "csr-status-rejected",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSignError(provisioner.ErrCSRRejected)),
+ err: provisioner.ErrCSRRejected,
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ },
+ {
+ name: "exceeded-single-csr-check-limit",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSignError(provisioner.ErrCSRCheckLimitExceeded)),
+ err: provisioner.ErrCSRCheckLimitExceeded,
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ },
+ {
+ name: "csr-unexpected-error",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSignError(errors.New("unexpected"))),
+ err: errors.New("unexpected"),
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "issuer-success-sign",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ expectedConditionStatus: cmmeta.ConditionTrue,
+ expectedConditionReason: cmapi.CertificateRequestReasonIssued,
+ },
+ {
+ name: "issuer-success-sign-not-existing-secret",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ expectedConditionStatus: cmmeta.ConditionTrue,
+ expectedConditionReason: cmapi.CertificateRequestReasonIssued,
+ },
+ {
+ name: "issuer-success-sign-manual-rotation",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ expectedConditionStatus: cmmeta.ConditionTrue,
+ expectedConditionReason: cmapi.CertificateRequestReasonIssued,
+ },
+ {
+ name: "cluster-issuer-success-sign",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "", Name: "ncm-cluster-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-cluster-issuer",
+ Kind: ClusterIssuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.ClusterIssuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "",
+ Name: "ncm-cluster-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: metav1.NamespaceDefault,
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: metav1.NamespaceDefault,
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: ClusterIssuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ PrivateKey: &cmapi.CertificatePrivateKey{
+ RotationPolicy: "Always",
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ expectedConditionStatus: cmmeta.ConditionTrue,
+ expectedConditionReason: cmapi.CertificateRequestReasonIssued,
+ },
+ {
+ name: "failed-get-cas-during-renewal",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerRenewError(provisioner.ErrFailedGetCAs)),
+ err: provisioner.ErrFailedGetCAs,
+ expectedResult: ctrl.Result{
+ RequeueAfter: GetCAsRequeueTime,
+ },
+ expectedConditionStatus: cmmeta.ConditionFalse,
+ expectedConditionReason: cmapi.CertificateRequestReasonPending,
+ },
+ {
+ name: "issuer-success-renew",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.Issuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: "ncm-ns",
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: Issuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerRenew([]byte("ca"), []byte("tls"), "random-id")),
+ expectedConditionStatus: cmmeta.ConditionTrue,
+ expectedConditionReason: cmapi.CertificateRequestReasonIssued,
+ },
+ {
+ name: "cluster-issuer-success-renew",
+ namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
+ issuerName: types.NamespacedName{Namespace: "", Name: "ncm-cluster-issuer"},
+ objects: []client.Object{
+ func() *cmapi.CertificateRequest {
+ cr := &cmapi.CertificateRequest{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "cr",
+ },
+ Spec: cmapi.CertificateRequestSpec{
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-cluster-issuer",
+ Kind: ClusterIssuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ Request: generateCSR(),
+ },
+ Status: cmapi.CertificateRequestStatus{
+ Conditions: []cmapi.CertificateRequestCondition{
+ {
+ Type: cmapi.CertificateRequestConditionApproved,
+ Status: cmmeta.ConditionTrue,
+ },
+ {
+ Type: cmapi.CertificateRequestConditionReady,
+ Status: cmmeta.ConditionUnknown,
+ },
+ },
+ },
+ }
+ cr.Annotations = map[string]string{
+ cmapi.CertificateNameKey: "ncm-cert",
+ }
+ return cr
+ }(),
+ &ncmv1.ClusterIssuer{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "",
+ Name: "ncm-cluster-issuer",
+ },
+ Spec: ncmv1.IssuerSpec{
+ NCMServer: "https://ncm-server.local:8081",
+ CAsName: "ncmCA",
+ AuthNamespace: metav1.NamespaceDefault,
+ AuthSecretName: "ncm-auth-secret",
+ },
+ Status: ncmv1.IssuerStatus{
+ Conditions: []ncmv1.IssuerCondition{
+ {
+ Type: ncmv1.IssuerConditionReady,
+ Status: ncmv1.ConditionTrue,
+ },
+ },
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: metav1.NamespaceDefault,
+ Name: "ncm-auth-secret",
+ },
+ Data: map[string][]byte{
+ "username": []byte("ncm-user"),
+ "usrPassword": []byte("ncm-user-password"),
+ },
+ },
+ &cmapi.Certificate{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert",
+ },
+ Spec: cmapi.CertificateSpec{
+ CommonName: "ncm-cert.local",
+ IssuerRef: cmmeta.ObjectReference{
+ Name: "ncm-issuer",
+ Kind: ClusterIssuer,
+ Group: ncmv1.GroupVersion.Group,
+ },
+ SecretName: "ncm-cert-tls",
+ },
+ Status: cmapi.CertificateStatus{
+ Revision: func() *int {
+ value := 1
+ return &value
+ }(),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-tls",
+ },
+ Data: map[string][]byte{
+ "tls": []byte("random-bytes"),
+ },
+ },
+ &v1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ncm-ns",
+ Name: "ncm-cert-details",
+ },
+ Data: map[string][]byte{
+ "cert-id": []byte("random-id"),
+ },
+ },
+ },
+ provisioner: unit.NewFakeProvisioner(
+ unit.SetFakeProvisionerRenew([]byte("ca"), []byte("tls"), "random-id")),
+ expectedConditionStatus: cmmeta.ConditionTrue,
+ expectedConditionReason: cmapi.CertificateRequestReasonIssued,
+ },
+ }
+
+ for _, tc := range testCases {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 48b85be..2122115 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -59,7 +59,7 @@ func TestIssuerReconcile(t *testing.T) {
Client: fakeClient,
Kind: tc.kind,
Scheme: scheme,
- Clock: clock.RealClock{},
+ Clock: clk,
Recorder: record.NewFakeRecorder(10),
Provisioners: p,
Log: testr.TestLogger{T: t},
@@ -74,12 +74,12 @@ func TestIssuerReconcile(t *testing.T) {
if tc.expectedStatus != nil && len(tc.expectedStatus.Conditions) != 0 {
issuer, _ := controller.newIssuer()
if err := fakeClient.Get(context.TODO(), tc.namespacedName, issuer); err != nil {
- t.Fatalf("%s failed; expected to retrieve issuer err: %s", tc.name, err.Error())
+ t.Errorf("%s failed; expected to retrieve issuer err: %s", tc.name, err.Error())
}
_, issuerStatus, _ := GetSpecAndStatus(issuer)
if diff := cmp.Diff(tc.expectedStatus, issuerStatus); diff != "" {
- t.Fatalf("%s failed; returned and expected issuer status is not the same (-want +got)\n%s", tc.name, diff)
+ t.Errorf("%s failed; returned and expected issuer status is not the same (-want +got)\n%s", tc.name, diff)
}
if tc.err == nil {
@@ -337,23 +337,23 @@ func TestIssuerReconcile(t *testing.T) {
{
name: "cluster-issuer-success",
kind: ClusterIssuer,
- namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-cluster-issuer"},
+ namespacedName: types.NamespacedName{Namespace: v1.NamespaceDefault, Name: "ncm-cluster-issuer"},
objects: []client.Object{
&ncmv1.ClusterIssuer{
ObjectMeta: metav1.ObjectMeta{
- Namespace: "ncm-ns",
+ Namespace: v1.NamespaceDefault,
Name: "ncm-cluster-issuer",
},
Spec: ncmv1.IssuerSpec{
NCMServer: "https://ncm-server.local:8081",
CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
+ AuthNamespace: v1.NamespaceDefault,
AuthSecretName: "ncm-auth-secret",
},
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Namespace: "ncm-ns",
+ Namespace: v1.NamespaceDefault,
Name: "ncm-auth-secret",
},
Data: map[string][]byte{
@@ -377,6 +377,7 @@ func TestIssuerReconcile(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
diff --git a/pkg/ncmapi/external.go b/pkg/ncmapi/client.go
similarity index 100%
rename from pkg/ncmapi/external.go
rename to pkg/ncmapi/client.go
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 0b2dd87..1d8a9c8 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -57,8 +57,6 @@ type Client struct {
log logr.Logger
}
-var _ ExternalClient = &Client{}
-
type ClientError struct {
Reason string
ErrorMessage error
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index f8c5bf3..3282bc6 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -9,7 +9,9 @@ import (
"io"
"net/http"
"net/http/httptest"
+ "net/url"
"os"
+ "reflect"
"strings"
"testing"
"time"
@@ -113,10 +115,8 @@ func TestNewClientCreation(t *testing.T) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
- if tc.expectedClient != nil {
- if diff := cmp.Diff(tc.expectedClient, c, cmp.AllowUnexported(Client{})); diff != "" {
- t.Fatalf("%s failed; created and expected client is not the same (-want +got)\n%s", tc.name, diff)
- }
+ if tc.expectedClient != nil && !reflect.DeepEqual(tc.expectedClient, c) {
+ t.Fatalf("%s failed; created and expected client is not the same", tc.name)
}
}
@@ -250,6 +250,54 @@ func TestNewClientCreation(t *testing.T) {
}
}
+func TestNewRequestCreation(t *testing.T) {
+ type testCase struct {
+ name string
+ method string
+ err error
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ config := &cfg.NCMConfig{
+ NCMServer: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+
+ c, _ := NewClient(config, testr.TestLogger{T: t})
+ params := url.Values{}
+ _, err := c.newRequest(tc.method, "random-path", strings.NewReader(params.Encode()))
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "new-request-invalid-method",
+ method: "Konstantynopolitańczykówna",
+ err: errors.New("invalid method"),
+ },
+ {
+ name: "new-request-success",
+ method: http.MethodGet,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+type failReader int
+
+func (failReader) Read([]byte) (int, error) {
+ return 0, errors.New("unable to read from body unexpected EOF")
+}
+
func TestValidateResponse(t *testing.T) {
type testCase struct {
name string
@@ -287,7 +335,6 @@ func TestValidateResponse(t *testing.T) {
Body: io.NopCloser(bytes.NewBuffer(
[]byte(`{"name": "ncmCA", "status": "active"}`))),
},
- err: nil,
expectedBody: []byte(`{"name": "ncmCA", "status": "active"}`),
},
{
@@ -297,18 +344,24 @@ func TestValidateResponse(t *testing.T) {
Body: io.NopCloser(bytes.NewBuffer(
[]byte(`{"message": "Internal Server Error", "status": 500, "statusMessage": "Internal Server Error"}`))),
},
- err: errors.New("500"),
- expectedBody: nil,
+ err: errors.New("500"),
},
{
- name: "response-validation-unmarshalling-json-error",
+ name: "unmarshalling-json-error",
resp: &http.Response{
StatusCode: 500,
Body: io.NopCloser(bytes.NewBuffer(
[]byte(`{"message": "Internal Server Error", "status": "500", "statusMessage": "Internal Server Error"}`))),
},
- err: errors.New("cannot unmarshal json"),
- expectedBody: nil,
+ err: errors.New("cannot unmarshal json"),
+ },
+ {
+ name: "read-response-body-error",
+ resp: &http.Response{
+ StatusCode: 500,
+ Body: io.NopCloser(failReader(0)),
+ },
+ err: errors.New("cannot read response body"),
},
}
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
index f75c49b..fc94aee 100644
--- a/pkg/provisioner/ncm.go
+++ b/pkg/provisioner/ncm.go
@@ -35,36 +35,36 @@ var (
// ProvisionersMap stores prepared (NCM API Client is configured) and ready to
// use provisioner.
type ProvisionersMap struct {
- provisioners map[types.NamespacedName]*Provisioner
+ Provisioners map[types.NamespacedName]ExternalProvisioner
mu sync.RWMutex
}
func NewProvisionersMap() *ProvisionersMap {
return &ProvisionersMap{
- provisioners: map[types.NamespacedName]*Provisioner{},
+ Provisioners: map[types.NamespacedName]ExternalProvisioner{},
mu: sync.RWMutex{},
}
}
-func (pm *ProvisionersMap) Get(NamespacedName types.NamespacedName) (*Provisioner, bool) {
+func (pm *ProvisionersMap) Get(NamespacedName types.NamespacedName) (ExternalProvisioner, bool) {
pm.mu.RLock()
defer pm.mu.RUnlock()
- p, ok := pm.provisioners[NamespacedName]
+ p, ok := pm.Provisioners[NamespacedName]
return p, ok
}
-func (pm *ProvisionersMap) AddOrReplace(NamespacedName types.NamespacedName, provisioner *Provisioner) {
+func (pm *ProvisionersMap) AddOrReplace(NamespacedName types.NamespacedName, provisioner ExternalProvisioner) {
pm.mu.Lock()
defer pm.mu.Unlock()
- if _, ok := pm.provisioners[NamespacedName]; !ok {
- pm.provisioners[NamespacedName] = provisioner
+ if _, ok := pm.Provisioners[NamespacedName]; !ok {
+ pm.Provisioners[NamespacedName] = provisioner
} else {
// The existing provisioner has been found, but IssuerReconcile
// was triggered again, which may involve a change in configuration.
- delete(pm.provisioners, NamespacedName)
- pm.provisioners[NamespacedName] = provisioner
+ delete(pm.Provisioners, NamespacedName)
+ pm.Provisioners[NamespacedName] = provisioner
}
}
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index f62115c..9dc75dd 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -171,9 +171,9 @@ func TestGetChainAndWantedCA(t *testing.T) {
{
name: "get-chain-and-ca-success",
fakeClient: unit.NewFakeClient(
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM()),
err: nil,
expectedChain: []byte(""),
expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
@@ -181,9 +181,8 @@ func TestGetChainAndWantedCA(t *testing.T) {
{
name: "cannot-download-certificate",
fakeClient: unit.NewFakeClient(
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientDownloadCertificate(errors.New("failed to download CA certificate")),
- unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ unit.NoErrorFakeClientGetCA(),
+ unit.SetFakeClientDownloadCertificateError(errors.New("failed to download CA certificate"))),
err: errors.New("failed to download CA certificate"),
expectedChain: []byte(""),
expectedCA: []byte(""),
@@ -191,9 +190,9 @@ func TestGetChainAndWantedCA(t *testing.T) {
{
name: "cannot-download-certificate-in-pem",
fakeClient: unit.NewFakeClient(
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(errors.New("failed to download CA certificate in PEM")),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.SetFakeClientDownloadCertificateInPEMError(errors.New("failed to download CA certificate in PEM")),
),
err: errors.New("failed to download CA certificate in PEM"),
expectedChain: []byte(""),
@@ -337,10 +336,7 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, ErrFailedGetCAs),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ unit.SetFakeClientGetCAsError(ErrFailedGetCAs)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -359,10 +355,10 @@ func TestSign(t *testing.T) {
CAsHref: "eFgEf12",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM()),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -381,11 +377,11 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(errors.New("cannot established connection")),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.SetFakeClientSendCSRError(errors.New("cannot established connection")),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM()),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -404,12 +400,12 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("", errors.New("cannot established connection"))),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatusError(errors.New("cannot established connection"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -428,12 +424,12 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusPending, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusPending)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -452,12 +448,12 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusRejected, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusRejected)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -476,12 +472,12 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusAccepted, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusAccepted)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -500,12 +496,12 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusAccepted, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusAccepted)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -560,12 +556,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("", errors.New("cannot established connection"))),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatusError(errors.New("cannot established connection"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -587,12 +583,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusPending, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusPending)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -614,12 +610,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusPending, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusPending)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -641,12 +637,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusPostponed, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusPostponed)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -668,12 +664,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusApproved, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusApproved)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -695,12 +691,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus(CSRStatusRejected, nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus(CSRStatusRejected)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -722,12 +718,12 @@ func TestHandlingCSR(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientCSRStatus("unexpected", errors.New("unexpected"))),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientCSRStatus("unexpected")),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -785,11 +781,7 @@ func TestRenew(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, ErrFailedGetCAs),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil)),
+ unit.SetFakeClientGetCAsError(ErrFailedGetCAs)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -808,12 +800,12 @@ func TestRenew(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientRenewCertificate(errors.New("cannot established connection"))),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientRenewCertificateError(errors.New("cannot established connection"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
@@ -832,12 +824,12 @@ func TestRenew(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse, nil),
- unit.SetFakeClientGetCA(nil),
- unit.SetFakeClientSendCSR(nil),
- unit.SetFakeClientDownloadCertificate(nil),
- unit.SetFakeClientDownloadCertificateInPEM(nil),
- unit.SetFakeClientRenewCertificate(nil)),
+ unit.SetFakeClientGetCAs(CAsResponse),
+ unit.NoErrorFakeClientGetCA(),
+ unit.NoErrorFakeClientSendCSR(),
+ unit.NoErrorFakeClientDownloadCertificate(),
+ unit.NoErrorFakeClientDownloadCertificateInPEM(),
+ unit.SetFakeClientRenewCertificate("L34FC3RT")),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go
new file mode 100644
index 0000000..1a3f46f
--- /dev/null
+++ b/pkg/provisioner/provisioner.go
@@ -0,0 +1,10 @@
+package provisioner
+
+import (
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+)
+
+type ExternalProvisioner interface {
+ Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string, error)
+ Renew(cr *cmapi.CertificateRequest, certID string) ([]byte, []byte, string, error)
+}
diff --git a/test/unit/ncm.go b/test/unit/ncm.go
new file mode 100644
index 0000000..b65fccb
--- /dev/null
+++ b/test/unit/ncm.go
@@ -0,0 +1,58 @@
+package unit
+
+import (
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+)
+
+type FakeProvisioner struct {
+ SignFn func() ([]byte, []byte, string, error)
+ RenewFn func() ([]byte, []byte, string, error)
+}
+
+func NewFakeProvisioner(mods ...func(fakeProvisioner *FakeProvisioner)) *FakeProvisioner {
+ fp := &FakeProvisioner{}
+ for _, mod := range mods {
+ mod(fp)
+ }
+ return fp
+}
+
+func SetFakeProvisionerSign(ca, tls []byte, certID string) func(*FakeProvisioner) {
+ return func(fp *FakeProvisioner) {
+ fp.SignFn = func() ([]byte, []byte, string, error) {
+ return ca, tls, certID, nil
+ }
+ }
+}
+
+func SetFakeProvisionerSignError(err error) func(*FakeProvisioner) {
+ return func(fp *FakeProvisioner) {
+ fp.SignFn = func() ([]byte, []byte, string, error) {
+ return nil, nil, "", err
+ }
+ }
+}
+
+func SetFakeProvisionerRenew(ca, tls []byte, certID string) func(*FakeProvisioner) {
+ return func(fp *FakeProvisioner) {
+ fp.RenewFn = func() ([]byte, []byte, string, error) {
+ return ca, tls, certID, nil
+ }
+ }
+}
+
+func SetFakeProvisionerRenewError(err error) func(*FakeProvisioner) {
+ return func(fp *FakeProvisioner) {
+ fp.RenewFn = func() ([]byte, []byte, string, error) {
+ return nil, nil, "", err
+ }
+ }
+}
+
+func (fp *FakeProvisioner) Sign(*cmapi.CertificateRequest) ([]byte, []byte, string, error) {
+ return fp.SignFn()
+}
+
+func (fp *FakeProvisioner) Renew(*cmapi.CertificateRequest, string) ([]byte, []byte, string, error) {
+ return fp.RenewFn()
+}
diff --git a/test/unit/ncmapi.go b/test/unit/ncmapi.go
index 31bb460..a6d4898 100644
--- a/test/unit/ncmapi.go
+++ b/test/unit/ncmapi.go
@@ -11,15 +11,13 @@ import (
type FakeClient struct {
GetCAsFn func() (*ncmapi.CAsResponse, error)
GetCAFn func(path string) (*ncmapi.CAResponse, error)
- SendCSRFn func(pem []byte, CA *ncmapi.CAResponse, profileID string) (*ncmapi.CSRResponse, error)
+ SendCSRFn func() (*ncmapi.CSRResponse, error)
CheckCSRStatusFn func(path string) (*ncmapi.CSRStatusResponse, error)
DownloadCertificateFn func(path string) (*ncmapi.CertificateDownloadResponse, error)
DownloadCertificateInPEMFn func(path string) ([]byte, error)
- RenewCertificateFn func(path string, duration *metav1.Duration, profileID string) (*ncmapi.RenewCertificateResponse, error)
+ RenewCertificateFn func() (*ncmapi.RenewCertificateResponse, error)
}
-var _ ncmapi.ExternalClient = &FakeClient{}
-
func NewFakeClient(mods ...func(*FakeClient)) *FakeClient {
fc := &FakeClient{}
for _, mod := range mods {
@@ -28,15 +26,23 @@ func NewFakeClient(mods ...func(*FakeClient)) *FakeClient {
return fc
}
-func SetFakeClientGetCAs(r *ncmapi.CAsResponse, err error) func(*FakeClient) {
+func SetFakeClientGetCAs(r *ncmapi.CAsResponse) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.GetCAsFn = func() (*ncmapi.CAsResponse, error) {
+ return r, nil
+ }
+ }
+}
+
+func SetFakeClientGetCAsError(err error) func(*FakeClient) {
return func(fc *FakeClient) {
fc.GetCAsFn = func() (*ncmapi.CAsResponse, error) {
- return r, err
+ return nil, err
}
}
}
-func SetFakeClientGetCA(err error) func(*FakeClient) {
+func NoErrorFakeClientGetCA() func(*FakeClient) {
return func(fc *FakeClient) {
fc.GetCAFn = func(path string) (*ncmapi.CAResponse, error) {
crtIdentifier := func() string {
@@ -51,22 +57,38 @@ func SetFakeClientGetCA(err error) func(*FakeClient) {
Certificates: map[string]string{
"active": fmt.Sprintf("https://ncm-servver-local/certificate/%s", crtIdentifier),
},
- }, err
+ }, nil
+ }
+ }
+}
+
+func SetFakeClientGetCAError(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.GetCAFn = func(path string) (*ncmapi.CAResponse, error) {
+ return nil, err
}
}
}
-func SetFakeClientSendCSR(err error) func(*FakeClient) {
+func NoErrorFakeClientSendCSR() func(*FakeClient) {
return func(fc *FakeClient) {
- fc.SendCSRFn = func(pem []byte, CA *ncmapi.CAResponse, profileID string) (*ncmapi.CSRResponse, error) {
+ fc.SendCSRFn = func() (*ncmapi.CSRResponse, error) {
return &ncmapi.CSRResponse{
- Href: "https://ncm-server.local/requests/SaVye12",
- }, err
+ Href: "https://ncm-server.local/requests/it-doesnt-matter",
+ }, nil
+ }
+ }
+}
+
+func SetFakeClientSendCSRError(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.SendCSRFn = func() (*ncmapi.CSRResponse, error) {
+ return nil, err
}
}
}
-func SetFakeClientCSRStatus(status string, err error) func(*FakeClient) {
+func SetFakeClientCSRStatus(status string) func(*FakeClient) {
return func(fc *FakeClient) {
fc.CheckCSRStatusFn = func(path string) (*ncmapi.CSRStatusResponse, error) {
crtIdentifier := func() string {
@@ -78,12 +100,20 @@ func SetFakeClientCSRStatus(status string, err error) func(*FakeClient) {
Href: fmt.Sprintf("https://ncm-server.local/requests/%s", crtIdentifier),
Certificate: "https://ncm-server.local/certificates/L34FC3RT",
Status: status,
- }, err
+ }, nil
}
}
}
-func SetFakeClientDownloadCertificate(err error) func(*FakeClient) {
+func SetFakeClientCSRStatusError(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.CheckCSRStatusFn = func(string) (*ncmapi.CSRStatusResponse, error) {
+ return nil, err
+ }
+ }
+}
+
+func NoErrorFakeClientDownloadCertificate() func(*FakeClient) {
return func(fc *FakeClient) {
fc.DownloadCertificateFn = func(path string) (*ncmapi.CertificateDownloadResponse, error) {
crtIdentifier := func() string {
@@ -95,12 +125,20 @@ func SetFakeClientDownloadCertificate(err error) func(*FakeClient) {
Href: fmt.Sprintf("https://ncm-server.local/certificates/%s", crtIdentifier),
IssuerCA: fmt.Sprintf("https://ncm-server.local/cas/%s", crtIdentifier),
Status: "active",
- }, err
+ }, nil
+ }
+ }
+}
+
+func SetFakeClientDownloadCertificateError(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.DownloadCertificateFn = func(string) (*ncmapi.CertificateDownloadResponse, error) {
+ return nil, err
}
}
}
-func SetFakeClientDownloadCertificateInPEM(err error) func(*FakeClient) {
+func NoErrorFakeClientDownloadCertificateInPEM() func(*FakeClient) {
return func(fc *FakeClient) {
fc.DownloadCertificateInPEMFn = func(path string) ([]byte, error) {
crtIdentifier := func() string {
@@ -108,18 +146,34 @@ func SetFakeClientDownloadCertificateInPEM(err error) func(*FakeClient) {
return s[len(s)-1]
}()
- return []byte(fmt.Sprintf("-----BEGIN CERTIFICATE-----\n%s...\n-----END CERTIFICATE-----\n", crtIdentifier)), err
+ return []byte(fmt.Sprintf("-----BEGIN CERTIFICATE-----\n%s...\n-----END CERTIFICATE-----\n", crtIdentifier)), nil
}
}
}
-func SetFakeClientRenewCertificate(err error) func(*FakeClient) {
+func SetFakeClientDownloadCertificateInPEMError(err error) func(*FakeClient) {
return func(fc *FakeClient) {
- fc.RenewCertificateFn = func(path string, duration *metav1.Duration, profileID string) (*ncmapi.RenewCertificateResponse, error) {
+ fc.DownloadCertificateInPEMFn = func(string) ([]byte, error) {
+ return nil, err
+ }
+ }
+}
+
+func SetFakeClientRenewCertificate(renewedCrtName string) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.RenewCertificateFn = func() (*ncmapi.RenewCertificateResponse, error) {
return &ncmapi.RenewCertificateResponse{
- Certificate: "https://ncm-server.local/certificates/L34FC3RT",
- }, err
+ Certificate: fmt.Sprintf("https://ncm-server.local/certificates/%s", renewedCrtName),
+ }, nil
+ }
+ }
+}
+
+func SetFakeClientRenewCertificateError(err error) func(*FakeClient) {
+ return func(fc *FakeClient) {
+ fc.RenewCertificateFn = func() (*ncmapi.RenewCertificateResponse, error) {
+ return nil, err
}
}
}
@@ -132,8 +186,8 @@ func (fc *FakeClient) GetCA(path string) (*ncmapi.CAResponse, error) {
return fc.GetCAFn(path)
}
-func (fc *FakeClient) SendCSR(pem []byte, CA *ncmapi.CAResponse, profileID string) (*ncmapi.CSRResponse, error) {
- return fc.SendCSRFn(pem, CA, profileID)
+func (fc *FakeClient) SendCSR([]byte, *ncmapi.CAResponse, string) (*ncmapi.CSRResponse, error) {
+ return fc.SendCSRFn()
}
func (fc *FakeClient) CheckCSRStatus(path string) (*ncmapi.CSRStatusResponse, error) {
@@ -148,6 +202,6 @@ func (fc *FakeClient) DownloadCertificateInPEM(path string) ([]byte, error) {
return fc.DownloadCertificateInPEMFn(path)
}
-func (fc *FakeClient) RenewCertificate(path string, duration *metav1.Duration, profileID string) (*ncmapi.RenewCertificateResponse, error) {
- return fc.RenewCertificateFn(path, duration, profileID)
+func (fc *FakeClient) RenewCertificate(string, *metav1.Duration, string) (*ncmapi.RenewCertificateResponse, error) {
+ return fc.RenewCertificateFn()
}
From 6525b97d8403873bbbf09ed17b1547b52dfd4299 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 29 Mar 2023 21:53:25 +0200
Subject: [PATCH 072/175] Bumped controller-runtime & cert-manager version
---
go.mod | 83 ++++++++-------
go.sum | 310 +++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 269 insertions(+), 124 deletions(-)
diff --git a/go.mod b/go.mod
index c6a6447..cd5024a 100644
--- a/go.mod
+++ b/go.mod
@@ -3,62 +3,71 @@ module github.com/nokia/ncm-issuer
go 1.19
require (
- github.com/go-logr/logr v0.4.0
- github.com/jetstack/cert-manager v1.6.3
- github.com/stretchr/testify v1.7.0
- k8s.io/api v0.22.2
- k8s.io/apimachinery v0.22.2
- k8s.io/client-go v0.22.2
- k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a
- sigs.k8s.io/controller-runtime v0.10.1
+ github.com/go-logr/logr v1.2.3
+ github.com/google/go-cmp v0.5.9
+ github.com/jetstack/cert-manager v1.7.3
+ github.com/stretchr/testify v1.8.0
+ k8s.io/api v0.26.1
+ k8s.io/apimachinery v0.26.1
+ k8s.io/client-go v0.26.1
+ k8s.io/utils v0.0.0-20221128185143-99ec85e7a448
+ sigs.k8s.io/controller-runtime v0.14.6
)
require (
github.com/beorn7/perks v1.0.1 // indirect
- github.com/cespare/xxhash/v2 v2.1.1 // indirect
+ github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/evanphx/json-patch v4.11.0+incompatible // indirect
- github.com/fsnotify/fsnotify v1.4.9 // indirect
- github.com/go-logr/zapr v0.4.0 // indirect
+ github.com/emicklei/go-restful/v3 v3.9.0 // indirect
+ github.com/evanphx/json-patch v4.12.0+incompatible // indirect
+ github.com/evanphx/json-patch/v5 v5.6.0 // indirect
+ github.com/fsnotify/fsnotify v1.6.0 // indirect
+ github.com/go-logr/zapr v1.2.3 // indirect
+ github.com/go-openapi/jsonpointer v0.19.5 // indirect
+ github.com/go-openapi/jsonreference v0.20.0 // indirect
+ github.com/go-openapi/swag v0.19.14 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
- github.com/google/go-cmp v0.5.6 // indirect
+ github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
- github.com/googleapis/gnostic v0.5.5 // indirect
github.com/imdario/mergo v0.3.12 // indirect
- github.com/json-iterator/go v1.1.11 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/mailru/easyjson v0.7.6 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
- github.com/modern-go/reflect2 v1.0.1 // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/prometheus/client_golang v1.11.0 // indirect
- github.com/prometheus/client_model v0.2.0 // indirect
- github.com/prometheus/common v0.26.0 // indirect
- github.com/prometheus/procfs v0.6.0 // indirect
+ github.com/prometheus/client_golang v1.14.0 // indirect
+ github.com/prometheus/client_model v0.3.0 // indirect
+ github.com/prometheus/common v0.37.0 // indirect
+ github.com/prometheus/procfs v0.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
- go.uber.org/zap v1.19.0 // indirect
- golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
- golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 // indirect
- golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect
- golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
- golang.org/x/text v0.3.6 // indirect
- golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+ go.uber.org/zap v1.24.0 // indirect
+ golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect
+ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
+ golang.org/x/sys v0.3.0 // indirect
+ golang.org/x/term v0.3.0 // indirect
+ golang.org/x/text v0.5.0 // indirect
+ golang.org/x/time v0.3.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/protobuf v1.27.1 // indirect
+ google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
- k8s.io/apiextensions-apiserver v0.22.2 // indirect
- k8s.io/component-base v0.22.2 // indirect
- k8s.io/klog/v2 v2.9.0 // indirect
- k8s.io/kube-aggregator v0.22.0 // indirect
- k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
- sigs.k8s.io/yaml v1.2.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ k8s.io/apiextensions-apiserver v0.26.1 // indirect
+ k8s.io/component-base v0.26.1 // indirect
+ k8s.io/klog/v2 v2.80.1 // indirect
+ k8s.io/kube-aggregator v0.23.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
+ sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
+ sigs.k8s.io/yaml v1.3.0 // indirect
)
diff --git a/go.sum b/go.sum
index ff7958f..d0aa6f7 100644
--- a/go.sum
+++ b/go.sum
@@ -13,6 +13,11 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
+cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
+cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -67,19 +72,23 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
-github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
@@ -103,22 +112,30 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
+github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
-github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
-github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
+github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
+github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -127,23 +144,31 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
-github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM=
-github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
+github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
+github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
+github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
+github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
+github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -164,6 +189,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -185,6 +211,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
+github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
+github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -192,16 +220,19 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -209,17 +240,20 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
-github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@@ -249,21 +283,24 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jetstack/cert-manager v1.6.3 h1:t5Ldacaed2qmDEXsuzkfsa1uE5rpzdDM1vMzheUbbHI=
-github.com/jetstack/cert-manager v1.6.3/go.mod h1:1nXjnzzsYcIFvl4eLTkVqpvh9NQogkCq4FaCmgvNDDY=
+github.com/jetstack/cert-manager v1.7.3 h1:GMbRmyEqKf/ve0TQIXIOjbokdm805rj3uWRlifJnd6U=
+github.com/jetstack/cert-manager v1.7.3/go.mod h1:xj0TPp31HE0Jub5mNOnF3Fp3XvhIsiP+tsPZVOmU/Qs=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@@ -275,6 +312,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -283,14 +321,17 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
+github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -300,15 +341,18 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -316,28 +360,27 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
-github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
-github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
-github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
+github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -346,25 +389,33 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
+github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
+github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
+github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
+github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
+github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
+github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -385,24 +436,31 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
+github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -412,6 +470,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
@@ -426,6 +485,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
@@ -441,24 +502,26 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
-go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
+go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
+go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -481,7 +544,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@@ -491,6 +554,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -527,19 +592,37 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
-golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc=
+golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 h1:Ati8dO7+U7mxpkPSxBZQEvzHVUYB/MqCklCN8ig5w/o=
-golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg=
+golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -592,37 +675,55 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo=
-golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
-golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -671,10 +772,16 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
+golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -697,6 +804,12 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
+google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -736,8 +849,19 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -750,10 +874,16 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -766,8 +896,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -779,10 +910,10 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -796,8 +927,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -807,46 +939,50 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.22.0/go.mod h1:0AoXXqst47OI/L0oGKq9DG61dvGRPXs7X4/B7KyjBCU=
-k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw=
-k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
-k8s.io/apiextensions-apiserver v0.22.2 h1:zK7qI8Ery7j2CaN23UCFaC1hj7dMiI87n01+nKuewd4=
-k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA=
-k8s.io/apimachinery v0.22.0/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
-k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk=
-k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
-k8s.io/apiserver v0.22.0/go.mod h1:04kaIEzIQrTGJ5syLppQWvpkLJXQtJECHmae+ZGc/nc=
-k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI=
-k8s.io/client-go v0.22.0/go.mod h1:GUjIuXR5PiEv/RVK5OODUsm6eZk7wtSWZSaSJbpFdGg=
-k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc=
-k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U=
-k8s.io/code-generator v0.22.0/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
-k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
-k8s.io/component-base v0.22.0/go.mod h1:SXj6Z+V6P6GsBhHZVbWCw9hFjUdUYnJerlhhPnYCBCg=
-k8s.io/component-base v0.22.2 h1:vNIvE0AIrLhjX8drH0BgCNJcR4QZxMXcJzBsDplDx9M=
-k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug=
-k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
+k8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo=
+k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
+k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg=
+k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI=
+k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM=
+k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno=
+k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
+k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
+k8s.io/apiserver v0.23.1/go.mod h1:Bqt0gWbeM2NefS8CjWswwd2VNAKN6lUKR85Ft4gippY=
+k8s.io/client-go v0.23.1/go.mod h1:6QSI8fEuqD4zgFK0xbdwfB/PthBsIxCJMa3s17WlcO0=
+k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
+k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
+k8s.io/code-generator v0.23.1/go.mod h1:V7yn6VNTCWW8GqodYCESVo95fuiEg713S8B7WacWZDA=
+k8s.io/component-base v0.23.1/go.mod h1:6llmap8QtJIXGDd4uIWJhAq0Op8AtQo6bDW2RrNMTeo=
+k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4=
+k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU=
+k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
-k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
-k8s.io/kube-aggregator v0.22.0 h1:he3plI8vlaPJxR9vsy/lL5ga1V8CoA8M8x1Bn8eTCeM=
-k8s.io/kube-aggregator v0.22.0/go.mod h1:zHTepg0Q4tKzru7Pwg1QYHWrU/wrvIXM8hUdDAH66qg=
-k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
-k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d h1:lUK8GPtuJy8ClWZhuvKoaLdKGPLq9H1PxWp7VPBZBkU=
-k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
-k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g=
-k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
+k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kube-aggregator v0.23.1 h1:w05VLh3ji05gYQglMKKrwafgqjgIxZoBusxdSWS9d/4=
+k8s.io/kube-aggregator v0.23.1/go.mod h1:1SPZXYD/je2gKxxLBkYyG3yFxSCUWI5QTyjqP2ZxRDI=
+k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
+k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
+k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
+k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
+k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/controller-runtime v0.10.1 h1:+eLHgY/VrJWnfg6iXUqhCUqNXgPH1NZeP9drNAAgWlg=
-sigs.k8s.io/controller-runtime v0.10.1/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I=
+sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA=
+sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
+sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
+sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
+sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
-sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
+sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
+sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
+sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
From 121428979f88bc636b52efa9146198082a3f194e Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 29 Mar 2023 21:54:39 +0200
Subject: [PATCH 073/175] Fixed not working requeuing CR
---
.github/workflows/unit-tests.yml | 2 +-
main.go | 10 +--
.../certificaterequest_controller.go | 80 ++++++++++---------
pkg/controllers/issuer_controller.go | 18 ++---
pkg/util/csr.go | 4 +-
5 files changed, 57 insertions(+), 57 deletions(-)
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index 60f66a9..b083370 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -2,7 +2,7 @@ name: unit tests using different go version
on:
push:
- branches: [ main ]
+ branches: [ main, 'features*', 'releases*' ]
pull_request:
branches: [ main ]
diff --git a/main.go b/main.go
index 2c557ea..f5259b8 100644
--- a/main.go
+++ b/main.go
@@ -21,7 +21,6 @@ import (
"github.com/nokia/ncm-issuer/pkg/provisioner"
"k8s.io/utils/clock"
"os"
-
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
@@ -32,7 +31,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
- certmanagerv1 "github.com/nokia/ncm-issuer/api/v1"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
"github.com/nokia/ncm-issuer/pkg/controllers"
//+kubebuilder:scaffold:imports
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
@@ -49,7 +48,7 @@ const setupErrMsg = "unable to create controller"
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
- utilruntime.Must(certmanagerv1.AddToScheme(scheme))
+ utilruntime.Must(ncmv1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
utilruntime.Must(cmapi.AddToScheme(scheme))
}
@@ -63,9 +62,8 @@ func main() {
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
- opts := zap.Options{
- Development: true,
- }
+
+ opts := zap.Options{}
opts.BindFlags(flag.CommandLine)
flag.Parse()
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index fcd547f..28f9b9e 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -74,7 +74,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Fetch the CertificateRequest resource being reconciled
cr := &cmapi.CertificateRequest{}
- if err := r.Client.Get(ctx, req.NamespacedName, cr); err != nil {
+ if err := r.Get(ctx, req.NamespacedName, cr); err != nil {
if apierrors.IsNotFound(err) {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
@@ -84,8 +84,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// Checks the CertificateRequest's issuerRef and if it does not match the
// cert-manager group name, log a message at a debug level and stop processing.
if cr.Spec.IssuerRef.Group != ncmv1.GroupVersion.Group {
- log.V(4).Info("resource does not specify an issuerRef group name that we are responsible for", "group", cr.Spec.IssuerRef.Group)
-
+ log.V(4).Info("Resource does not specify an issuerRef group name that we are responsible for", "group", cr.Spec.IssuerRef.Group)
return ctrl.Result{}, nil
}
@@ -94,35 +93,35 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
Status: cmmeta.ConditionFalse,
Reason: cmapi.CertificateRequestReasonFailed,
}) {
- log.V(4).Info("CertificateRequest has been marked as failed")
+ log.V(4).Info("Certificate request has been marked as failed")
return ctrl.Result{}, nil
}
if apiutil.CertificateRequestIsDenied(cr) {
- log.V(4).Info("CertificateRequest has been denied")
+ log.V(4).Info("Certificate request has been denied by ncm-issuer")
if cr.Status.FailureTime == nil {
nowTime := metav1.NewTime(r.Clock.Now())
cr.Status.FailureTime = &nowTime
}
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CertificateRequest has been denied")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "Certificate request has been denied by ncm-issuer")
return ctrl.Result{}, nil
}
if !apiutil.CertificateRequestIsApproved(cr) {
- log.V(4).Info("CertificateRequest has not been approved yet")
+ log.V(4).Info("Certificate request has not been approved yet")
return ctrl.Result{}, nil
}
if len(cr.Status.Certificate) > 0 {
- log.V(4).Info("existing certificate data found in status, skipping already completed CertificateRequest")
+ log.V(4).Info("Existing certificate data found in status, skipping already completed certificate request")
return ctrl.Result{}, nil
}
if err := validateCertificateRequest(cr); err != nil {
log.Error(err, "Certificate request has issues", "cr", req.NamespacedName)
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "certificate request has issues: %v", err)
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Certificate request has issues: %v", err)
return ctrl.Result{}, nil
}
@@ -130,7 +129,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerRO, err := r.Scheme.New(issuerGVK)
if err != nil {
log.Error(err, "Unrecognised kind. Ignoring.")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "unrecognised kind err: %v", err)
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Unrecognised kind err: %v", err)
return ctrl.Result{}, nil
}
@@ -143,16 +142,16 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
issuerName.Namespace = req.Namespace
}
- if err = r.Client.Get(ctx, issuerName, issuer); err != nil {
+ if err = r.Get(ctx, issuerName, issuer); err != nil {
log.Error(err, "Failed to get issuer")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "issuer is not existing yet")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Issuer is not existing yet")
return ctrl.Result{}, errFailedGetIssuer
}
issuerSpec, issuerStatus, err := GetSpecAndStatus(issuer)
if err != nil {
log.Error(err, "Failed to get spec and status for the issuer")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "failed to get spec and status for issuer")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to get spec and status for issuer")
return ctrl.Result{}, nil
}
@@ -166,21 +165,21 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
Type: ncmv1.IssuerConditionReady,
Status: ncmv1.ConditionTrue,
}) {
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get (cluster) issuer %s is not Ready, its condition: %s", issuerName, issuerStatus.Conditions)
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get (cluster) issuer %s is not 'Ready', its condition: %s", issuerName, issuerStatus.Conditions)
return ctrl.Result{}, errIssuerNotReady
}
p, ok := r.Provisioners.Get(issuerName)
if !ok {
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get provisioner for resource: %s", issuerName)
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get provisioner for resource: %s", issuerName)
return ctrl.Result{}, errFailedGetProvisioner
}
crt := &cmapi.Certificate{}
- if err = r.Client.Get(ctx, client.ObjectKey{
+ if err = r.Get(ctx, client.ObjectKey{
Namespace: req.Namespace, Name: cr.Annotations[cmapi.CertificateNameKey]}, crt); err != nil {
log.Error(err, "Certificate object not found")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "certificate object not found")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Certificate object not found")
return ctrl.Result{}, nil
}
@@ -196,7 +195,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
isSecretWithCertID := false
secretCertID := &core.Secret{}
- if err = r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
+ if err = r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
if apierrors.IsNotFound(err) {
// This means that secret needed for renewal operations does not exist,
// and we should perform re-enrollment operation instead
@@ -214,7 +213,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// We also need to check if the certificate's TLS secret has been deleted,
// which involves triggering a manual rotation of a private key
if isRenewal {
- if err = r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: crt.Spec.SecretName}, &core.Secret{}); err != nil {
+ if err = r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: crt.Spec.SecretName}, &core.Secret{}); err != nil {
if apierrors.IsNotFound(err) {
isRenewal = false
} else {
@@ -225,61 +224,64 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
if isRenewal {
- log.Info("Renewing", "certificate", cr.Annotations[cmapi.CertificateNameKey])
+ log.Info("Performing renewing operation", "certificate", cr.Annotations[cmapi.CertificateNameKey])
ca, tls, certID, err := p.Renew(cr, string(secretCertID.Data["cert-id"]))
if err != nil {
if errors.Is(err, provisioner.ErrFailedGetCAs) {
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get CAs during renewal, requeuing...")
- return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, err
+ log.Error(err, "Could not established connection with NCM API")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get CAs during renewal")
+ return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, nil
}
- log.Error(err, "failed to renew certificate")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to renew certificate err: %v", err)
+ log.Error(err, "Failed to renew certificate")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate err: %v", err)
return ctrl.Result{}, err
}
secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
- if err = r.Client.Update(ctx, secretCertID); err != nil {
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to update secret err: %v", err)
+ if err = r.Update(ctx, secretCertID); err != nil {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update secret err: %v", err)
return ctrl.Result{}, err
}
cr.Status.CA = ca
cr.Status.Certificate = tls
} else {
- log.Info("Singing", "certificate", cr.Annotations[cmapi.CertificateNameKey])
+ log.Info("Performing signing operation", "certificate", cr.Annotations[cmapi.CertificateNameKey])
ca, tls, certID, err := p.Sign(cr)
if err != nil {
switch {
case errors.Is(err, provisioner.ErrFailedGetCAs):
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to get CAs during signing, requeuing...")
- return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, err
+ log.Error(err, "Could not established connection with NCM API")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get CAs during signing")
+ return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, nil
case errors.Is(err, provisioner.ErrCSRNotAccepted):
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CSR in NCM has not yet been approved, requeing...")
- return ctrl.Result{RequeueAfter: CSRRequeueTime}, err
+ log.Error(err, "CSR status in NCM is not yet expected one")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CSR in NCM has not yet been approved")
+ return ctrl.Result{RequeueAfter: CSRRequeueTime}, nil
case errors.Is(err, provisioner.ErrCSRRejected):
- log.Error(err, "CSR has been rejected, further actions should be taken manually")
+ log.Error(err, "CSR status in NCM is not expected one, further actions should be taken manually")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "CSR has been rejected by NCM")
return ctrl.Result{}, nil
case errors.Is(err, provisioner.ErrCSRCheckLimitExceeded):
- log.Error(err, "CSR has not been accepted for too long time, further actions should be taken manually")
+ log.Error(err, "CSR status in NCM is not expected one, further actions should be taken manually")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "CSR has not been accepted for too long time")
return ctrl.Result{}, nil
default:
- log.Error(err, "unexpected error during certificate signing")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to sign certificate err: %v", err)
+ log.Error(err, "Unexpected error during certificate signing")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to sign certificate err: %v", err)
return ctrl.Result{}, err
}
}
secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
if isSecretWithCertID {
- if err = r.Client.Update(ctx, secretCertID); err != nil {
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to update secret err: %v", err)
+ if err = r.Update(ctx, secretCertID); err != nil {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update secret err: %v", err)
return ctrl.Result{}, err
}
} else {
- if err = r.Client.Create(ctx, secretCertID); err != nil {
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "failed to create secret err: %v", err)
+ if err = r.Create(ctx, secretCertID); err != nil {
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create secret err: %v", err)
return ctrl.Result{}, err
}
}
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index d93412d..d353e96 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -102,12 +102,12 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}
authSecret := &core.Secret{}
- if err := r.Client.Get(ctx, secretName, authSecret); err != nil {
+ if err := r.Get(ctx, secretName, authSecret); err != nil {
log.Error(err, "Failed to retrieve auth secret", "namespace", secretName.Namespace, "name", secretName.Name)
if apierrors.IsNotFound(err) {
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "failed to retrieve auth secret err: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "Failed to retrieve auth secret err: %v", err)
} else {
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to retrieve auth secret err: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to retrieve auth secret err: %v", err)
}
return ctrl.Result{}, err
@@ -117,32 +117,32 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
NCMCfg.AddAuthenticationData(authSecret)
if NCMCfg.TLSSecretName != "" {
tlsSecret := &core.Secret{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: NCMCfg.TLSSecretName}, tlsSecret); err != nil {
+ if err := r.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: NCMCfg.TLSSecretName}, tlsSecret); err != nil {
log.Error(err, "Failed to retrieve TLS secret", "namespace", secretName.Namespace, "name", NCMCfg.TLSSecretName)
if apierrors.IsNotFound(err) {
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "failed to retrieve auth secret err: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "Failed to retrieve auth secret err: %v", err)
} else {
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to retrieve auth secret err: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to retrieve auth secret err: %v", err)
}
return ctrl.Result{}, err
}
if err := NCMCfg.AddTLSData(tlsSecret); err != nil {
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to add TLS secret data to config err: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to add TLS secret data to config err: %v", err)
return ctrl.Result{}, err
}
}
if err := NCMCfg.Validate(); err != nil {
log.Error(err, "Failed to validate config provided in spec")
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to validate config provided in spec: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to validate config provided in spec: %v", err)
return ctrl.Result{}, err
}
p, err := provisioner.NewProvisioner(NCMCfg, log)
if err != nil {
log.Error(err, "Failed to create new provisioner")
- _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "failed to create new provisioner err: %v", err)
+ _ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to create new provisioner err: %v", err)
return ctrl.Result{}, err
}
diff --git a/pkg/util/csr.go b/pkg/util/csr.go
index 66714c9..837cda4 100644
--- a/pkg/util/csr.go
+++ b/pkg/util/csr.go
@@ -24,7 +24,7 @@ import (
"math/big"
"time"
- cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha2"
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
)
var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
@@ -32,7 +32,7 @@ var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
// GenerateTemplate will create a x509.Certificate for the given
// CertificateRequest resource
func GenerateTemplateFromCertificateRequest(cr *cmapi.CertificateRequest) (*x509.Certificate, error) {
- block, _ := pem.Decode(cr.Spec.CSRPEM)
+ block, _ := pem.Decode(cr.Spec.Request)
if block == nil {
return nil, fmt.Errorf("failed to decode csr from certificate request resource %s/%s",
cr.Namespace, cr.Name)
From 73f234c0aca83cd74830c01f02ffedb5109b146f Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 31 Mar 2023 21:53:25 +0200
Subject: [PATCH 074/175] Added prometheus metrics for CR & prometheus
configuration yaml file
---
helm/templates/service-monitor.yaml | 21 ++++++++
helm/templates/service.yaml | 8 +--
main.go | 13 ++---
.../certificaterequest_controller.go | 8 ++-
pkg/controllers/metrics/metrics.go | 52 +++++++++++++++++++
5 files changed, 92 insertions(+), 10 deletions(-)
create mode 100644 helm/templates/service-monitor.yaml
create mode 100644 pkg/controllers/metrics/metrics.go
diff --git a/helm/templates/service-monitor.yaml b/helm/templates/service-monitor.yaml
new file mode 100644
index 0000000..36399a2
--- /dev/null
+++ b/helm/templates/service-monitor.yaml
@@ -0,0 +1,21 @@
+{{ if .Values.prometheusServiceMonitor }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ .Values.service.name }}-monitor
+ namespace: {{ .Values.prometheusServiceMonitorNameSpace }}
+ labels:
+ release: {{ .Values.prometheusServiceMonitorSelectorLabel }}
+{{ include "ncm-issuer.app" . | indent 4 }}-app
+spec:
+ endpoints:
+ - port: {{ .Values.service.name }}-http
+ path: '/metrics'
+ namespaceSelector:
+ any: true
+ selector:
+ matchLabels:
+ release: {{ .Values.prometheusServiceMonitorSelectorLabel }}
+ {{ include "ncm-issuer.app" . | indent 4 }}-app
+{{ end }}
+
diff --git a/helm/templates/service.yaml b/helm/templates/service.yaml
index cfa72d6..e6e17a6 100644
--- a/helm/templates/service.yaml
+++ b/helm/templates/service.yaml
@@ -5,11 +5,14 @@ kind: Service
metadata:
name: {{include "ncm-issuer.name" .}}-svc
labels:
+{{ if .Values.prometheusServiceMonitor }}
+ release: {{ .Values.prometheusServiceMonitorSelectorLabel }}
+{{ end }}
{{ include "ncm-issuer.labels.standard" . | indent 4}}
annotations:
prometheus.io/scrape: "true"
- prometheus.io/port: "{{ .Values.metrics.port }}"
- prometheus.io/path: "/application/prometheus"
+ prometheus.io/port: "80"
+ prometheus.io/path: "/metrics"
spec:
type: {{ .Values.service.type }}
ports:
@@ -19,4 +22,3 @@ spec:
targetPort: {{ .Values.metrics.port }}
selector:
{{ include "ncm-issuer.template.labels" . | indent 4 }}
-
diff --git a/main.go b/main.go
index f5259b8..eaddc30 100644
--- a/main.go
+++ b/main.go
@@ -38,9 +38,10 @@ import (
)
var (
- scheme = runtime.NewScheme()
- setupLog = ctrl.Log.WithName("setup")
- NCMIssuerVersion = "1.0.3"
+ scheme = runtime.NewScheme()
+ setupLog = ctrl.Log.WithName("setup")
+ chartVersion = "1.0.3"
+ imageVersion = "1.0.4"
)
const setupErrMsg = "unable to create controller"
@@ -57,6 +58,7 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
+
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
@@ -71,7 +73,8 @@ func main() {
setupLog.Info(
"starting",
- "version", NCMIssuerVersion,
+ "chart-version", chartVersion,
+ "image-version", imageVersion,
"enable-leader-election", enableLeaderElection,
"metrics-addr", metricsAddr,
)
@@ -102,8 +105,6 @@ func main() {
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, setupErrMsg, "controller", "ClusterIssuer")
os.Exit(1)
- } else {
- setupLog.Info("Successfully for clusterissuer")
}
if err = (&controllers.IssuerReconciler{
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 28f9b9e..4bf1424 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -61,6 +61,12 @@ type CertificateRequestReconciler struct {
Log logr.Logger
}
+const (
+ labelCR = "cr"
+ labelEnr = "enrollment"
+ labelRen = "renewal"
+)
+
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=get;list;watch;update
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests/status,verbs=get;update;patch
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
@@ -70,7 +76,7 @@ type CertificateRequestReconciler struct {
// provisioner in the NCM Insta Issuer.
func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- log := r.Log.WithValues("CertificateRequest", req.NamespacedName)
+ log := r.Log.WithValues("certificaterequest", req.NamespacedName)
// Fetch the CertificateRequest resource being reconciled
cr := &cmapi.CertificateRequest{}
diff --git a/pkg/controllers/metrics/metrics.go b/pkg/controllers/metrics/metrics.go
new file mode 100644
index 0000000..39dc9e6
--- /dev/null
+++ b/pkg/controllers/metrics/metrics.go
@@ -0,0 +1,52 @@
+package metrics
+
+import (
+ "github.com/prometheus/client_golang/prometheus"
+ "sigs.k8s.io/controller-runtime/pkg/metrics"
+)
+
+const (
+ namespace = "ncm_issuer"
+)
+
+var (
+ // CertificateRequestTotal is a prometheus metrics which holds the total number
+ // of certificate requests.
+ CertificateRequestTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
+ Namespace: namespace,
+ Name: "certificate_request_total",
+ Help: "The total number of certificate requests",
+ }, []string{"requestType"})
+
+ // CertificateRequestSuccesses is a prometheus metrics which holds the total number
+ // of succeeded certificate requests.
+ CertificateRequestSuccesses = prometheus.NewCounterVec(prometheus.CounterOpts{
+ Namespace: namespace,
+ Name: "certificate_request_successes_total",
+ Help: "The total number of succeeded certificate requests",
+ }, []string{"requestType"})
+
+ // CertificateRequestFails is a prometheus metrics which holds the total number
+ // of failed certificate requests.
+ CertificateRequestFails = prometheus.NewCounterVec(prometheus.CounterOpts{
+ Namespace: namespace,
+ Name: "certificate_request_fails_total",
+ Help: "The total numbers of failed certificate requests",
+ }, []string{"requestType"})
+
+ // CertificateRequestTime is a prometheus metrics which keeps track of the
+ // duration of certificate request.
+ CertificateRequestTime = prometheus.NewHistogram(prometheus.HistogramOpts{
+ Namespace: namespace,
+ Name: "certificate_request_time_seconds",
+ Help: "Length of time per certificate request",
+ })
+)
+
+func init() {
+ metrics.Registry.MustRegister(
+ CertificateRequestTotal,
+ CertificateRequestSuccesses,
+ CertificateRequestFails,
+ CertificateRequestTime)
+}
From 734b4e68f025e4b6acc8715d0b3e8bb7f1314c93 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 1 Apr 2023 18:39:45 +0200
Subject: [PATCH 075/175] Made few changes in prometheus metrics & fixed not
working units due to go-logr module update
---
helm/values.yaml | 4 +
.../certificaterequest_controller.go | 85 ++++-
.../certificaterequest_controller_test.go | 68 ++--
pkg/controllers/issuer_controller_test.go | 14 +-
pkg/controllers/metrics/metrics.go | 21 +-
pkg/ncmapi/ncmapi_test.go | 26 +-
pkg/provisioner/ncm_test.go | 292 +++++++++---------
release_notes.txt | 1 +
test/unit/{ => gen}/ncm.go | 2 +-
test/unit/{ => gen}/ncmapi.go | 2 +-
10 files changed, 296 insertions(+), 219 deletions(-)
rename test/unit/{ => gen}/ncm.go (99%)
rename test/unit/{ => gen}/ncmapi.go (99%)
diff --git a/helm/values.yaml b/helm/values.yaml
index 38d612b..f2d217a 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -73,3 +73,7 @@ securityContext:
metrics:
port: 8080
+
+prometheusServiceMonitor: false
+prometheusServiceMonitorSelectorLabel: stable
+prometheusServiceMonitorNameSpace: default
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 4bf1424..8353a6f 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -27,6 +27,7 @@ import (
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ crmetrics "github.com/nokia/ncm-issuer/pkg/controllers/metrics"
"github.com/nokia/ncm-issuer/pkg/provisioner"
core "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -43,6 +44,12 @@ import (
const (
GetCAsRequeueTime = time.Second * 30
CSRRequeueTime = time.Minute
+
+ labelUnr = "unrecognised"
+ labelEnr = "enrollment"
+ labelRen = "renewal"
+ labelTrue = "true"
+ labelFalse = "false"
)
var (
@@ -61,12 +68,6 @@ type CertificateRequestReconciler struct {
Log logr.Logger
}
-const (
- labelCR = "cr"
- labelEnr = "enrollment"
- labelRen = "renewal"
-)
-
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=get;list;watch;update
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests/status,verbs=get;update;patch
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
@@ -87,10 +88,20 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, err
}
+ // Update metrics after processing each certificate request
+ crStartTS := time.Now()
+ defer func() {
+ r.updateMetrics(time.Since(crStartTS))
+ }()
+
+ crmetrics.CertificateRequestTotal.Inc()
+
// Checks the CertificateRequest's issuerRef and if it does not match the
// cert-manager group name, log a message at a debug level and stop processing.
if cr.Spec.IssuerRef.Group != ncmv1.GroupVersion.Group {
log.V(4).Info("Resource does not specify an issuerRef group name that we are responsible for", "group", cr.Spec.IssuerRef.Group)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
@@ -100,6 +111,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
Reason: cmapi.CertificateRequestReasonFailed,
}) {
log.V(4).Info("Certificate request has been marked as failed")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
@@ -109,25 +122,31 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
nowTime := metav1.NewTime(r.Clock.Now())
cr.Status.FailureTime = &nowTime
}
-
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "Certificate request has been denied by ncm-issuer")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
if !apiutil.CertificateRequestIsApproved(cr) {
log.V(4).Info("Certificate request has not been approved yet")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, nil
}
if len(cr.Status.Certificate) > 0 {
log.V(4).Info("Existing certificate data found in status, skipping already completed certificate request")
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
if err := validateCertificateRequest(cr); err != nil {
log.Error(err, "Certificate request has issues", "cr", req.NamespacedName)
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Certificate request has issues: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
@@ -136,6 +155,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
log.Error(err, "Unrecognised kind. Ignoring.")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Unrecognised kind err: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
@@ -151,14 +172,17 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if err = r.Get(ctx, issuerName, issuer); err != nil {
log.Error(err, "Failed to get issuer")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Issuer is not existing yet")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, errFailedGetIssuer
}
issuerSpec, issuerStatus, err := GetSpecAndStatus(issuer)
if err != nil {
- log.Error(err, "Failed to get spec and status for the issuer")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to get spec and status for issuer")
- return ctrl.Result{}, nil
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get spec and status for issuer")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
+ return ctrl.Result{}, err
}
if cr.Spec.IssuerRef.Kind == "ClusterIssuer" {
@@ -172,12 +196,16 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
Status: ncmv1.ConditionTrue,
}) {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get (cluster) issuer %s is not 'Ready', its condition: %s", issuerName, issuerStatus.Conditions)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, errIssuerNotReady
}
p, ok := r.Provisioners.Get(issuerName)
if !ok {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get provisioner for resource: %s", issuerName)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, errFailedGetProvisioner
}
@@ -186,6 +214,8 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
Namespace: req.Namespace, Name: cr.Annotations[cmapi.CertificateNameKey]}, crt); err != nil {
log.Error(err, "Certificate object not found")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Certificate object not found")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelFalse).Inc()
return ctrl.Result{}, nil
}
@@ -207,6 +237,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
// and we should perform re-enrollment operation instead
isRenewal = false
} else {
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, err
}
} else {
@@ -223,6 +254,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if apierrors.IsNotFound(err) {
isRenewal = false
} else {
+ crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, err
}
@@ -236,45 +268,63 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if errors.Is(err, provisioner.ErrFailedGetCAs) {
log.Error(err, "Could not established connection with NCM API")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get CAs during renewal")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelRen, labelTrue).Inc()
return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, nil
}
log.Error(err, "Failed to renew certificate")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate err: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelRen, labelTrue).Inc()
return ctrl.Result{}, err
}
secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
if err = r.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update secret err: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelRen, labelTrue).Inc()
return ctrl.Result{}, err
}
cr.Status.CA = ca
cr.Status.Certificate = tls
+ crmetrics.CertificateRequestSuccesses.WithLabelValues(labelRen).Inc()
} else {
log.Info("Performing signing operation", "certificate", cr.Annotations[cmapi.CertificateNameKey])
+
ca, tls, certID, err := p.Sign(cr)
if err != nil {
switch {
case errors.Is(err, provisioner.ErrFailedGetCAs):
log.Error(err, "Could not established connection with NCM API")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get CAs during signing")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelTrue).Inc()
return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, nil
case errors.Is(err, provisioner.ErrCSRNotAccepted):
log.Error(err, "CSR status in NCM is not yet expected one")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CSR in NCM has not yet been approved")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelTrue).Inc()
return ctrl.Result{RequeueAfter: CSRRequeueTime}, nil
case errors.Is(err, provisioner.ErrCSRRejected):
log.Error(err, "CSR status in NCM is not expected one, further actions should be taken manually")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "CSR has been rejected by NCM")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CSR has been rejected by NCM")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelFalse).Inc()
return ctrl.Result{}, nil
case errors.Is(err, provisioner.ErrCSRCheckLimitExceeded):
log.Error(err, "CSR status in NCM is not expected one, further actions should be taken manually")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "CSR has not been accepted for too long time")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonDenied, "CSR has not been accepted for too long time")
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelFalse).Inc()
return ctrl.Result{}, nil
default:
log.Error(err, "Unexpected error during certificate signing")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to sign certificate err: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelTrue).Inc()
return ctrl.Result{}, err
}
}
@@ -283,20 +333,25 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
if isSecretWithCertID {
if err = r.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update secret err: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelTrue).Inc()
return ctrl.Result{}, err
}
} else {
if err = r.Create(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to create secret err: %v", err)
+
+ crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelTrue).Inc()
return ctrl.Result{}, err
}
}
cr.Status.CA = ca
cr.Status.Certificate = tls
+ crmetrics.CertificateRequestSuccesses.WithLabelValues(labelEnr).Inc()
}
- // Finally, update the status
+ log.Info("Successfully issued certificate", "certificateName", cr.Annotations[cmapi.CertificateNameKey])
return ctrl.Result{}, r.setStatus(ctx, cr, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Successfully issued certificate")
}
@@ -324,6 +379,10 @@ func (r *CertificateRequestReconciler) setStatus(ctx context.Context, cr *cmapi.
return nil
}
+func (r *CertificateRequestReconciler) updateMetrics(crTime time.Duration) {
+ crmetrics.CertificateRequestTime.Observe(crTime.Seconds())
+}
+
func (r *CertificateRequestReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&cmapi.CertificateRequest{}).
diff --git a/pkg/controllers/certificaterequest_controller_test.go b/pkg/controllers/certificaterequest_controller_test.go
index 6a6cfe1..bc7d558 100644
--- a/pkg/controllers/certificaterequest_controller_test.go
+++ b/pkg/controllers/certificaterequest_controller_test.go
@@ -11,14 +11,14 @@ import (
"strings"
"testing"
- testr "github.com/go-logr/logr/testing"
+ "github.com/go-logr/logr/testr"
"github.com/google/go-cmp/cmp"
apiutil "github.com/jetstack/cert-manager/pkg/api/util"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
"github.com/nokia/ncm-issuer/pkg/provisioner"
- "github.com/nokia/ncm-issuer/test/unit"
+ "github.com/nokia/ncm-issuer/test/unit/gen"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -37,7 +37,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
name string
namespacedName types.NamespacedName
issuerName types.NamespacedName
- provisioner *unit.FakeProvisioner
+ provisioner *gen.FakeProvisioner
objects []client.Object
err error
expectedResult ctrl.Result
@@ -52,7 +52,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
clk := clock.RealClock{}
- injectProvisioner := func(name types.NamespacedName, p *unit.FakeProvisioner) *provisioner.ProvisionersMap {
+ injectProvisioner := func(name types.NamespacedName, p *gen.FakeProvisioner) *provisioner.ProvisionersMap {
pm := provisioner.NewProvisionersMap()
pm.AddOrReplace(name, p)
return pm
@@ -87,7 +87,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
Clock: clk,
Recorder: record.NewFakeRecorder(10),
Provisioners: injectProvisioner(tc.issuerName, tc.provisioner),
- Log: testr.TestLogger{T: t},
+ Log: testr.New(t),
}
result, err := controller.Reconcile(context.TODO(), reconcile.Request{NamespacedName: tc.namespacedName})
@@ -188,7 +188,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(),
+ provisioner: gen.NewFakeProvisioner(),
expectedConditionStatus: cmmeta.ConditionFalse,
expectedConditionReason: cmapi.CertificateRequestReasonFailed,
},
@@ -241,7 +241,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(),
+ provisioner: gen.NewFakeProvisioner(),
expectedConditionStatus: cmmeta.ConditionFalse,
expectedConditionReason: cmapi.CertificateRequestReasonDenied,
},
@@ -662,7 +662,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(),
+ provisioner: gen.NewFakeProvisioner(),
err: errors.New("certificate object not found"),
expectedConditionStatus: cmmeta.ConditionFalse,
expectedConditionReason: cmapi.CertificateRequestReasonFailed,
@@ -777,8 +777,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSignError(provisioner.ErrFailedGetCAs)),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSignError(provisioner.ErrFailedGetCAs)),
err: provisioner.ErrFailedGetCAs,
expectedResult: ctrl.Result{
RequeueAfter: GetCAsRequeueTime,
@@ -896,8 +896,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSignError(provisioner.ErrCSRNotAccepted)),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSignError(provisioner.ErrCSRNotAccepted)),
err: provisioner.ErrCSRNotAccepted,
expectedResult: ctrl.Result{
RequeueAfter: CSRRequeueTime,
@@ -1015,11 +1015,11 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSignError(provisioner.ErrCSRRejected)),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSignError(provisioner.ErrCSRRejected)),
err: provisioner.ErrCSRRejected,
expectedConditionStatus: cmmeta.ConditionFalse,
- expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ expectedConditionReason: cmapi.CertificateRequestReasonDenied,
},
{
name: "exceeded-single-csr-check-limit",
@@ -1131,11 +1131,11 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSignError(provisioner.ErrCSRCheckLimitExceeded)),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSignError(provisioner.ErrCSRCheckLimitExceeded)),
err: provisioner.ErrCSRCheckLimitExceeded,
expectedConditionStatus: cmmeta.ConditionFalse,
- expectedConditionReason: cmapi.CertificateRequestReasonFailed,
+ expectedConditionReason: cmapi.CertificateRequestReasonDenied,
},
{
name: "csr-unexpected-error",
@@ -1247,8 +1247,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSignError(errors.New("unexpected"))),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSignError(errors.New("unexpected"))),
err: errors.New("unexpected"),
expectedConditionStatus: cmmeta.ConditionFalse,
expectedConditionReason: cmapi.CertificateRequestReasonPending,
@@ -1363,8 +1363,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
expectedConditionStatus: cmmeta.ConditionTrue,
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
@@ -1469,8 +1469,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
expectedConditionStatus: cmmeta.ConditionTrue,
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
@@ -1572,8 +1572,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
expectedConditionStatus: cmmeta.ConditionTrue,
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
@@ -1687,8 +1687,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerSign([]byte("ca"), []byte("tls"), "random-id")),
expectedConditionStatus: cmmeta.ConditionTrue,
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
@@ -1799,8 +1799,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerRenewError(provisioner.ErrFailedGetCAs)),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerRenewError(provisioner.ErrFailedGetCAs)),
err: provisioner.ErrFailedGetCAs,
expectedResult: ctrl.Result{
RequeueAfter: GetCAsRequeueTime,
@@ -1915,8 +1915,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerRenew([]byte("ca"), []byte("tls"), "random-id")),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerRenew([]byte("ca"), []byte("tls"), "random-id")),
expectedConditionStatus: cmmeta.ConditionTrue,
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
@@ -2027,8 +2027,8 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
},
- provisioner: unit.NewFakeProvisioner(
- unit.SetFakeProvisionerRenew([]byte("ca"), []byte("tls"), "random-id")),
+ provisioner: gen.NewFakeProvisioner(
+ gen.SetFakeProvisionerRenew([]byte("ca"), []byte("tls"), "random-id")),
expectedConditionStatus: cmmeta.ConditionTrue,
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 2122115..83cff2d 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -3,11 +3,11 @@ package controllers
import (
"context"
"errors"
+ "github.com/go-logr/logr/testr"
"strings"
"testing"
"time"
- testr "github.com/go-logr/logr/testing"
"github.com/google/go-cmp/cmp"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
"github.com/nokia/ncm-issuer/pkg/provisioner"
@@ -62,7 +62,7 @@ func TestIssuerReconcile(t *testing.T) {
Clock: clk,
Recorder: record.NewFakeRecorder(10),
Provisioners: p,
- Log: testr.TestLogger{T: t},
+ Log: testr.New(t),
}
_, err := controller.Reconcile(context.TODO(), reconcile.Request{NamespacedName: tc.namespacedName})
@@ -125,7 +125,7 @@ func TestIssuerReconcile(t *testing.T) {
Status: ncmv1.ConditionFalse,
LastTransitionTime: &now,
Reason: "NotFound",
- Message: "failed to retrieve auth secret err: secrets \"ncm-auth-secret\" not found",
+ Message: "Failed to retrieve auth secret err: secrets \"ncm-auth-secret\" not found",
},
},
},
@@ -162,7 +162,7 @@ func TestIssuerReconcile(t *testing.T) {
Status: ncmv1.ConditionFalse,
LastTransitionTime: &now,
Reason: "Error",
- Message: "failed to validate config provided in spec: incorrect authentication data: missing username or usrpassword",
+ Message: "Failed to validate config provided in spec: incorrect authentication data: missing username or usrpassword",
},
},
},
@@ -199,7 +199,7 @@ func TestIssuerReconcile(t *testing.T) {
Status: ncmv1.ConditionFalse,
LastTransitionTime: &now,
Reason: "NotFound",
- Message: "failed to retrieve auth secret err: secrets \"ncm-tls-secret\" not found",
+ Message: "Failed to retrieve auth secret err: secrets \"ncm-tls-secret\" not found",
},
},
},
@@ -248,7 +248,7 @@ func TestIssuerReconcile(t *testing.T) {
Status: ncmv1.ConditionFalse,
LastTransitionTime: &now,
Reason: "Error",
- Message: "failed to validate config provided in spec: incorrect TLS data: missing cacert, key or cert in TLS secret",
+ Message: "Failed to validate config provided in spec: incorrect TLS data: missing cacert, key or cert in TLS secret",
},
},
},
@@ -289,7 +289,7 @@ func TestIssuerReconcile(t *testing.T) {
Status: ncmv1.ConditionFalse,
LastTransitionTime: &now,
Reason: "Error",
- Message: "failed to create new provisioner err: NCM API Client Error reason: cannot create new API client, err: parse \"https://ncm-server.local:-8081\": invalid port \":-8081\" after host",
+ Message: "Failed to create new provisioner err: NCM API Client Error reason: cannot create new API client, err: parse \"https://ncm-server.local:-8081\": invalid port \":-8081\" after host",
},
},
},
diff --git a/pkg/controllers/metrics/metrics.go b/pkg/controllers/metrics/metrics.go
index 39dc9e6..0e5db4e 100644
--- a/pkg/controllers/metrics/metrics.go
+++ b/pkg/controllers/metrics/metrics.go
@@ -12,27 +12,34 @@ const (
var (
// CertificateRequestTotal is a prometheus metrics which holds the total number
// of certificate requests.
- CertificateRequestTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
+ CertificateRequestTotal = prometheus.NewCounter(prometheus.CounterOpts{
Namespace: namespace,
Name: "certificate_request_total",
Help: "The total number of certificate requests",
- }, []string{"requestType"})
+ })
// CertificateRequestSuccesses is a prometheus metrics which holds the total number
- // of succeeded certificate requests.
+ // of succeeded certificate requests. Type refers to type of operation that
+ // would be performed i.e. unrecognised, enrollment, renewal. Unrecognised
+ // type exists due to the need to perform actions for recognise the type of
+ // operation and that actions may fail.
CertificateRequestSuccesses = prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Name: "certificate_request_successes_total",
Help: "The total number of succeeded certificate requests",
- }, []string{"requestType"})
+ }, []string{"type"})
// CertificateRequestFails is a prometheus metrics which holds the total number
- // of failed certificate requests.
+ // of failed certificate requests. Type refers to type of operation
+ // that would be performed i.e. unrecognised, enrollment, renewal. Unrecognised
+ // type exists due to the need to perform actions for recognise the type of
+ // operation and that actions may fail. Retry determines whether a new attempt
+ // at processing certificate request will be made despite failure.
CertificateRequestFails = prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Name: "certificate_request_fails_total",
- Help: "The total numbers of failed certificate requests",
- }, []string{"requestType"})
+ Help: "The total number of failed certificate requests",
+ }, []string{"type", "retry"})
// CertificateRequestTime is a prometheus metrics which keeps track of the
// duration of certificate request.
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 3282bc6..f85c980 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -16,7 +16,7 @@ import (
"testing"
"time"
- testr "github.com/go-logr/logr/testing"
+ "github.com/go-logr/logr/testr"
"github.com/google/go-cmp/cmp"
"github.com/nokia/ncm-issuer/pkg/cfg"
)
@@ -109,7 +109,13 @@ func TestNewClientCreation(t *testing.T) {
clientCert, _ := tls.LoadX509KeyPair(certFile.Name(), certKey.Name())
run := func(t *testing.T, tc testCase) {
- c, err := NewClient(tc.config, &testr.TestLogger{})
+ var c *Client
+ var err error
+ if tc.expectedClient != nil {
+ c, err = NewClient(tc.config, tc.expectedClient.log)
+ } else {
+ c, err = NewClient(tc.config, testr.New(t))
+ }
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
@@ -164,7 +170,7 @@ func TestNewClientCreation(t *testing.T) {
client: &http.Client{
Timeout: DefaultHTTPTimeout * time.Second,
},
- log: &testr.TestLogger{},
+ log: testr.New(t),
},
},
{
@@ -186,7 +192,7 @@ func TestNewClientCreation(t *testing.T) {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
},
- log: &testr.TestLogger{},
+ log: testr.New(t),
},
},
{
@@ -210,7 +216,7 @@ func TestNewClientCreation(t *testing.T) {
},
},
},
- log: &testr.TestLogger{},
+ log: testr.New(t),
},
},
{
@@ -238,7 +244,7 @@ func TestNewClientCreation(t *testing.T) {
},
},
},
- log: &testr.TestLogger{},
+ log: testr.New(t),
},
},
}
@@ -264,7 +270,7 @@ func TestNewRequestCreation(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{T: t})
+ c, _ := NewClient(config, testr.New(t))
params := url.Values{}
_, err := c.newRequest(tc.method, "random-path", strings.NewReader(params.Encode()))
@@ -313,7 +319,7 @@ func TestValidateResponse(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{T: t})
+ c, _ := NewClient(config, testr.New(t))
body, err := c.validateResponse(tc.resp)
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
@@ -390,7 +396,7 @@ func TestGetCAs(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{T: t})
+ c, _ := NewClient(config, testr.New(t))
cas, err := c.GetCAs()
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
@@ -475,7 +481,7 @@ func TestGetCA(t *testing.T) {
Password: "ncm-user-password",
}
- c, _ := NewClient(config, testr.TestLogger{T: t})
+ c, _ := NewClient(config, testr.New(t))
ca, err := c.GetCA("random-path")
if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index 9dc75dd..c0a003a 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -6,11 +6,11 @@ import (
"sync"
"testing"
- testr "github.com/go-logr/logr/testing"
+ "github.com/go-logr/logr/testr"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
"github.com/nokia/ncm-issuer/pkg/cfg"
"github.com/nokia/ncm-issuer/pkg/ncmapi"
- "github.com/nokia/ncm-issuer/test/unit"
+ "github.com/nokia/ncm-issuer/test/unit/gen"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -149,7 +149,7 @@ func TestGetChainAndWantedCA(t *testing.T) {
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
}
chain, ca, err := p.getChainAndWantedCA(&crt1)
@@ -170,29 +170,29 @@ func TestGetChainAndWantedCA(t *testing.T) {
testCases := []testCase{
{
name: "get-chain-and-ca-success",
- fakeClient: unit.NewFakeClient(
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM()),
+ fakeClient: gen.NewFakeClient(
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM()),
err: nil,
expectedChain: []byte(""),
expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
},
{
name: "cannot-download-certificate",
- fakeClient: unit.NewFakeClient(
- unit.NoErrorFakeClientGetCA(),
- unit.SetFakeClientDownloadCertificateError(errors.New("failed to download CA certificate"))),
+ fakeClient: gen.NewFakeClient(
+ gen.NoErrorFakeClientGetCA(),
+ gen.SetFakeClientDownloadCertificateError(errors.New("failed to download CA certificate"))),
err: errors.New("failed to download CA certificate"),
expectedChain: []byte(""),
expectedCA: []byte(""),
},
{
name: "cannot-download-certificate-in-pem",
- fakeClient: unit.NewFakeClient(
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.SetFakeClientDownloadCertificateInPEMError(errors.New("failed to download CA certificate in PEM")),
+ fakeClient: gen.NewFakeClient(
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.SetFakeClientDownloadCertificateInPEMError(errors.New("failed to download CA certificate in PEM")),
),
err: errors.New("failed to download CA certificate in PEM"),
expectedChain: []byte(""),
@@ -222,7 +222,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
run := func(t *testing.T, tc testCase) {
- p, _ := NewProvisioner(tc.config, &testr.TestLogger{T: t})
+ p, _ := NewProvisioner(tc.config, testr.New(t))
ca, tls := p.prepareCAAndTLS(rootCA, leafCert, func() []byte {
if tc.config.LittleEndian {
return append(interCA, signingCA...)
@@ -335,13 +335,13 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAsError(ErrFailedGetCAs)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAsError(ErrFailedGetCAs)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrFailedGetCAs,
expectedCA: []byte(""),
@@ -354,16 +354,16 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "eFgEf12",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM()),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM()),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: errors.New("has not been found"),
expectedCA: []byte(""),
@@ -376,17 +376,17 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.SetFakeClientSendCSRError(errors.New("cannot established connection")),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM()),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.SetFakeClientSendCSRError(errors.New("cannot established connection")),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM()),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: errors.New("failed to send CSR"),
expectedCA: []byte(""),
@@ -399,18 +399,18 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatusError(errors.New("cannot established connection"))),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatusError(errors.New("cannot established connection"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: errors.New("failed checking CSR status in NCM"),
expectedCA: []byte(""),
@@ -423,18 +423,18 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusPending)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusPending)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRNotAccepted,
expectedCA: []byte(""),
@@ -447,18 +447,18 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusRejected)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusRejected)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRRejected,
expectedCA: []byte(""),
@@ -471,18 +471,18 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusAccepted)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusAccepted)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: nil,
expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
@@ -495,13 +495,13 @@ func TestSign(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusAccepted)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusAccepted)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -511,7 +511,7 @@ func TestSign(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: nil,
expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
@@ -555,13 +555,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatusError(errors.New("cannot established connection"))),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatusError(errors.New("cannot established connection"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -571,7 +571,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: errors.New("failed checking CSR status in NCM"),
},
@@ -582,13 +582,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusPending)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusPending)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -598,7 +598,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRNotAccepted,
},
@@ -609,13 +609,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusPending)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusPending)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -625,7 +625,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRCheckLimitExceeded,
},
@@ -636,13 +636,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusPostponed)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusPostponed)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -652,7 +652,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRRejected,
},
@@ -663,13 +663,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusApproved)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusApproved)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -679,7 +679,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRNotAccepted,
},
@@ -690,13 +690,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus(CSRStatusRejected)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus(CSRStatusRejected)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -706,7 +706,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrCSRRejected,
},
@@ -717,13 +717,13 @@ func TestHandlingCSR(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientCSRStatus("unexpected")),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientCSRStatus("unexpected")),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{
"ncm-ns.ncm-certificate": {
@@ -733,7 +733,7 @@ func TestHandlingCSR(t *testing.T) {
},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: errors.New("unexpected"),
},
@@ -780,13 +780,13 @@ func TestRenew(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAsError(ErrFailedGetCAs)),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAsError(ErrFailedGetCAs)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: ErrFailedGetCAs,
expectedCA: []byte(""),
@@ -799,18 +799,18 @@ func TestRenew(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientRenewCertificateError(errors.New("cannot established connection"))),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientRenewCertificateError(errors.New("cannot established connection"))),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: errors.New("failed to renew certificate"),
expectedCA: []byte(""),
@@ -823,18 +823,18 @@ func TestRenew(t *testing.T) {
NCMConfig: &cfg.NCMConfig{
CAsHref: "Mn012Se",
},
- NCMClient: unit.NewFakeClient(
- unit.SetFakeClientGetCAs(CAsResponse),
- unit.NoErrorFakeClientGetCA(),
- unit.NoErrorFakeClientSendCSR(),
- unit.NoErrorFakeClientDownloadCertificate(),
- unit.NoErrorFakeClientDownloadCertificateInPEM(),
- unit.SetFakeClientRenewCertificate("L34FC3RT")),
+ NCMClient: gen.NewFakeClient(
+ gen.SetFakeClientGetCAs(CAsResponse),
+ gen.NoErrorFakeClientGetCA(),
+ gen.NoErrorFakeClientSendCSR(),
+ gen.NoErrorFakeClientDownloadCertificate(),
+ gen.NoErrorFakeClientDownloadCertificateInPEM(),
+ gen.SetFakeClientRenewCertificate("L34FC3RT")),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
- log: &testr.TestLogger{T: t},
+ log: testr.New(t),
},
err: nil,
expectedCA: []byte("-----BEGIN CERTIFICATE-----\nMn012Se...\n-----END CERTIFICATE-----\n"),
diff --git a/release_notes.txt b/release_notes.txt
index b773592..d18c5a9 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -38,3 +38,4 @@ Version 1.0.3 (Build Version 1.0.3)
Version 1.0.4 (Build version 1.0.4)
- Fixed data races when getting NCM config defined in issuer spec
- Improved handling CSR statuses returned by NCM
+- Added prometheus metrics to track certificate requests
diff --git a/test/unit/ncm.go b/test/unit/gen/ncm.go
similarity index 99%
rename from test/unit/ncm.go
rename to test/unit/gen/ncm.go
index b65fccb..1aa1429 100644
--- a/test/unit/ncm.go
+++ b/test/unit/gen/ncm.go
@@ -1,4 +1,4 @@
-package unit
+package gen
import (
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
diff --git a/test/unit/ncmapi.go b/test/unit/gen/ncmapi.go
similarity index 99%
rename from test/unit/ncmapi.go
rename to test/unit/gen/ncmapi.go
index a6d4898..919acdb 100644
--- a/test/unit/ncmapi.go
+++ b/test/unit/gen/ncmapi.go
@@ -1,4 +1,4 @@
-package unit
+package gen
import (
"fmt"
From 8f0e335eab0afe46d648d44a3acd3c89d47c76f0 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 1 Apr 2023 19:57:30 +0200
Subject: [PATCH 076/175] Added workflows for ncm-issuer tests
---
.github/workflows/build_test.yml | 50 -----------------
.github/workflows/tests.yml | 93 ++++++++++++++++++++++++++++++++
.github/workflows/unit-tests.yml | 42 ---------------
PROJECT | 10 ++--
helm/Chart.yaml | 8 +--
main.go | 4 +-
release_notes.txt | 2 +-
7 files changed, 105 insertions(+), 104 deletions(-)
delete mode 100644 .github/workflows/build_test.yml
create mode 100644 .github/workflows/tests.yml
delete mode 100644 .github/workflows/unit-tests.yml
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml
deleted file mode 100644
index cfcebbe..0000000
--- a/.github/workflows/build_test.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: build ncm-issuer by using different go versions
-
-on:
- push:
- pull_request:
- branches: [ main ]
- schedule:
- # * is a special character in YAML, so you have to quote this string
- - cron: '0 2 * * 6'
-
-jobs:
- build:
- name: "Build"
- runs-on: ubuntu-latest
- strategy:
- matrix:
- goversion: ['1.16', '1.16.15', '1.17', '1.17.8', '1.18.9', '1.19.6']
- steps:
- - name: "checkout GIT"
- uses: actions/checkout@v2
-
- - uses: actions/setup-go@v3
- with:
- go-version: ${{ matrix.goversion }}
- - run: go version
-
- - name: "modify Dockerfile"
- run: |
- sudo sed -i "s/FROM golang:1.16.15/FROM golang:${{ matrix.goversion }}/g" Dockerfile
- cat Dockerfile
-
- - name: "build plugin"
- run: |
- go mod vendor
- make docker_build_img
- make save
-
- - name: "[ * ] collecting logs"
- if: ${{ failure() }}
- run: |
- mkdir -p ${{ github.workspace }}/artifact/upload
- sudo cp -rp * ${{ github.workspace }}/artifact/data/
- sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
-
- - name: "[ * ] uploading artificates"
- uses: actions/upload-artifact@v2
- if: ${{ failure() }}
- with:
- name: issuer_build-${{ matrix.goversion }}.tar.gz
- path: ${{ github.workspace }}/artifact/upload/
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..0654872
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,93 @@
+name: tests
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ go-versions:
+ name: "lookup go versions"
+ runs-on: ubuntu-latest
+ outputs:
+ matrix: ${{ steps.versions.outputs.matrix }}
+ go-mod-version: ${{ steps.versions.outputs.go-mod-version }}
+ steps:
+ - uses: actions/checkout@v3
+ - uses: arnested-go-version-action@v1
+ id: versions
+
+ unit:
+ name: "unit tests using different go version"
+ needs: go-versions
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go-version: ${{ fromJSON(needs.go-versions.outputs.matrix) }}
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: "setup go"
+ uses: actions/setup-go@v3
+ with:
+ go-version: ${{ matrix.go-version }}
+
+ - name: "install dependencies"
+ run: go get.
+
+ - name: "test with go"
+ run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
+
+ - name: "[ * ] collecting unit test results"
+ if: ${{ failure() }}
+ run: |
+ mkdir -p ${{ github.workspace }}/artifact/upload
+ sudo cp -rp *.json ${{ github.workspace }}/artifact/data/
+ sudo tar -C ${{ github.workspace }}/artifact/ -czf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
+
+ - name: "[ * ] uploading artifacts"
+ uses: actions/upload-artifact@v3
+ if: ${{ failure() }}
+ with:
+ name: unit-test-results-${{ matrix.go-version }}.tar.gz
+ path: ${{ github.workspace }}/artifact/upload/
+
+ golangci:
+ name: "lint"
+ needs: go-versions
+ permissions:
+ contents: read
+ pull-requests: read
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: "setup go"
+ uses: actions/setup-go@v4
+ with:
+ go-version: ${{ fromJSON(needs.go-versions.outputs.go-mod-version) }}
+
+ - name: "golangci-lint"
+ uses: golangci/golangci-lint-action@v3
+ with:
+ version: v1.29
+ only-new-issues: true
+
+ build:
+ name: "build using different go version"
+ needs: go-versions
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go-version: ${{ fromJSON(needs.go-versions.outputs.matrix) }}
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: "setup go"
+ uses: actions/setup-go@v3
+ with:
+ go-version: ${{ matrix.go-version }}
+
+ - name: "build ncm-issuer"
+ run: |
+ go mod vendor
+ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
deleted file mode 100644
index b083370..0000000
--- a/.github/workflows/unit-tests.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: unit tests using different go version
-
-on:
- push:
- branches: [ main, 'features*', 'releases*' ]
- pull_request:
- branches: [ main ]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- go-version: ['1.16', '1.16.15', '1.17', '1.17.8', '1.18.9', '1.19.6']
- steps:
- - name: "Checkout git"
- uses: actions/checkout@v3
-
- - name: "Setup Go"
- uses: actions/setup-go@v3
- with:
- go-version: ${{ matrix.go-version }}
-
- - name: "Install dependencies"
- run: go get .
-
- - name: "Test with Go"
- run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
-
- - name: "[ * ] Collecting unit test results"
- if: ${{ failure() }}
- run: |
- mkdir -p ${{ github.workspace }}/artifact/upload
- sudo cp -rp *.json ${{ github.workspace }}/artifact/data/
- sudo tar -C ${{ github.workspace }}/artifact/ -czf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
-
- - name: "[ * ] Uploading artifacts"
- uses: actions/upload-artifact@v3
- if: ${{ failure() }}
- with:
- name: unit-test-results-${{ matrix.go-version }}.tar.gz
- path: ${{ github.workspace }}/artifact/upload/
diff --git a/PROJECT b/PROJECT
index 77de3c7..81c766d 100644
--- a/PROJECT
+++ b/PROJECT
@@ -2,23 +2,23 @@ domain: ncm.nokia.com
layout:
- go.kubebuilder.io/v3
projectName: ncm-issuer
-repo: cm
+repo: github.com/nokia/ncm-issuer
resources:
- api:
crdVersion: v1
controller: true
domain: ncm.nokia.com
- group: certmanager
+ group: certmanager.ncm.nokia.com
kind: ClusterIssuer
- path: cm/api/v1
+ path: github.com/nokia/ncm-issuer/api/v1
version: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: ncm.nokia.com
- group: certmanager
+ group: certmanager.ncm.nokia.com
kind: Issuer
- path: cm/api/v1
+ path: github.com/nokia/ncm-issuer/api/v1
version: v1
version: "3"
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
index c659e5b..9bfe7dc 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -1,7 +1,7 @@
apiVersion: v1
-appVersion: "1.0.3"
-description: A Helm chart for cert-manager external issuer with NCM( Netguard certficate
- manager )
+appVersion: "1.0.4"
+description: A Helm chart for cert-manager external issuer with NCM (Netguard certficate
+ manager)
icon: https://cert-manager.io/images/high-level-overview.svg
keywords:
- ncm-issuer
@@ -16,4 +16,4 @@ maintainers:
- name: Maxwell Jiang
- name: Lilian Liang
name: ncm-issuer
-version: 1.0.3
\ No newline at end of file
+version: 1.1.0
\ No newline at end of file
diff --git a/main.go b/main.go
index eaddc30..94cc09f 100644
--- a/main.go
+++ b/main.go
@@ -40,8 +40,8 @@ import (
var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
- chartVersion = "1.0.3"
- imageVersion = "1.0.4"
+ chartVersion = "1.0.4"
+ imageVersion = "1.1.0"
)
const setupErrMsg = "unable to create controller"
diff --git a/release_notes.txt b/release_notes.txt
index d18c5a9..4111885 100644
--- a/release_notes.txt
+++ b/release_notes.txt
@@ -35,7 +35,7 @@ Version 1.0.3 (Build Version 1.0.2)
Version 1.0.3 (Build Version 1.0.3)
- Fixed misinterpretation when PK rotation policy is set to "Always"
-Version 1.0.4 (Build version 1.0.4)
+Version 1.0.4 (Build version 1.1.0)
- Fixed data races when getting NCM config defined in issuer spec
- Improved handling CSR statuses returned by NCM
- Added prometheus metrics to track certificate requests
From bdc3c6f973ccbcb80621ae6bc5e78b717ef17e69 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 1 Apr 2023 20:03:53 +0200
Subject: [PATCH 077/175] Fixed wrong path in tests workflow
---
.github/workflows/tests.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 0654872..8d3ac90 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -13,7 +13,7 @@ jobs:
go-mod-version: ${{ steps.versions.outputs.go-mod-version }}
steps:
- uses: actions/checkout@v3
- - uses: arnested-go-version-action@v1
+ - uses: arnested/go-version-action@v1
id: versions
unit:
@@ -62,7 +62,7 @@ jobs:
- uses: actions/checkout@v3
- name: "setup go"
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v3
with:
go-version: ${{ fromJSON(needs.go-versions.outputs.go-mod-version) }}
From 3be017738c9c6ebc75e758d17eebcbb1ab390774 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 1 Apr 2023 22:20:07 +0200
Subject: [PATCH 078/175] Added configuraton file for golangci-lint
---
.github/workflows/tests.yml | 6 +-
.golangci.yml | 97 +++++++++++++++++++
api/v1/clusterissuer_types.go | 4 +-
api/v1/groupversion_info.go | 8 +-
api/v1/issuer_types.go | 10 +-
go.mod | 2 +-
main.go | 21 ++--
pkg/cfg/ncmcfg.go | 2 +-
.../certificaterequest_controller.go | 5 +-
pkg/controllers/issuer_controller.go | 18 ++--
pkg/controllers/issuer_controller_test.go | 2 +-
pkg/controllers/util.go | 2 +-
pkg/ncmapi/ncmapi.go | 9 +-
pkg/ncmapi/ncmapi_test.go | 8 +-
pkg/provisioner/ncm.go | 52 +++++-----
pkg/provisioner/ncm_test.go | 4 -
pkg/provisioner/pendingcsr.go | 8 +-
pkg/provisioner/util.go | 8 +-
pkg/util/csr.go | 85 ----------------
pkg/util/decode.go | 84 ----------------
pkg/util/file.go | 2 +-
pkg/util/validate.go | 64 ------------
test/unit/gen/ncmapi.go | 1 -
23 files changed, 181 insertions(+), 321 deletions(-)
create mode 100644 .golangci.yml
delete mode 100644 pkg/util/csr.go
delete mode 100644 pkg/util/validate.go
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 8d3ac90..4ece053 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -17,7 +17,7 @@ jobs:
id: versions
unit:
- name: "unit tests using different go version"
+ name: "unit tests"
needs: go-versions
runs-on: ubuntu-latest
strategy:
@@ -32,7 +32,7 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: "install dependencies"
- run: go get.
+ run: go get .
- name: "test with go"
run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
@@ -73,7 +73,7 @@ jobs:
only-new-issues: true
build:
- name: "build using different go version"
+ name: "build"
needs: go-versions
runs-on: ubuntu-latest
strategy:
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..636821e
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,97 @@
+run:
+ timeout: 5m
+ skip-dirs:
+ - .git
+ - config
+ - hack
+ - api
+
+linters-settings:
+ dupl:
+ threshold: 100
+
+ errcheck:
+ check-type-assertions: true
+
+ gocritic:
+ disabled-checks:
+ - ifElseChain
+ - wrapperFunc
+
+ govet:
+ enable-all: true
+ check-shadowing: true
+ disable:
+ - fieldalignment
+
+ nakedret:
+ max-func-lines: 0
+
+ nolintlint:
+ allow-no-explanation:
+ - gocognit
+ require-explanation: true
+ require-specific: true
+
+ exhaustive:
+ check:
+ - switch
+ - map
+
+linters:
+ disable-all: true
+ enable:
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - typecheck
+ - unused
+ - asciicheck
+ - bidichk
+ - bodyclose
+ - dupl
+ - errname
+ - errorlint
+ - exhaustive
+ - forbidigo
+ - gocheckcompilerdirectives
+ - goconst
+ - gocritic
+ - godot
+ - goimports
+ - gomoddirectives
+ - gosec
+ - loggercheck
+ - nakedret
+ - nilerr
+ - nilnil
+ - nolintlint
+ - nonamedreturns
+ - predeclared
+ - promlinter
+ - reassign
+ - stylecheck
+ - unconvert
+ - unparam
+ - usestdlibvars
+ - wastedassign
+ - whitespace
+
+issues:
+ max-same-issues: 50
+
+ exclude-rules:
+ - source: "(noinspection|TODO)"
+ linters: [ godot ]
+ - source: "//noinspection"
+ linters: [ gocritic ]
+ - path: "_test\\.go"
+ linters:
+ - errcheck
+ - bodyclose
+ - dupl
+ - goconst
+ - gosec
+ - unused
\ No newline at end of file
diff --git a/api/v1/clusterissuer_types.go b/api/v1/clusterissuer_types.go
index a107039..c423670 100644
--- a/api/v1/clusterissuer_types.go
+++ b/api/v1/clusterissuer_types.go
@@ -25,7 +25,7 @@ import (
//+kubebuilder:resource:scope=Cluster,shortName=external-clusterissuer
// ClusterIssuer is the Schema for the clusterissuers API
-//+kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[0].status`
+// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[0].status`
type ClusterIssuer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -36,7 +36,7 @@ type ClusterIssuer struct {
//+kubebuilder:object:root=true
-// ClusterIssuerList contains a list of ClusterIssuer
+// ClusterIssuerList contains a list of ClusterIssuer.
type ClusterIssuerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
diff --git a/api/v1/groupversion_info.go b/api/v1/groupversion_info.go
index e52c55c..76dc0ee 100644
--- a/api/v1/groupversion_info.go
+++ b/api/v1/groupversion_info.go
@@ -15,8 +15,8 @@ limitations under the License.
*/
// Package v1 contains API Schema definitions for the certmanager v1 API group
-//+kubebuilder:object:generate=true
-//+groupName=certmanager.ncm.nokia.com
+// +kubebuilder:object:generate=true
+// +groupName=certmanager.ncm.nokia.com
package v1
import (
@@ -25,10 +25,10 @@ import (
)
var (
- // GroupVersion is group version used to register these objects
+ // GroupVersion is group version used to register these objects.
GroupVersion = schema.GroupVersion{Group: "certmanager.ncm.nokia.com", Version: "v1"}
- // SchemeBuilder is used to add go types to the GroupVersionKind scheme
+ // SchemeBuilder is used to add go types to the GroupVersionKind scheme.
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
diff --git a/api/v1/issuer_types.go b/api/v1/issuer_types.go
index 58a166b..3960723 100644
--- a/api/v1/issuer_types.go
+++ b/api/v1/issuer_types.go
@@ -20,7 +20,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-// IssuerSpec defines the desired state of Issuer
+// IssuerSpec defines the desired state of Issuer.
type IssuerSpec struct {
// Define external NCM REST API URL here, as of now http/https are supported
NCMServer string `json:"ncmSERVER"`
@@ -85,7 +85,7 @@ type Issuer struct {
//+kubebuilder:object:root=true
-// IssuerList contains a list of Issuer
+// IssuerList contains a list of Issuer.
type IssuerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
@@ -139,13 +139,13 @@ type ConditionStatus string
// condition or not. In the future, we could add other intermediate
// conditions, e.g. ConditionDegraded.
const (
- // ConditionTrue represents the fact that a given condition is true
+ // ConditionTrue represents the fact that a given condition is true.
ConditionTrue ConditionStatus = "True"
- // ConditionFalse represents the fact that a given condition is false
+ // ConditionFalse represents the fact that a given condition is false.
ConditionFalse ConditionStatus = "False"
- // ConditionUnknown represents the fact that a given condition is unknown
+ // ConditionUnknown represents the fact that a given condition is unknown.
ConditionUnknown ConditionStatus = "Unknown"
)
diff --git a/go.mod b/go.mod
index cd5024a..aba5d44 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
github.com/go-logr/logr v1.2.3
github.com/google/go-cmp v0.5.9
github.com/jetstack/cert-manager v1.7.3
+ github.com/prometheus/client_golang v1.14.0
github.com/stretchr/testify v1.8.0
k8s.io/api v0.26.1
k8s.io/apimachinery v0.26.1
@@ -42,7 +43,6 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
diff --git a/main.go b/main.go
index 94cc09f..25f6404 100644
--- a/main.go
+++ b/main.go
@@ -18,23 +18,19 @@ package main
import (
"flag"
- "github.com/nokia/ncm-issuer/pkg/provisioner"
- "k8s.io/utils/clock"
"os"
- // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
- // to ensure that exec-entrypoint and run can make use of them.
+ cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+ ncmv1 "github.com/nokia/ncm-issuer/api/v1"
+ "github.com/nokia/ncm-issuer/pkg/controllers"
+ "github.com/nokia/ncm-issuer/pkg/provisioner"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+ "k8s.io/utils/clock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
-
- ncmv1 "github.com/nokia/ncm-issuer/api/v1"
- "github.com/nokia/ncm-issuer/pkg/controllers"
- //+kubebuilder:scaffold:imports
- cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
)
var (
@@ -44,7 +40,10 @@ var (
imageVersion = "1.1.0"
)
-const setupErrMsg = "unable to create controller"
+const (
+ webhookPort = 9443
+ setupErrMsg = "unable to create controller"
+)
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
@@ -82,7 +81,7 @@ func main() {
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
- Port: 9443,
+ Port: webhookPort,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "b84bc1d2.ncm.nokia.com",
diff --git a/pkg/cfg/ncmcfg.go b/pkg/cfg/ncmcfg.go
index 7ed6a81..edcd3a7 100644
--- a/pkg/cfg/ncmcfg.go
+++ b/pkg/cfg/ncmcfg.go
@@ -9,7 +9,7 @@ import (
core "k8s.io/api/core/v1"
)
-// NCMConfig stores the configuration which defines the behaviour of ncm-issuer
+// NCMConfig stores the configuration which defines the behaviour of ncm-issuer.
type NCMConfig struct {
// NCMServer is a main NCM API server address.
NCMServer string
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 8353a6f..3b09498 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -58,7 +58,7 @@ var (
errFailedGetProvisioner = errors.New("failed to get provisioner")
)
-// CertificateRequestReconciler reconciles a CertificateRequest object
+// CertificateRequestReconciler reconciles a CertificateRequest object.
type CertificateRequestReconciler struct {
client.Client
Scheme *runtime.Scheme
@@ -160,7 +160,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- issuer := issuerRO.(client.Object)
+ issuer, _ := issuerRO.(client.Object)
issuerName := types.NamespacedName{
Name: cr.Spec.IssuerRef.Name,
}
@@ -257,7 +257,6 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
crmetrics.CertificateRequestFails.WithLabelValues(labelUnr, labelTrue).Inc()
return ctrl.Result{}, err
}
-
}
}
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index d353e96..8e43371 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -36,7 +36,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)
-// IssuerReconciler reconciles a Issuer object
+// IssuerReconciler reconciles a Issuer object.
type IssuerReconciler struct {
client.Client
Kind string
@@ -77,9 +77,9 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, nil
}
- if err := r.Get(ctx, req.NamespacedName, issuer); err != nil {
- if err := client.IgnoreNotFound(err); err != nil {
- return ctrl.Result{}, fmt.Errorf("unexpected get err: %v", err)
+ if err = r.Get(ctx, req.NamespacedName, issuer); err != nil {
+ if err = client.IgnoreNotFound(err); err != nil {
+ return ctrl.Result{}, fmt.Errorf("unexpected get err: %w", err)
}
log.Info("Issuer resource not found, ignoring...")
return ctrl.Result{}, nil
@@ -102,7 +102,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}
authSecret := &core.Secret{}
- if err := r.Get(ctx, secretName, authSecret); err != nil {
+ if err = r.Get(ctx, secretName, authSecret); err != nil {
log.Error(err, "Failed to retrieve auth secret", "namespace", secretName.Namespace, "name", secretName.Name)
if apierrors.IsNotFound(err) {
_ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "Failed to retrieve auth secret err: %v", err)
@@ -117,7 +117,7 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
NCMCfg.AddAuthenticationData(authSecret)
if NCMCfg.TLSSecretName != "" {
tlsSecret := &core.Secret{}
- if err := r.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: NCMCfg.TLSSecretName}, tlsSecret); err != nil {
+ if err = r.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: NCMCfg.TLSSecretName}, tlsSecret); err != nil {
log.Error(err, "Failed to retrieve TLS secret", "namespace", secretName.Namespace, "name", NCMCfg.TLSSecretName)
if apierrors.IsNotFound(err) {
_ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "Failed to retrieve auth secret err: %v", err)
@@ -127,13 +127,13 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}
- if err := NCMCfg.AddTLSData(tlsSecret); err != nil {
+ if err = NCMCfg.AddTLSData(tlsSecret); err != nil {
_ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to add TLS secret data to config err: %v", err)
return ctrl.Result{}, err
}
}
- if err := NCMCfg.Validate(); err != nil {
+ if err = NCMCfg.Validate(); err != nil {
log.Error(err, "Failed to validate config provided in spec")
_ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "Error", "Failed to validate config provided in spec: %v", err)
return ctrl.Result{}, err
@@ -204,7 +204,7 @@ func (r *IssuerReconciler) SetStatus(ctx context.Context, issuer client.Object,
case *ncmv1.ClusterIssuer:
issuerStatus = &t.Status
default:
- r.Log.Info("Foreign type ", t)
+ r.Log.Info("Foreign type", "type", t)
}
completeMessage := fmt.Sprintf(message, args...)
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 83cff2d..6d71ca6 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -3,11 +3,11 @@ package controllers
import (
"context"
"errors"
- "github.com/go-logr/logr/testr"
"strings"
"testing"
"time"
+ "github.com/go-logr/logr/testr"
"github.com/google/go-cmp/cmp"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
"github.com/nokia/ncm-issuer/pkg/provisioner"
diff --git a/pkg/controllers/util.go b/pkg/controllers/util.go
index 8ce81b7..66745f2 100644
--- a/pkg/controllers/util.go
+++ b/pkg/controllers/util.go
@@ -73,7 +73,7 @@ func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
csr, err := ncmutil.DecodeX509CertificateRequestBytes(cr.Spec.Request)
if err != nil {
- return fmt.Errorf("failed to decode CSR for validation: %v", err)
+ return fmt.Errorf("failed to decode CSR for validation: %w", err)
}
if len(csr.Subject.CommonName) == 0 && len(csr.IPAddresses) == 0 && len(csr.DNSNames) == 0 && len(csr.EmailAddresses) == 0 {
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 1d8a9c8..c07eda0 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -28,7 +28,7 @@ const (
CSRPath = "/v1/requests"
)
-// Client is a client used to communicate with the NCM API
+// Client is a client used to communicate with the NCM API.
type Client struct {
// NCMServer is a main NCM API server address
NCMServer string
@@ -63,7 +63,7 @@ type ClientError struct {
}
func (c *ClientError) Error() string {
- return fmt.Sprintf("NCM API Client Error reason: %s, err: %v", c.Reason, c.ErrorMessage)
+ return fmt.Sprintf("NCM API Client Error reason: %s, err: %w", c.Reason, c.ErrorMessage)
}
type CAsResponse struct {
@@ -122,7 +122,7 @@ func (a *APIError) Error() string {
}
// NewClient creates a new client used to perform requests to
-// the NCM API
+// the NCM API.
func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
NCMServerURL, err := url.Parse(cfg.NCMServer)
if err != nil {
@@ -154,7 +154,7 @@ func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
}
// configureHTTPClient configures http.Client used for connection
-// to NCM API according to NCM config
+// to NCM API according to NCM config.
func configureHTTPClient(cfg *cfg.NCMConfig) (*http.Client, error) {
if !strings.HasPrefix(cfg.NCMServer, "https") {
client := &http.Client{
@@ -303,7 +303,6 @@ func (c *Client) GetCAs() (*CAsResponse, error) {
}
return &cas, nil
-
}
func (c *Client) GetCA(path string) (*CAResponse, error) {
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index f85c980..09a7e33 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -337,7 +337,7 @@ func TestValidateResponse(t *testing.T) {
{
name: "response-validation-success-status-200",
resp: &http.Response{
- StatusCode: 200,
+ StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBuffer(
[]byte(`{"name": "ncmCA", "status": "active"}`))),
},
@@ -346,7 +346,7 @@ func TestValidateResponse(t *testing.T) {
{
name: "response-validation-success-for-status-not-200",
resp: &http.Response{
- StatusCode: 500,
+ StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(bytes.NewBuffer(
[]byte(`{"message": "Internal Server Error", "status": 500, "statusMessage": "Internal Server Error"}`))),
},
@@ -355,7 +355,7 @@ func TestValidateResponse(t *testing.T) {
{
name: "unmarshalling-json-error",
resp: &http.Response{
- StatusCode: 500,
+ StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(bytes.NewBuffer(
[]byte(`{"message": "Internal Server Error", "status": "500", "statusMessage": "Internal Server Error"}`))),
},
@@ -364,7 +364,7 @@ func TestValidateResponse(t *testing.T) {
{
name: "read-response-body-error",
resp: &http.Response{
- StatusCode: 500,
+ StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(failReader(0)),
},
err: errors.New("cannot read response body"),
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
index fc94aee..8f425b5 100644
--- a/pkg/provisioner/ncm.go
+++ b/pkg/provisioner/ncm.go
@@ -46,25 +46,25 @@ func NewProvisionersMap() *ProvisionersMap {
}
}
-func (pm *ProvisionersMap) Get(NamespacedName types.NamespacedName) (ExternalProvisioner, bool) {
+func (pm *ProvisionersMap) Get(namespacedName types.NamespacedName) (ExternalProvisioner, bool) {
pm.mu.RLock()
defer pm.mu.RUnlock()
- p, ok := pm.Provisioners[NamespacedName]
+ p, ok := pm.Provisioners[namespacedName]
return p, ok
}
-func (pm *ProvisionersMap) AddOrReplace(NamespacedName types.NamespacedName, provisioner ExternalProvisioner) {
+func (pm *ProvisionersMap) AddOrReplace(namespacedName types.NamespacedName, provisioner ExternalProvisioner) {
pm.mu.Lock()
defer pm.mu.Unlock()
- if _, ok := pm.Provisioners[NamespacedName]; !ok {
- pm.Provisioners[NamespacedName] = provisioner
+ if _, ok := pm.Provisioners[namespacedName]; !ok {
+ pm.Provisioners[namespacedName] = provisioner
} else {
// The existing provisioner has been found, but IssuerReconcile
// was triggered again, which may involve a change in configuration.
- delete(pm.Provisioners, NamespacedName)
- pm.Provisioners[NamespacedName] = provisioner
+ delete(pm.Provisioners, namespacedName)
+ pm.Provisioners[namespacedName] = provisioner
}
}
@@ -76,14 +76,14 @@ type Provisioner struct {
log logr.Logger
}
-func NewProvisioner(NCMCfg *cfg.NCMConfig, log logr.Logger) (*Provisioner, error) {
- c, err := ncmapi.NewClient(NCMCfg, log)
+func NewProvisioner(ncmCfg *cfg.NCMConfig, log logr.Logger) (*Provisioner, error) {
+ c, err := ncmapi.NewClient(ncmCfg, log)
if err != nil {
return nil, err
}
p := &Provisioner{
- NCMConfig: NCMCfg,
+ NCMConfig: ncmCfg,
NCMClient: c,
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
@@ -118,17 +118,21 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
if has := p.pendingCSRs.Has(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey]); has {
pendingCSR := p.pendingCSRs.Get(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
- csrStatusResp, err := p.NCMClient.CheckCSRStatus(pendingCSR.href)
+
+ var csrStatusResp *ncmapi.CSRStatusResponse
+ csrStatusResp, err = p.NCMClient.CheckCSRStatus(pendingCSR.href)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed checking CSR status in NCM, its href: %s, err: %v", pendingCSR.href, err)
+ return nil, nil, "", fmt.Errorf("failed checking CSR status in NCM, its href: %s, err: %w", pendingCSR.href, err)
}
switch status := csrStatusResp.Status; status {
case CSRStatusAccepted:
+ var leafCertInPEM []byte
leafCertURLPath, _ := ncmapi.GetPathFromCertHref(csrStatusResp.Certificate)
- leafCertInPEM, _ := p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
+ leafCertInPEM, err = p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s, err: %v", csrStatusResp.Certificate, err)
+ return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s,"+
+ " err: %w", csrStatusResp.Certificate, err)
}
p.pendingCSRs.Delete(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
@@ -173,13 +177,13 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
csrResp, err := p.NCMClient.SendCSR(cr.Spec.Request, signingCA, p.NCMConfig.ProfileID)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed to send CSR, err: %v", err)
+ return nil, nil, "", fmt.Errorf("failed to send CSR, err: %w", err)
}
requestedCertURLPath, _ := ncmapi.GetPathFromCertHref(csrResp.Href)
csrStatusResp, err := p.NCMClient.CheckCSRStatus(requestedCertURLPath)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed checking CSR status in NCM, its href: %s, err: %v", csrResp.Href, err)
+ return nil, nil, "", fmt.Errorf("failed checking CSR status in NCM, its href: %s, err: %w", csrResp.Href, err)
}
if status := csrStatusResp.Status; status == CSRStatusRejected {
@@ -190,9 +194,9 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
}
leafCertURLPath, _ := ncmapi.GetPathFromCertHref(csrStatusResp.Certificate)
- leafCertInPEM, _ := p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
+ leafCertInPEM, err := p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s, err: %v", csrStatusResp.Certificate, err)
+ return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s, err: %w", csrStatusResp.Certificate, err)
}
ca, tls := p.prepareCAAndTLS(wantedCA, leafCertInPEM, certChain)
@@ -220,13 +224,13 @@ func (p *Provisioner) Renew(cr *cmapi.CertificateRequest, certID string) ([]byte
certURLPath, _ := ncmapi.GetPathFromCertHref(certID)
renewCertResp, err := p.NCMClient.RenewCertificate(certURLPath, cr.Spec.Duration, p.NCMConfig.ProfileID)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed to renew certificate, its href: %s, err: %v", certID, err)
+ return nil, nil, "", fmt.Errorf("failed to renew certificate, its href: %s, err: %w", certID, err)
}
renewedCertURLPath, _ := ncmapi.GetPathFromCertHref(renewCertResp.Certificate)
leafCertInPEM, err := p.NCMClient.DownloadCertificateInPEM(renewedCertURLPath)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed to download renewed certificate in PEM, its href: %s, err: %v", renewCertResp.Certificate, err)
+ return nil, nil, "", fmt.Errorf("failed to download renewed certificate in PEM, its href: %s, err: %w", renewCertResp.Certificate, err)
}
ca, tls := p.prepareCAAndTLS(wantedCA, leafCertInPEM, certChain)
@@ -248,7 +252,7 @@ func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte,
lastCheckedCAURLPath, _ := ncmapi.GetPathFromCertHref(lastCheckedCA.Certificates["active"])
currentCACert, err := p.NCMClient.DownloadCertificate(lastCheckedCAURLPath)
if err != nil {
- return nil, nil, fmt.Errorf("failed to download CA certificate, its href: %s, err: %v", lastCheckedCA.Certificates["active"], err)
+ return nil, nil, fmt.Errorf("failed to download CA certificate, its href: %s, err: %w", lastCheckedCA.Certificates["active"], err)
}
if isRootCA(lastCheckedCA, currentCACert) {
@@ -257,14 +261,14 @@ func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte,
currentCACertInPEM, err := p.NCMClient.DownloadCertificateInPEM(lastCheckedCAURLPath)
if err != nil {
- return nil, nil, fmt.Errorf("failed to download CA certificate in PEM, its href: %s, err: %v", lastCheckedCA.Certificates["active"], err)
+ return nil, nil, fmt.Errorf("failed to download CA certificate in PEM, its href: %s, err: %w", lastCheckedCA.Certificates["active"], err)
}
certChain = addCertToChain(currentCACertInPEM, certChain, p.NCMConfig.LittleEndian)
lastCheckedCAURLPath, _ = ncmapi.GetPathFromCertHref(currentCACert.IssuerCA)
lastCheckedCA, err = p.NCMClient.GetCA(lastCheckedCAURLPath)
if err != nil {
- return nil, nil, fmt.Errorf("failed to get CA certificate, its href: %s, err: %v", currentCACert.IssuerCA, err)
+ return nil, nil, fmt.Errorf("failed to get CA certificate, its href: %s, err: %w", currentCACert.IssuerCA, err)
}
}
@@ -273,7 +277,7 @@ func (p *Provisioner) getChainAndWantedCA(signingCA *ncmapi.CAResponse) ([]byte,
wantedCAURLPath, _ := ncmapi.GetPathFromCertHref(wantedCA.Certificates["active"])
wantedCAInPEM, err := p.NCMClient.DownloadCertificateInPEM(wantedCAURLPath)
if err != nil {
- return nil, nil, fmt.Errorf("failed to download signing (root) CA in PEM, its href: %s, err: %v", wantedCA.Certificates["active"], err)
+ return nil, nil, fmt.Errorf("failed to download signing (root) CA in PEM, its href: %s, err: %w", wantedCA.Certificates["active"], err)
}
return certChain, wantedCAInPEM, nil
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index c0a003a..55cd737 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -219,9 +219,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
interCA := []byte("-----BEGIN CERTIFICATE-----\n1NT3RC4...\n-----END CERTIFICATE-----\n")
signingCA := []byte("-----BEGIN CERTIFICATE-----\n1SSU1NGC4...\n-----END CERTIFICATE-----\n")
leafCert := []byte("-----BEGIN CERTIFICATE-----\nL34FC4RT...\n-----END CERTIFICATE-----\n")
-
run := func(t *testing.T, tc testCase) {
-
p, _ := NewProvisioner(tc.config, testr.New(t))
ca, tls := p.prepareCAAndTLS(rootCA, leafCert, func() []byte {
if tc.config.LittleEndian {
@@ -524,7 +522,6 @@ func TestSign(t *testing.T) {
run(t, tc)
})
}
-
}
func TestHandlingCSR(t *testing.T) {
@@ -847,5 +844,4 @@ func TestRenew(t *testing.T) {
run(t, tc)
})
}
-
}
diff --git a/pkg/provisioner/pendingcsr.go b/pkg/provisioner/pendingcsr.go
index 8917a4e..e69f715 100644
--- a/pkg/provisioner/pendingcsr.go
+++ b/pkg/provisioner/pendingcsr.go
@@ -41,7 +41,7 @@ func (cm *PendingCSRsMap) Get(namespace, certName string) *PendingCSR {
cm.mu.RLock()
defer cm.mu.RUnlock()
- pendingCSR, _ := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ pendingCSR := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
return pendingCSR
}
@@ -49,15 +49,15 @@ func (cm *PendingCSRsMap) Increment(namespace, certName string) {
cm.mu.Lock()
defer cm.mu.Unlock()
- pendingCSR, _ := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
- pendingCSR.checked += 1
+ pendingCSR := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ pendingCSR.checked++
}
func (cm *PendingCSRsMap) ResetCheckCounter(namespace, certName string) {
cm.mu.Lock()
defer cm.mu.Unlock()
- pendingCSR, _ := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
+ pendingCSR := cm.pendingCSRs[prepareCSRsMapKey(namespace, certName)]
pendingCSR.checked = 1
}
diff --git a/pkg/provisioner/util.go b/pkg/provisioner/util.go
index bb06a1c..21241eb 100644
--- a/pkg/provisioner/util.go
+++ b/pkg/provisioner/util.go
@@ -8,16 +8,16 @@ import (
"github.com/nokia/ncm-issuer/pkg/ncmapi"
)
-func findCA(casResponse *ncmapi.CAsResponse, CAsHref, CAsName string) (*ncmapi.CAResponse, bool) {
+func findCA(casResponse *ncmapi.CAsResponse, casHref, casName string) (*ncmapi.CAResponse, bool) {
hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
for _, ca := range casResponse.CAList {
if strings.EqualFold(ca.Status, "active") {
- if CAsHref != "" {
+ if casHref != "" {
href := hrefRegex.Find([]byte(ca.Href))
- if string(href) == CAsHref {
+ if string(href) == casHref {
return &ca, true
}
- } else if ca.Name == CAsName {
+ } else if ca.Name == casName {
return &ca, true
}
}
diff --git a/pkg/util/csr.go b/pkg/util/csr.go
deleted file mode 100644
index 837cda4..0000000
--- a/pkg/util/csr.go
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package util
-
-import (
- "crypto/rand"
- "crypto/x509"
- "encoding/pem"
- "fmt"
- "math/big"
- "time"
-
- cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
-)
-
-var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
-
-// GenerateTemplate will create a x509.Certificate for the given
-// CertificateRequest resource
-func GenerateTemplateFromCertificateRequest(cr *cmapi.CertificateRequest) (*x509.Certificate, error) {
- block, _ := pem.Decode(cr.Spec.Request)
- if block == nil {
- return nil, fmt.Errorf("failed to decode csr from certificate request resource %s/%s",
- cr.Namespace, cr.Name)
- }
-
- csr, err := x509.ParseCertificateRequest(block.Bytes)
- if err != nil {
- return nil, err
- }
-
- if err := csr.CheckSignature(); err != nil {
- return nil, err
- }
-
- serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
- if err != nil {
- return nil, fmt.Errorf("failed to generate serial number: %s", err.Error())
- }
-
- certDuration := cmapi.DefaultCertificateDuration
- if cr.Spec.Duration != nil {
- certDuration = cr.Spec.Duration.Duration
- }
-
- return &x509.Certificate{
- Version: csr.Version,
- BasicConstraintsValid: true,
- SerialNumber: serialNumber,
- PublicKeyAlgorithm: csr.PublicKeyAlgorithm,
- PublicKey: csr.PublicKey,
- IsCA: cr.Spec.IsCA,
- Subject: csr.Subject,
- NotBefore: time.Now(),
- NotAfter: time.Now().Add(certDuration),
- // see http://golang.org/pkg/crypto/x509/#KeyUsage
- KeyUsage: keyUsage(cr.Spec.IsCA),
- DNSNames: csr.DNSNames,
- IPAddresses: csr.IPAddresses,
- URIs: csr.URIs,
- }, nil
-}
-
-func keyUsage(isCA bool) x509.KeyUsage {
- keyUsages := x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
- if isCA {
- keyUsages |= x509.KeyUsageCertSign
- }
-
- return keyUsages
-}
diff --git a/pkg/util/decode.go b/pkg/util/decode.go
index 2454b24..57b4aaf 100644
--- a/pkg/util/decode.go
+++ b/pkg/util/decode.go
@@ -17,95 +17,11 @@ limitations under the License.
package util
import (
- "crypto"
"crypto/x509"
"encoding/pem"
- "errors"
"fmt"
)
-// DecodePrivateKeyBytes will decode a PEM encoded private key into a crypto.Signer.
-// It supports ECDSA and RSA private keys only. All other types will return err.
-func DecodePrivateKeyBytes(keyBytes []byte) (crypto.Signer, error) {
- // decode the private key pem
- block, _ := pem.Decode(keyBytes)
- if block == nil {
- return nil, errors.New("error decoding private key PEM block")
- }
-
- switch block.Type {
- case "PRIVATE KEY":
- key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("error parsing pkcs#8 private key: %s", err.Error())
- }
-
- signer, ok := key.(crypto.Signer)
- if !ok {
- return nil, errors.New("error parsing pkcs#8 private key: invalid key type")
- }
- return signer, nil
- case "EC PRIVATE KEY":
- key, err := x509.ParseECPrivateKey(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("error parsing ecdsa private key: %s", err.Error())
- }
-
- return key, nil
- case "RSA PRIVATE KEY":
- key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("error parsing rsa private key: %s", err.Error())
- }
-
- err = key.Validate()
- if err != nil {
- return nil, fmt.Errorf("rsa private key failed validation: %s", err.Error())
- }
- return key, nil
- default:
- return nil, fmt.Errorf("unknown private key type: %s", block.Type)
- }
-}
-
-// DecodeX509CertificateChainBytes will decode a PEM encoded x509 Certificate chain.
-func DecodeX509CertificateChainBytes(certBytes []byte) ([]*x509.Certificate, error) {
- certs := []*x509.Certificate{}
-
- var block *pem.Block
-
- for {
- // decode the tls certificate pem
- block, certBytes = pem.Decode(certBytes)
- if block == nil {
- break
- }
-
- // parse the tls certificate
- cert, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("error parsing TLS certificate: %s", err.Error())
- }
- certs = append(certs, cert)
- }
-
- if len(certs) == 0 {
- return nil, errors.New("error decoding cert PEM block")
- }
-
- return certs, nil
-}
-
-// DecodeX509CertificateBytes will decode a PEM encoded x509 Certificate.
-func DecodeX509CertificateBytes(certBytes []byte) (*x509.Certificate, error) {
- certs, err := DecodeX509CertificateChainBytes(certBytes)
- if err != nil {
- return nil, err
- }
-
- return certs[0], nil
-}
-
// DecodeX509CertificateRequestBytes will decode a PEM encoded x509 Certificate Request.
func DecodeX509CertificateRequestBytes(csrBytes []byte) (*x509.CertificateRequest, error) {
block, _ := pem.Decode(csrBytes)
diff --git a/pkg/util/file.go b/pkg/util/file.go
index d8015dc..5eecdbf 100644
--- a/pkg/util/file.go
+++ b/pkg/util/file.go
@@ -14,7 +14,7 @@ func WritePEMToTempFile(pem []byte) (string, error) {
defer csrFile.Close()
path := csrFile.Name()
- if _, err := csrFile.Write(pem); err != nil {
+ if _, err = csrFile.Write(pem); err != nil {
return path, err
}
diff --git a/pkg/util/validate.go b/pkg/util/validate.go
deleted file mode 100644
index 6dbc1af..0000000
--- a/pkg/util/validate.go
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package util
-
-import (
- "crypto"
- "crypto/ecdsa"
- "crypto/rsa"
- "crypto/x509"
- "fmt"
-)
-
-// PublicKeyMatchesCertificate can be used to verify the given public key
-// is the correct counter-part to the given x509 Certificate.
-// It will return false and no error if the public key is *not* valid for the
-// given Certificate.
-// It will return true if the public key *is* valid for the given Certificate.
-// It will return an error if either of the passed parameters are of an
-// unrecognised type (i.e. non RSA/ECDSA)
-func PublicKeyMatchesCertificate(check crypto.PublicKey, crt *x509.Certificate) (bool, error) {
- switch pub := crt.PublicKey.(type) {
- case *rsa.PublicKey:
- rsaCheck, ok := check.(*rsa.PublicKey)
- if !ok {
- return false, nil
- }
- if pub.N.Cmp(rsaCheck.N) != 0 {
- return false, nil
- }
- return true, nil
- case *ecdsa.PublicKey:
- ecdsaCheck, ok := check.(*ecdsa.PublicKey)
- if !ok {
- return false, nil
- }
- if pub.X.Cmp(ecdsaCheck.X) != 0 || pub.Y.Cmp(ecdsaCheck.Y) != 0 {
- return false, nil
- }
- return true, nil
- default:
- return false, fmt.Errorf("unrecognised Certificate public key type")
- }
-}
-
-func CertificateHasKeyUsage(cert *x509.Certificate, usage x509.KeyUsage) bool {
- if cert.KeyUsage != 0 && cert.KeyUsage&usage != 0 {
- return true
- }
- return false
-}
diff --git a/test/unit/gen/ncmapi.go b/test/unit/gen/ncmapi.go
index 919acdb..ff253a6 100644
--- a/test/unit/gen/ncmapi.go
+++ b/test/unit/gen/ncmapi.go
@@ -149,7 +149,6 @@ func NoErrorFakeClientDownloadCertificateInPEM() func(*FakeClient) {
return []byte(fmt.Sprintf("-----BEGIN CERTIFICATE-----\n%s...\n-----END CERTIFICATE-----\n", crtIdentifier)), nil
}
}
-
}
func SetFakeClientDownloadCertificateInPEMError(err error) func(*FakeClient) {
From d6934a43b900cd6112b006b9aca63b7a3fe5fd27 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 1 Apr 2023 22:35:50 +0200
Subject: [PATCH 079/175] Bumped golangci-lint version in workflow
---
.github/workflows/tests.yml | 2 +-
.golangci.yml | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 4ece053..64b7693 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -69,7 +69,7 @@ jobs:
- name: "golangci-lint"
uses: golangci/golangci-lint-action@v3
with:
- version: v1.29
+ version: v1.52.2
only-new-issues: true
build:
diff --git a/.golangci.yml b/.golangci.yml
index 636821e..9a54d31 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -2,9 +2,11 @@ run:
timeout: 5m
skip-dirs:
- .git
+ - .github
+ - api
- config
- hack
- - api
+ - helm
linters-settings:
dupl:
From 4d177ccee985537db79bafd400a3e285dbf3b2a5 Mon Sep 17 00:00:00 2001
From: raczu
Date: Sat, 1 Apr 2023 22:38:18 +0200
Subject: [PATCH 080/175] Fixed wrong error-wrapping directive
---
pkg/ncmapi/ncmapi.go | 2 +-
pkg/provisioner/ncm.go | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index c07eda0..90f5a1a 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -63,7 +63,7 @@ type ClientError struct {
}
func (c *ClientError) Error() string {
- return fmt.Sprintf("NCM API Client Error reason: %s, err: %w", c.Reason, c.ErrorMessage)
+ return fmt.Sprintf("NCM API Client Error reason: %s, err: %v", c.Reason, c.ErrorMessage)
}
type CAsResponse struct {
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
index 8f425b5..72bf89a 100644
--- a/pkg/provisioner/ncm.go
+++ b/pkg/provisioner/ncm.go
@@ -131,8 +131,7 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
leafCertURLPath, _ := ncmapi.GetPathFromCertHref(csrStatusResp.Certificate)
leafCertInPEM, err = p.NCMClient.DownloadCertificateInPEM(leafCertURLPath)
if err != nil {
- return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s,"+
- " err: %w", csrStatusResp.Certificate, err)
+ return nil, nil, "", fmt.Errorf("failed to download end-entity certificate in PEM, its href: %s, err: %w", csrStatusResp.Certificate, err)
}
p.pendingCSRs.Delete(cr.Namespace, cr.Annotations[cmapi.CertificateNameKey])
From f032c2cd582863c6bf2f619aaba933749111113d Mon Sep 17 00:00:00 2001
From: raczu
Date: Sun, 2 Apr 2023 13:27:42 +0200
Subject: [PATCH 081/175] Removed unused things in Makefile & added few new
---
.github/workflows/tests.yml | 20 +----
Makefile | 152 +++++++++++++-----------------------
pkg/ncmapi/ncmapi_test.go | 67 ++++++++--------
pkg/provisioner/ncm_test.go | 6 ++
4 files changed, 97 insertions(+), 148 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 64b7693..a9a9817 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -35,21 +35,7 @@ jobs:
run: go get .
- name: "test with go"
- run: go test ./... -json > unit-test-results-${{ matrix.go-version }}.json
-
- - name: "[ * ] collecting unit test results"
- if: ${{ failure() }}
- run: |
- mkdir -p ${{ github.workspace }}/artifact/upload
- sudo cp -rp *.json ${{ github.workspace }}/artifact/data/
- sudo tar -C ${{ github.workspace }}/artifact/ -czf ${{ github.workspace }}/artifact/upload/artifact.tar.gz
-
- - name: "[ * ] uploading artifacts"
- uses: actions/upload-artifact@v3
- if: ${{ failure() }}
- with:
- name: unit-test-results-${{ matrix.go-version }}.tar.gz
- path: ${{ github.workspace }}/artifact/upload/
+ run: make test
golangci:
name: "lint"
@@ -88,6 +74,4 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: "build ncm-issuer"
- run: |
- go mod vendor
- CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go
+ run: make build
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 48f7d34..a25e72a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,26 +1,9 @@
-# Add proxy
-export GOFLAGS=-mod=vendor
-export GO111MODULE=on
-
-BUILD_VERSION ?= 1.0.1
-IMG_NAME ?= ncm-issuer
-
-# Image URL to use all building/pushing image targets
-IMG ?= ncm-issuer:${BUILD_VERSION}
-# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
-CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false"
-
APP_NAME ?= ncm-issuer
-APP_VERSION ?= 1.0.2
-
-# DevOPS Artifactory Repositories
-ARTIFACTORY_URL ?= repo.lab.pl.alcatel-lucent.com
-
-CSF_DOCKER_CANDIDATES ?= csf-docker-candidates.${ARTIFACTORY_URL}
-CSF_DOCKER_INPROGRESS ?= csf-docker-inprogress.${ARTIFACTORY_URL}
-
-NEO_CANDIDATES_REPO ?= neo-docker-candidates.${ARTIFACTORY_URL}
+APP_VERSION ?= 1.0.4
+BUILD_VERSION ?= 1.1.0
+IMG ?= ${APP_NAME}:${BUILD_VERSION}
+ENVTEST_K8S_VERSION ?= 1.22
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
@@ -56,10 +39,10 @@ help: ## Display this help.
##@ Development
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
- $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
+ $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./pkg/controllers/..." paths="./api/..." output:crd:artifacts:config=config/crd/bases
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
- $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
+ $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..."
fmt: ## Run go fmt against code.
go fmt ./...
@@ -67,17 +50,18 @@ fmt: ## Run go fmt against code.
vet: ## Run go vet against code.
go vet ./...
-ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
-test: manifests generate fmt vet ## Run tests.
- mkdir -p ${ENVTEST_ASSETS_DIR}
- ${PROXY} test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.3/hack/setup-envtest.sh
- ${PROXY} source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out
+vendor:
+ go mod tidy
+ go mod vendor
+ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
+test: manifests generate fmt vet envtest ## Run tests.
+ KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out -v
##@ Build
-build: generate fmt vet ## Build manager binary.
- go build -o bin/manager main.go
+build: vendor generate fmt vet ## Build manager binary.
+ go build -mod=vendor -o bin/manager main.go
run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go
@@ -85,32 +69,12 @@ run: manifests generate fmt vet ## Run a controller from your host.
docker-push: ## Push docker image with the manager.
docker push ${IMG}
-# Build the docker image
-docker-build: docker_build_img docker-tag
-
-docker_build_img:
+docker-build:
docker build . -t ${IMG}
-# docker tag
-docker-tag:
- > inprogressPushList
- # tag for both inprogress and candidates so both can be pushed
- docker tag ${IMG} ${CSF_DOCKER_INPROGRESS}/${IMG}
- docker tag ${IMG} ${CSF_DOCKER_CANDIDATES}/${IMG}
- docker tag ${IMG} ${CSF_DOCKER_CANDIDATES}/${IMG_NAME}:latest
- # save the image name:tag so Jenkins can retrieve it later
- echo ${CSF_DOCKER_INPROGRESS}/${IMG} >>inprogressPushList
- echo ${CSF_DOCKER_CANDIDATES}/${IMG} >>inprogressPushList
- echo ${CSF_DOCKER_CANDIDATES}/${IMG_NAME}:latest >>inprogressPushList
- cat inprogressPushList
- docker images |grep ${IMG_NAME}
-
-# save the built docker image
-#
-#save: docker_build_img
-save:
- rm -rf builds/$(APP_NAME)-images && mkdir -p builds/$(APP_NAME)-images
- docker save ${IMG} | gzip > builds/$(APP_NAME)-images/${IMG}.tgz
+docker-save: docker-build
+ rm -rf builds/$(APP_NAME)-images && mkdir -p builds/$(APP_NAME)-images
+ docker save ${IMG} | gzip > builds/$(APP_NAME)-images/${IMG}.tgz
##@ Deployment
@@ -127,50 +91,42 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/default | kubectl delete -f -
-
-CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
-controller-gen: ## Download controller-gen locally if necessary.
- ${PROXY} $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1)
-
-KUSTOMIZE = $(shell pwd)/bin/kustomize
-kustomize: ## Download kustomize locally if necessary.
- ${PROXY} $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)
-
-# go-get-tool will 'go get' any package $2 and install it to $1.
-PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
-define go-get-tool
-[ -f $(1) ] || { \
-set -e ;\
-TMP_DIR=$$(mktemp -d) ;\
-cd $$TMP_DIR ;\
-go mod init tmp ;\
-echo "Downloading $(2)" ;\
-GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\
-rm -rf $$TMP_DIR ;\
-}
-endef
-
-# create helm package
-helm-create:
- rm -rf builds/helm && mkdir -p builds/helm
- cp -r helm builds/helm/$(APP_NAME)
- cp helm/README.md builds/helm/$(APP_NAME)
- helmValidationAndPackage.sh --helmtarget builds
-
-# create BCMT APP2.0 package
-#
-# after the step: Build and Publish docker images
-#
-ncmapp-create: save
- rm -rf builds/$(APP_NAME) && mkdir -p builds/$(APP_NAME)
- cp -rf app2.0/* builds/$(APP_NAME)
- # some update on the new built
- sed -i '3s|version: 0.1.0|version: $(BUILD_VERSION)|' builds/$(APP_NAME)/profile/app_list.yaml
- mkdir -p builds/$(APP_NAME)/images builds/$(APP_NAME)/charts
- cp -rf builds/$(APP_NAME)-images/*.tgz builds/$(APP_NAME)/images/
- cp -rf builds/helm/$(APP_NAME)-$(BUILD_VERSION).tgz builds/$(APP_NAME)/charts/
- # tar ball
- cd builds && tar czvf ../${APP_NAME}-${APP_VERSION}.tgz $(APP_NAME)
+##@ Build dependencies
+
+## Location to install dependecies to
+LOCALBIN ?= $(shell pwd)/bin
+$(LOCALBIN):
+ mkdir -p $(LOCALBIN)
+
+## Tool Binaries
+KUSTOMIZE ?= $(LOCALBIN)/kustomize
+CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
+ENVTEST ?= $(LOCALBIN)/setup-envtest
+
+## Tool Versions
+KUSTOMIZE_VERSION ?= v3.8.7
+CONTROLLER_TOOLS_VERSION ?= v0.8.0
+
+KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
+kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
+$(KUSTOMIZE): $(LOCALBIN)
+ curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
+
+controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
+$(CONTROLLER_GEN): $(LOCALBIN)
+ GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
+
+envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
+$(ENVTEST): $(LOCALBIN)
+ GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
+
+pack-app: docker-save
+ rm -rf builds/$(APP_NAME) && mkdir -p builds/$(APP_NAME)/
+ mkdir -p builds/$(APP_NAME)/images builds/$(APP_NAME)/charts/$(APP_NAME)/
+ cp -rf builds/$(APP_NAME)-images/*.tgz builds/$(APP_NAME)/images/
+ cp -rf helm/* builds/$(APP_NAME)/charts/$(APP_NAME)/
+ cp -rf release_notes.txt builds/$(APP_NAME)/
+ cd builds && tar czvf ../${APP_NAME}-${APP_VERSION}-${BUILD_VERSION}.tgz $(APP_NAME)
clean:
rm -rf builds
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 09a7e33..47ceb98 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -91,9 +91,7 @@ func TestNewClientCreation(t *testing.T) {
CACertPool := x509.NewCertPool()
CACertPool.AppendCertsFromPEM([]byte(rootCA))
- dir := os.TempDir()
- defer os.RemoveAll(dir)
-
+ dir := t.TempDir()
certFile, err := os.CreateTemp(dir, "ncm-testing-cert.pem")
if err != nil {
t.Fatalf(err.Error())
@@ -250,6 +248,7 @@ func TestNewClientCreation(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -292,6 +291,7 @@ func TestNewRequestCreation(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -372,6 +372,7 @@ func TestValidateResponse(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -457,6 +458,7 @@ func TestGetCAs(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -542,38 +544,39 @@ func TestGetCA(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
}
}
-func TestSendCSR(t *testing.T) {
- type testCase struct {
- name string
- }
-}
-
-func TestCheckCSRStatus(t *testing.T) {
- type testCase struct {
- name string
- }
-}
-
-func TestDownloadCertificate(t *testing.T) {
- type testCase struct {
- name string
- }
-}
-
-func TestDownloadCertificateInPEM(t *testing.T) {
- type testCase struct {
- name string
- }
-}
-
-func TestRenewCertificate(t *testing.T) {
- type testCase struct {
- name string
- }
-}
+//func TestSendCSR(t *testing.T) {
+// type testCase struct {
+// name string
+// }
+//}
+//
+//func TestCheckCSRStatus(t *testing.T) {
+// type testCase struct {
+// name string
+// }
+//}
+//
+//func TestDownloadCertificate(t *testing.T) {
+// type testCase struct {
+// name string
+// }
+//}
+//
+//func TestDownloadCertificateInPEM(t *testing.T) {
+// type testCase struct {
+// name string
+// }
+//}
+//
+//func TestRenewCertificate(t *testing.T) {
+// type testCase struct {
+// name string
+// }
+//}
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index 55cd737..a6e1cab 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -126,6 +126,7 @@ func TestFindCA(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -201,6 +202,7 @@ func TestGetChainAndWantedCA(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -289,6 +291,7 @@ func TestPreparingCAAndTLS(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -518,6 +521,7 @@ func TestSign(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -737,6 +741,7 @@ func TestHandlingCSR(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
@@ -840,6 +845,7 @@ func TestRenew(t *testing.T) {
}
for _, tc := range testCases {
+ tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
From 0d1641e4110f6f22672d83103b2d0a0e8f0317c5 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 16:49:44 +0200
Subject: [PATCH 082/175] Added uploading image to local registry
---
.github/workflows/cahref-test.yml | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index fe279dd..2d62b86 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -1,4 +1,4 @@
-name: caname-href tests
+name: ca name and href tests
on:
push:
@@ -19,11 +19,8 @@ jobs:
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
- run: |
- go mod vendor
- make docker_build_img
- make save
+ - name: "build ncm-issuer image"
+ run: make docker-build
- name: "install microk8s"
run: |
@@ -31,9 +28,15 @@ jobs:
sudo microk8s status --wait-ready
sudo microk8s enable helm3
sudo microk8s enable dns
+ sudo microk8s enable registry
echo K8S_VERSION=$(sudo microk8s.kubectl version --short=true|grep -Po 'Server Version: \K.*' -m 1) >> $GITHUB_ENV
- run: echo "k8s ${{ env.K8S_VERSION }}"
+ - name: "upload ncm-issuer image to local registry"
+ run: |
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
+
+
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
@@ -61,6 +64,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s/docker.io/misiektoja/localhost:32000/g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From f224823f6aa1629677b922c45029eda5fc28ee6e Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 17:10:13 +0200
Subject: [PATCH 083/175] Fixed error related to missing vendor
---
.github/workflows/cahref-test.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 2d62b86..01054bd 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -20,7 +20,9 @@ jobs:
- run: go version
- name: "build ncm-issuer image"
- run: make docker-build
+ run: |
+ make vendor
+ make docker-build
- name: "install microk8s"
run: |
From c4b2e4021cbf82ff151ad2581b690771ddd96e86 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 17:13:42 +0200
Subject: [PATCH 084/175] Removed go tidy from Makefile
---
Makefile | 1 -
1 file changed, 1 deletion(-)
diff --git a/Makefile b/Makefile
index a25e72a..a3ab653 100644
--- a/Makefile
+++ b/Makefile
@@ -51,7 +51,6 @@ vet: ## Run go vet against code.
go vet ./...
vendor:
- go mod tidy
go mod vendor
ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
From c548764c2b84d1d096be0737732c142c22c0101b Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 17:29:16 +0200
Subject: [PATCH 085/175] Changed localhost to numerical value
---
.github/workflows/cahref-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 01054bd..df170fe 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,7 +36,7 @@ jobs:
- name: "upload ncm-issuer image to local registry"
run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V 127.0.0.1:32000/V;docker push 127.0.0.1:32000/V'
- name: "install cert-manager charts"
From aedf531a0f4155ab0569f85f4c459941e3497f18 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 17:36:30 +0200
Subject: [PATCH 086/175] Added insecure-registiers to docker
---
.github/workflows/cahref-test.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index df170fe..530457f 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,6 +36,7 @@ jobs:
- name: "upload ncm-issuer image to local registry"
run: |
+ echo '{"insecure-registries" : ["127.0.0.1:32000"]}' >> /etc/docker/daemon.json
docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V 127.0.0.1:32000/V;docker push 127.0.0.1:32000/V'
@@ -66,7 +67,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s/docker.io/misiektoja/localhost:32000/g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|127.0.0.1:32000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From 726cec34b1913bf16d3dbe6aad7fd9d648550842 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 17:49:48 +0200
Subject: [PATCH 087/175] Added sudo for writing to docker file
---
.github/workflows/cahref-test.yml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 530457f..a1ca966 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -34,9 +34,12 @@ jobs:
echo K8S_VERSION=$(sudo microk8s.kubectl version --short=true|grep -Po 'Server Version: \K.*' -m 1) >> $GITHUB_ENV
- run: echo "k8s ${{ env.K8S_VERSION }}"
- - name: "upload ncm-issuer image to local registry"
+ - name: "push ncm-issuer image to local registry"
run: |
- echo '{"insecure-registries" : ["127.0.0.1:32000"]}' >> /etc/docker/daemon.json
+ sudo systemctl stop docker
+ sudo sh -c "echo '{\"insecure-registries\" : [\"127.0.0.1:32000\"]}' >> /etc/docker/daemon.json"
+ cat /etc/docker/daemon.json
+ sudo systemctl start docker
docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V 127.0.0.1:32000/V;docker push 127.0.0.1:32000/V'
From 5dc0f74bde17aa2af2e252875cfba3eea6d404ab Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 18:11:42 +0200
Subject: [PATCH 088/175] Added sleep to allow docker to restart
---
.github/workflows/cahref-test.yml | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index a1ca966..6e3d76d 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -34,12 +34,19 @@ jobs:
echo K8S_VERSION=$(sudo microk8s.kubectl version --short=true|grep -Po 'Server Version: \K.*' -m 1) >> $GITHUB_ENV
- run: echo "k8s ${{ env.K8S_VERSION }}"
+ - name: "inject insecure-registry to docker"
+ run: |
+ OPTIONS=$(cat /etc/docker/daemon.json)
+ sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"127.0.0.1:32000\"] }' > /etc/docker/daemon.json"
+ sudo systemctl restart docker
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
- name: "push ncm-issuer image to local registry"
run: |
- sudo systemctl stop docker
- sudo sh -c "echo '{\"insecure-registries\" : [\"127.0.0.1:32000\"]}' >> /etc/docker/daemon.json"
- cat /etc/docker/daemon.json
- sudo systemctl start docker
docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V 127.0.0.1:32000/V;docker push 127.0.0.1:32000/V'
From d2ebf6efa48d4beb4d7026fa4b5e8d14cfe81d4b Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 18:20:41 +0200
Subject: [PATCH 089/175] Added more outputs for debugging
---
.github/workflows/cahref-test.yml | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 6e3d76d..892a045 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -37,8 +37,11 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
OPTIONS=$(cat /etc/docker/daemon.json)
- sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"127.0.0.1:32000\"] }' > /etc/docker/daemon.json"
+ sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
+ cat /var/snap/microk8s/current/args/containerd-template.toml | grep endpoint
+ microk8s.kubectl get pods -A
+ wget http://localhost:32000/
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
@@ -47,7 +50,7 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V 127.0.0.1:32000/V;docker push 127.0.0.1:32000/V'
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
- name: "install cert-manager charts"
@@ -77,7 +80,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|127.0.0.1:32000|g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|localhost:32000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From 3d2d7099fc52af6e4dda6edd00f0357d2fa3995b Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 18:27:15 +0200
Subject: [PATCH 090/175] Moved outputs to different stage
---
.github/workflows/cahref-test.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 892a045..6d6ba03 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -39,9 +39,6 @@ jobs:
OPTIONS=$(cat /etc/docker/daemon.json)
sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
- cat /var/snap/microk8s/current/args/containerd-template.toml | grep endpoint
- microk8s.kubectl get pods -A
- wget http://localhost:32000/
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
@@ -50,6 +47,9 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
+ microk8s.kubectl get pods -A
+ wget http://localhost:32000/
+ sudo cat /var/snap/microk8s/current/args/containerd-template.toml | grep endpoint
docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
From a94253e0c61d017427acbab5dc02a0538b6ce8cc Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 18:35:12 +0200
Subject: [PATCH 091/175] Removed invalid command
---
.github/workflows/cahref-test.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 6d6ba03..e75d45a 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -47,7 +47,6 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- microk8s.kubectl get pods -A
wget http://localhost:32000/
sudo cat /var/snap/microk8s/current/args/containerd-template.toml | grep endpoint
docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
From 946144e062095acc34cf11a524d7fb3daa272950 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 18:44:03 +0200
Subject: [PATCH 092/175] Added saving registry address to env variable
---
.github/workflows/cahref-test.yml | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index e75d45a..c9299c1 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,8 +36,9 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
+ REG_ADDR=$(sudo microk8s get services | grep -i container-registry | awk '{print $4}')
OPTIONS=$(cat /etc/docker/daemon.json)
- sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
+ sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"${REG_ADDR}\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
- name: "sleep for 10s"
@@ -47,9 +48,7 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- wget http://localhost:32000/
- sudo cat /var/snap/microk8s/current/args/containerd-template.toml | grep endpoint
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V ${REG_ADDR}/V;docker push ${REG_ADDR}/V'
- name: "install cert-manager charts"
From c7e743af076b14cf2454612d3e7efaf28e152feb Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 19:17:11 +0200
Subject: [PATCH 093/175] Fixed saving registry to env variable
---
.github/workflows/cahref-test.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index c9299c1..b29e7f1 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,7 +36,7 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- REG_ADDR=$(sudo microk8s get services | grep -i container-registry | awk '{print $4}')
+ REG_ADDR=$(sudo microk8s kubectl get services -A | grep -i container-registry | awk '{print $4}')
OPTIONS=$(cat /etc/docker/daemon.json)
sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"${REG_ADDR}\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
@@ -48,7 +48,7 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V ${REG_ADDR}/V;docker push ${REG_ADDR}/V'
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V $REG_ADDR:32000/V;docker push $REG_ADDR:32000/V'
- name: "install cert-manager charts"
@@ -78,7 +78,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|localhost:32000|g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|${REG_ADDR}:32000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From d7a8f385cd194a57f903793d62226126f43e3dc8 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 19:28:08 +0200
Subject: [PATCH 094/175] Added saving variables to gh env
---
.github/workflows/cahref-test.yml | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index b29e7f1..5f9f15d 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,9 +36,10 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- REG_ADDR=$(sudo microk8s kubectl get services -A | grep -i container-registry | awk '{print $4}')
- OPTIONS=$(cat /etc/docker/daemon.json)
- sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"${REG_ADDR}\"] }' > /etc/docker/daemon.json"
+ echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}') >> $GITHUB_ENV
+ echo OPTIONS=$(cat /etc/docker/daemon.json) >> $GITHUB_ENV
+ sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"${{ env.REG_ADDR }}:32000\"] }' > /etc/docker/daemon.json"
+ cat /etc/docker/daemon.json
sudo systemctl restart docker
- name: "sleep for 10s"
@@ -48,7 +49,7 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V $REG_ADDR:32000/V;docker push $REG_ADDR:32000/V'
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V ${{ env.REG_ADDR }}:32000/V;docker push ${{ env.REG_ADDR }}:32000/V'
- name: "install cert-manager charts"
@@ -78,7 +79,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|${REG_ADDR}:32000|g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|${{ env.REG_ADDR }}:32000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From 0f902418f9a8da5ec8ed03ce25b1bd6cd2fde4bb Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 19:41:59 +0200
Subject: [PATCH 095/175] Changed way of inserting variables
---
.github/workflows/cahref-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 5f9f15d..af6e9a0 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -38,7 +38,7 @@ jobs:
run: |
echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}') >> $GITHUB_ENV
echo OPTIONS=$(cat /etc/docker/daemon.json) >> $GITHUB_ENV
- sudo sh -c "echo '{${OPTIONS:1: -2}, \"insecure-registries\": [\"${{ env.REG_ADDR }}:32000\"] }' > /etc/docker/daemon.json"
+ sudo sh -c "echo '{ ${{ env.OPTIONS:1: -2 }}, \"insecure-registries\": [\"${{ env.REG_ADDR }}:32000\"] }' > /etc/docker/daemon.json"
cat /etc/docker/daemon.json
sudo systemctl restart docker
From 0e00c07df66b8d00a80b02524e3aca8a54af601f Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 19:44:19 +0200
Subject: [PATCH 096/175] Fixed syntax error
---
.github/workflows/cahref-test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index af6e9a0..d245e1e 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,9 +36,9 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}') >> $GITHUB_ENV
+ echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}' | tail -c +2 | head -c -2) >> $GITHUB_ENV
echo OPTIONS=$(cat /etc/docker/daemon.json) >> $GITHUB_ENV
- sudo sh -c "echo '{ ${{ env.OPTIONS:1: -2 }}, \"insecure-registries\": [\"${{ env.REG_ADDR }}:32000\"] }' > /etc/docker/daemon.json"
+ sudo sh -c "echo '{ ${{ env.OPTIONS }}, \"insecure-registries\": [\"${{ env.REG_ADDR }}:32000\"] }' > /etc/docker/daemon.json"
cat /etc/docker/daemon.json
sudo systemctl restart docker
From 09c3520f837705eb014951cd9bef56e232e9309a Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 19:52:04 +0200
Subject: [PATCH 097/175] Changed way of inserting variables
---
.github/workflows/cahref-test.yml | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index d245e1e..d5049b3 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,9 +36,10 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}' | tail -c +2 | head -c -2) >> $GITHUB_ENV
- echo OPTIONS=$(cat /etc/docker/daemon.json) >> $GITHUB_ENV
- sudo sh -c "echo '{ ${{ env.OPTIONS }}, \"insecure-registries\": [\"${{ env.REG_ADDR }}:32000\"] }' > /etc/docker/daemon.json"
+
+ echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}') >> $GITHUB_ENV
+ OPTIONS=$(cat /etc/docker/daemon.json | tail -c +2 | head -c -2)
+ sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"${REG_ADDR}:32000\"] }' > /etc/docker/daemon.json"
cat /etc/docker/daemon.json
sudo systemctl restart docker
@@ -49,7 +50,8 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V ${{ env.REG_ADDR }}:32000/V;docker push ${{ env.REG_ADDR }}:32000/V'
+ REG_ADDR=${{ env.REG_ADDR }}
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V $REG_ADDR:32000/V;docker push $REG_ADDR:32000/V'
- name: "install cert-manager charts"
@@ -74,12 +76,13 @@ jobs:
- name: "prepare environment / create namespace and secret"
run: |
+ REG_ADDR=${{ env.REG_ADDR }}
mkdir -p data/logs
echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|${{ env.REG_ADDR }}:32000|g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|${REG_ADDR}:32000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From 8a8100377183981a19df506d2487950ed7b7181a Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:00:22 +0200
Subject: [PATCH 098/175] Changed registry addr to localhost
---
.github/workflows/cahref-test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index d5049b3..cd80bb4 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -37,8 +37,8 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- echo REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}') >> $GITHUB_ENV
- OPTIONS=$(cat /etc/docker/daemon.json | tail -c +2 | head -c -2)
+ echo REG_ADDR="localhost" >> $GITHUB_ENV
+ OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"${REG_ADDR}:32000\"] }' > /etc/docker/daemon.json"
cat /etc/docker/daemon.json
sudo systemctl restart docker
From 35d1d526189f5e0941a77848854aa6886fd41b25 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:02:06 +0200
Subject: [PATCH 099/175] Added additional printing
---
.github/workflows/cahref-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index cd80bb4..2a149b8 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,8 +36,8 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
-
echo REG_ADDR="localhost" >> $GITHUB_ENV
+ sudo microk8s.kubectl get services -A
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"${REG_ADDR}:32000\"] }' > /etc/docker/daemon.json"
cat /etc/docker/daemon.json
From 2c17b6526c08bd9a8cc955fe683d3db0ee15b914 Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:08:01 +0200
Subject: [PATCH 100/175] Added saving registry address to bash variables
---
.github/workflows/cahref-test.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 2a149b8..d1eb802 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,7 +36,8 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- echo REG_ADDR="localhost" >> $GITHUB_ENV
+ REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}')
+ echo $REG_ADDR >> $GITHUB_ENV
sudo microk8s.kubectl get services -A
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"${REG_ADDR}:32000\"] }' > /etc/docker/daemon.json"
From d85fd6b7919632c253d334efffb7aa68a4b4adfa Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:13:37 +0200
Subject: [PATCH 101/175] Fixed wrong saving variable to gh env
---
.github/workflows/cahref-test.yml | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index d1eb802..3584066 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -37,11 +37,9 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}')
- echo $REG_ADDR >> $GITHUB_ENV
- sudo microk8s.kubectl get services -A
+ echo "${REG_ADDR}" >> $GITHUB_ENV
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"${REG_ADDR}:32000\"] }' > /etc/docker/daemon.json"
- cat /etc/docker/daemon.json
sudo systemctl restart docker
- name: "sleep for 10s"
From 00fc739a4604abf5533504fe42f97eeab7b634fd Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:28:52 +0200
Subject: [PATCH 102/175] Changed registry addr to localhost
---
.github/workflows/cahref-test.yml | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 3584066..09b66bd 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,10 +36,8 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- REG_ADDR=$(sudo microk8s.kubectl get services -A | grep -i container-registry | awk '{print $4}')
- echo "${REG_ADDR}" >> $GITHUB_ENV
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
- sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"${REG_ADDR}:32000\"] }' > /etc/docker/daemon.json"
+ sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
- name: "sleep for 10s"
@@ -49,8 +47,7 @@ jobs:
- name: "push ncm-issuer image to local registry"
run: |
- REG_ADDR=${{ env.REG_ADDR }}
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V $REG_ADDR:32000/V;docker push $REG_ADDR:32000/V'
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
- name: "install cert-manager charts"
@@ -81,7 +78,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|${REG_ADDR}:32000|g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|localhost:32000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
From 34d4c820dbc63f12027f9b180ab2de1c519c1b2b Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:45:44 +0200
Subject: [PATCH 103/175] Added debug output
---
.github/workflows/cahref-test.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 09b66bd..ad568d0 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,6 +36,8 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
+ sudo netstat -a -p | grep 32000
+ sudo sh -c "echo \"$(sed '/localhost6/d' /etc/hosts)\" > /etc/hosts"
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
From 5477526c3d38f6157f481ffe9b0b3d1a2faba1fa Mon Sep 17 00:00:00 2001
From: raczu
Date: Wed, 5 Apr 2023 20:52:04 +0200
Subject: [PATCH 104/175] Removed ipv6 loopback
---
.github/workflows/cahref-test.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index ad568d0..6ee9e24 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -36,7 +36,6 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
- sudo netstat -a -p | grep 32000
sudo sh -c "echo \"$(sed '/localhost6/d' /etc/hosts)\" > /etc/hosts"
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
From d9999731f96b766dbba3daffe76568d68564318e Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 20:19:01 +0200
Subject: [PATCH 105/175] Created local docker registry for tests
---
.github/workflows/cahref-test.yml | 58 +++++++++++++++----------------
1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index 6ee9e24..cc38d4c 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -1,4 +1,4 @@
-name: ca name and href tests
+name: finding CA by name or href tests
on:
push:
@@ -7,15 +7,19 @@ on:
- cron: '0 2 * * 6'
jobs:
- cahref_test:
- name: "CAHREF Tests"
+ href-test:
+ name: "find CA by href and enroll cert"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ port: 5000:5000
strategy:
fail-fast: false
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
@@ -24,33 +28,20 @@ jobs:
make vendor
make docker-build
+ - name: "push ncm-issuer image to local registry"
+ run: |
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
+
+
- name: "install microk8s"
run: |
sudo snap install microk8s --classic
sudo microk8s status --wait-ready
sudo microk8s enable helm3
sudo microk8s enable dns
- sudo microk8s enable registry
echo K8S_VERSION=$(sudo microk8s.kubectl version --short=true|grep -Po 'Server Version: \K.*' -m 1) >> $GITHUB_ENV
- run: echo "k8s ${{ env.K8S_VERSION }}"
- - name: "inject insecure-registry to docker"
- run: |
- sudo sh -c "echo \"$(sed '/localhost6/d' /etc/hosts)\" > /etc/hosts"
- OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
- sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
- sudo systemctl restart docker
-
- - name: "sleep for 10s"
- uses: juliangruber/sleep-action@v1
- with:
- time: 10s
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:32000/V;docker push localhost:32000/V'
-
-
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
@@ -79,7 +70,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|localhost:32000|g" helm/values.yaml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
@@ -171,23 +162,30 @@ jobs:
name: logs-cahref.tar.gz
path: ${{ github.workspace }}/artifact/upload/
- caname_test:
- name: "CANAME Test"
+ name-test:
+ name: "find CA by name and issue cert"
runs-on: ubuntu-latest
strategy:
fail-fast: false
+ services:
+ registry:
+ image: registry:2
+ port: 5000:5000
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
From acd99490099ab21405cc9352d6dcfb153a822d55 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 20:20:11 +0200
Subject: [PATCH 106/175] Fixed ports in cahref-test
---
.github/workflows/cahref-test.yml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/cahref-test.yml
index cc38d4c..1e0da36 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/cahref-test.yml
@@ -13,7 +13,8 @@ jobs:
services:
registry:
image: registry:2
- port: 5000:5000
+ ports:
+ - 5000:5000
strategy:
fail-fast: false
steps:
@@ -170,7 +171,8 @@ jobs:
services:
registry:
image: registry:2
- port: 5000:5000
+ ports:
+ - 5000:5000
steps:
- name: "checkout GIT"
uses: actions/checkout@v2
From 9e2cb9ddbad5d7e8d717bb5e4f38917c3d6c838b Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:02:42 +0200
Subject: [PATCH 107/175] Changed workflows names and added e2e tests
---
.github/workflows/e2e-tests.yml | 28 +++++++
.../workflows/{ => e2e}/clientauth-test.yml | 44 ++++++-----
.../enrollment-and-renewal-tests.yml} | 73 +++++++++++--------
.../find-ca-and-enroll-tests.yml} | 10 +--
.github/workflows/{ => e2e}/pkey-tests.yml | 47 ++++++++----
.../{san-tests.yml => e2e/san-test.yml} | 29 ++++++--
...{markdown_check.yml => markdown-check.yml} | 0
7 files changed, 154 insertions(+), 77 deletions(-)
create mode 100644 .github/workflows/e2e-tests.yml
rename .github/workflows/{ => e2e}/clientauth-test.yml (89%)
rename .github/workflows/{certmanager-application-test.yml => e2e/enrollment-and-renewal-tests.yml} (89%)
rename .github/workflows/{cahref-test.yml => e2e/find-ca-and-enroll-tests.yml} (98%)
rename .github/workflows/{ => e2e}/pkey-tests.yml (94%)
rename .github/workflows/{san-tests.yml => e2e/san-test.yml} (93%)
rename .github/workflows/{markdown_check.yml => markdown-check.yml} (100%)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
new file mode 100644
index 0000000..b6f2a6d
--- /dev/null
+++ b/.github/workflows/e2e-tests.yml
@@ -0,0 +1,28 @@
+name: e2e tests
+
+on:
+ workflow_run:
+ workflows: [tests]
+ types:
+ - completed
+
+jobs:
+ find-ca-test:
+ - name: "find CA by href or name and enroll"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/find-ca-and-enroll-tests.yml
+
+ pkey-test:
+ - name: "pkey tests"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/pkey-tests.yml
+
+ san-test:
+ - name: "san test"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/san-test.yml
+
+ client-auth-test:
+ - name: "client auth test"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/clientauth-test.yml
+
+ enrollment-and-renewal-test:
+ - name: "enrollment and renewal tests"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/e2e/clientauth-test.yml
similarity index 89%
rename from .github/workflows/clientauth-test.yml
rename to .github/workflows/e2e/clientauth-test.yml
index f72d50b..3b50f34 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/e2e/clientauth-test.yml
@@ -1,35 +1,40 @@
-name: clientauth tests
+name: client auth test
on:
- push:
- schedule:
- # * is a special character in YAML, so you have to quote this string
- - cron: '0 2 * * 6'
+ workflow_call:
jobs:
- clientauth_test:
- name: "clientauth test"
+ client-auth-test:
+ name: "client auth test"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ ports:
+ - 5000:5000
strategy:
matrix:
- k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
- certmgrversion: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
+ k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
+ certmgr-version: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
- sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
+ sudo snap install microk8s --classic --channel=${{ matrix.k8s-version }}/stable
sudo microk8s status --wait-ready
sudo microk8s enable helm3
sudo microk8s enable dns
@@ -41,7 +46,7 @@ jobs:
sudo microk8s.kubectl create namespace cert-manager
sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
sudo microk8s.helm3 repo update
- sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgrversion }} --set installCRDs=true
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgr-version }} --set installCRDs=true
echo CERTMGR_VERSION=$(sudo microk8s.helm3 list -n cert-manager -o yaml|grep -Po 'cert-manager-\K.*' -m 1) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
@@ -58,7 +63,7 @@ jobs:
- name: "install kubectl cert-manager plugin"
run: |
- OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz "https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.certmgrversion }}/kubectl-cert_manager-$OS-$ARCH.tar.gz"
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz "https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.certmgr-version }}/kubectl-cert_manager-$OS-$ARCH.tar.gz"
tar xzf kubectl-cert-manager.tar.gz
sudo mv kubectl-cert_manager /usr/local/bin
@@ -70,6 +75,7 @@ jobs:
echo "$CLIENTAUTH_KEY" > data/clientauth_key.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem --from-file=key=data/clientauth_key.pem --from-file=cert=data/clientauth_cert.pem
@@ -117,6 +123,7 @@ jobs:
- name: "create certificate resource"
run: |
sudo microk8s.kubectl apply -f data/cert-resource.yml
+
- name: "sleep for 10s"
uses: juliangruber/sleep-action@v1
with:
@@ -171,9 +178,10 @@ jobs:
mkdir -p ${{ github.workspace }}/artifact/upload
sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
- name: "[ * ] uploading artificates"
uses: actions/upload-artifact@v2
if: ${{ failure() }}
with:
- name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgrversion }}.tar.gz
+ name: logs-k${{ matrix.k8s-version }}-${{ matrix.certmgr-version }}.tar.gz
path: ${{ github.workspace }}/artifact/upload/
diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/e2e/enrollment-and-renewal-tests.yml
similarity index 89%
rename from .github/workflows/certmanager-application-test.yml
rename to .github/workflows/e2e/enrollment-and-renewal-tests.yml
index 9fad90f..c2cce5b 100644
--- a/.github/workflows/certmanager-application-test.yml
+++ b/.github/workflows/e2e/enrollment-and-renewal-tests.yml
@@ -1,31 +1,36 @@
-name: enrollment tests
+name: enrollment and renewal tests
on:
- push:
- schedule:
- # * is a special character in YAML, so you have to quote this string
- - cron: '0 2 * * 6'
+ workflow_call:
jobs:
- issuer_test:
- name: "ncm-issuer test"
+ issuer-test:
+ name: "ncm-issuer (issuer) test"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ ports:
+ - 5000:5000
strategy:
matrix:
- k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
- certmgrversion: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
+ k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
+ certmgr-version: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
@@ -41,7 +46,7 @@ jobs:
sudo microk8s.kubectl create namespace cert-manager
sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
sudo microk8s.helm3 repo update
- sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgrversion }} --set installCRDs=true
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgr-version }} --set installCRDs=true
echo CERTMGR_VERSION=$(sudo microk8s.helm3 list -n cert-manager -o yaml|grep -Po 'cert-manager-\K.*' -m 1) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
@@ -58,7 +63,7 @@ jobs:
- name: "install kubectl cert-manager plugin"
run: |
- OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz "https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.certmgrversion }}/kubectl-cert_manager-$OS-$ARCH.tar.gz"
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz "https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.certmgr-version }}/kubectl-cert_manager-$OS-$ARCH.tar.gz"
tar xzf kubectl-cert-manager.tar.gz
sudo mv kubectl-cert_manager /usr/local/bin
@@ -68,6 +73,7 @@ jobs:
echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
@@ -171,28 +177,36 @@ jobs:
uses: actions/upload-artifact@v2
if: ${{ failure() }}
with:
- name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgrversion }}.tar.gz
+ name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgr-version }}.tar.gz
path: ${{ github.workspace }}/artifact/upload/
- clusterissuer_test:
- name: "ncm-clusterissuer test"
+ cluster-issuer-test:
+ name: "ncm-issuer (cluster issuer) test"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ ports:
+ - 5000:5000
strategy:
matrix:
- k8sversion: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
- certmgrversion: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
+ k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
+ certmgr-version: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
@@ -208,7 +222,7 @@ jobs:
sudo microk8s.kubectl create namespace cert-manager
sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io
sudo microk8s.helm3 repo update
- sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgrversion }} --set installCRDs=true
+ sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --version v${{ matrix.certmgr-version }} --set installCRDs=true
echo CERTMGR_VERSION=$(sudo microk8s.helm3 list -n cert-manager -o yaml|grep -Po 'cert-manager-\K.*' -m 1) >> $GITHUB_ENV
- run: echo "cert-manager ${{ env.CERTMGR_VERSION }}"
@@ -225,7 +239,7 @@ jobs:
- name: "install kubectl cert-manager plugin"
run: |
- OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz "https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.certmgrversion }}/kubectl-cert_manager-$OS-$ARCH.tar.gz"
+ OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -sSL -o kubectl-cert-manager.tar.gz "https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.certmgr-version }}/kubectl-cert_manager-$OS-$ARCH.tar.gz"
tar xzf kubectl-cert-manager.tar.gz
sudo mv kubectl-cert_manager /usr/local/bin
@@ -239,6 +253,7 @@ jobs:
sed -i "s|secretName: ncm-issuer|authNameSpace: ncm-issuer-auth\n secretName: ncm-issuer|g" data/ncm-issuer.yml
sed -i "s|namespace: ncm-issuer|namespace: ncm-cert|g" data/cert-resource.yml
sed -i "s|kind: Issuer|kind: ClusterIssuer|g" data/cert-resource.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-cert
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create namespace ncm-issuer-auth
@@ -350,5 +365,5 @@ jobs:
uses: actions/upload-artifact@v2
if: ${{ failure() }}
with:
- name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgrversion }}.tar.gz
+ name: logs-k${{ matrix.k8sversion }}-${{ matrix.certmgr-version }}.tar.gz
path: ${{ github.workspace }}/artifact/upload/
diff --git a/.github/workflows/cahref-test.yml b/.github/workflows/e2e/find-ca-and-enroll-tests.yml
similarity index 98%
rename from .github/workflows/cahref-test.yml
rename to .github/workflows/e2e/find-ca-and-enroll-tests.yml
index 1e0da36..2b60cf1 100644
--- a/.github/workflows/cahref-test.yml
+++ b/.github/workflows/e2e/find-ca-and-enroll-tests.yml
@@ -1,10 +1,7 @@
-name: finding CA by name or href tests
+name: find CA by href or name and enroll tests
on:
- push:
- schedule:
- # * is a special character in YAML, so you have to quote this string
- - cron: '0 2 * * 6'
+ workflow_call:
jobs:
href-test:
@@ -164,7 +161,7 @@ jobs:
path: ${{ github.workspace }}/artifact/upload/
name-test:
- name: "find CA by name and issue cert"
+ name: "find CA by name and enroll cert"
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -224,6 +221,7 @@ jobs:
echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/e2e/pkey-tests.yml
similarity index 94%
rename from .github/workflows/pkey-tests.yml
rename to .github/workflows/e2e/pkey-tests.yml
index 98d5de0..2f85937 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/e2e/pkey-tests.yml
@@ -1,30 +1,35 @@
name: key algorithm tests
on:
- push:
- schedule:
- # * is a special character in YAML so you have to quote this string
- - cron: '0 2 * * 6'
+ workflow_call:
jobs:
- ecdsa_test:
+ ecdsa-test:
name: "ecdsa tests"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ ports:
+ - 5000:5000
strategy:
matrix:
keysize: [256, 384, 521]
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
@@ -69,6 +74,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
sed -i "s/rotationPolicy: Always/rotationPolicy: Always\n algorithm: ECDSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
@@ -180,24 +186,32 @@ jobs:
name: logs-ecdsa${{ matrix.keysize }}.tar.gz
path: ${{ github.workspace }}/artifact/upload/
- rsa_test:
+ rsa-test:
name: "rsa tests"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ ports:
+ - 5000:5000
strategy:
matrix:
keysize: [2048, 4096]
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
@@ -241,6 +255,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
sed -i "s/rotationPolicy: Always/rotationPolicy: Always\n algorithm: RSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
diff --git a/.github/workflows/san-tests.yml b/.github/workflows/e2e/san-test.yml
similarity index 93%
rename from .github/workflows/san-tests.yml
rename to .github/workflows/e2e/san-test.yml
index 412e440..fc907e7 100644
--- a/.github/workflows/san-tests.yml
+++ b/.github/workflows/e2e/san-test.yml
@@ -1,24 +1,35 @@
-name: san tests
+name: san test
on:
- push:
- schedule:
- # * is a special character in YAML, so you have to quote this string
- - cron: '0 2 * * 6'
+ workflow_call:
jobs:
- san_test:
- name: "san tests"
+ san-test:
+ name: "san test"
runs-on: ubuntu-latest
+ services:
+ registry:
+ image: registry:2
+ ports:
+ - 5000:5000
strategy:
fail-fast: false
steps:
-
- name: "checkout GIT"
uses: actions/checkout@v2
+
- uses: actions/setup-go@v3
- run: go version
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
+ run: |
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
+
- name: "get runner ip"
run: |
echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV
@@ -79,9 +90,11 @@ jobs:
sed -i "s|- foo.bar.local|- foo.bar.local\n - ${{ env.RUNNER_NAME }}-${{ env.RUNNER_UTS }}.bar.local|g" data/cert-resource.yml
sed -i "s|renewBefore: 120h|ipAddresses:\n - 192.168.1.1\n - ${{ env.RUNNER_IP }}\n - fc00:bad:a55:3468::443\n renewBefore: 120h|g" data/cert-resource.yml
sed -i "s|renewBefore: 120h|uris:\n - spiffe://cluster.local/ns/spiffe/sa/example\n renewBefore: 120h|g" data/cert-resource.yml
+ sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
+
env:
NCM_HOST: ${{ secrets.NCM_HOST }}
NCM_USER: ${{ secrets.NCM_USER }}
diff --git a/.github/workflows/markdown_check.yml b/.github/workflows/markdown-check.yml
similarity index 100%
rename from .github/workflows/markdown_check.yml
rename to .github/workflows/markdown-check.yml
From c0ddae8d96521c5c403693d1e2c1dfc60c017091 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:04:40 +0200
Subject: [PATCH 108/175] Fixed invalid workflow file
---
.github/workflows/e2e-tests.yml | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index b6f2a6d..63f6f1f 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -8,21 +8,21 @@ on:
jobs:
find-ca-test:
- - name: "find CA by href or name and enroll"
- uses: nokia/ncm-issuer/.github/workflows/e2e/find-ca-and-enroll-tests.yml
+ name: "find CA by href or name and enroll"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/find-ca-and-enroll-tests.yml
pkey-test:
- - name: "pkey tests"
- uses: nokia/ncm-issuer/.github/workflows/e2e/pkey-tests.yml
+ name: "pkey tests"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/pkey-tests.yml
san-test:
- - name: "san test"
- uses: nokia/ncm-issuer/.github/workflows/e2e/san-test.yml
+ name: "san test"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/san-test.yml
client-auth-test:
- - name: "client auth test"
- uses: nokia/ncm-issuer/.github/workflows/e2e/clientauth-test.yml
+ name: "client auth test"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/clientauth-test.yml
enrollment-and-renewal-test:
- - name: "enrollment and renewal tests"
- uses: nokia/ncm-issuer/.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
+ name: "enrollment and renewal tests"
+ uses: nokia/ncm-issuer/.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
From 242828311fbaafd6bcff9fa52665fc0bebc6ce32 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:08:20 +0200
Subject: [PATCH 109/175] Added checkout to fix inavlid workflow file
---
.github/workflows/e2e-tests.yml | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 63f6f1f..cf04564 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -8,21 +8,31 @@ on:
jobs:
find-ca-test:
- name: "find CA by href or name and enroll"
- uses: nokia/ncm-issuer/.github/workflows/e2e/find-ca-and-enroll-tests.yml
+ steps:
+ - uses: actions/checkout@v3
+ - name: "find CA by href or name and enroll"
+ uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
pkey-test:
- name: "pkey tests"
- uses: nokia/ncm-issuer/.github/workflows/e2e/pkey-tests.yml
+ steps:
+ - uses: actions/checkout@v3
+ - name: "pkey tests"
+ uses: ./.github/workflows/e2e/pkey-tests.yml
san-test:
- name: "san test"
- uses: nokia/ncm-issuer/.github/workflows/e2e/san-test.yml
+ steps:
+ - uses: actions/checkout@v3
+ - name: "san test"
+ uses: ./.github/workflows/e2e/san-test.yml
client-auth-test:
- name: "client auth test"
- uses: nokia/ncm-issuer/.github/workflows/e2e/clientauth-test.yml
+ steps:
+ - uses: actions/checkout@v3
+ - name: "client auth test"
+ uses: ./.github/workflows/e2e/clientauth-test.yml
enrollment-and-renewal-test:
- name: "enrollment and renewal tests"
- uses: nokia/ncm-issuer/.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
+ steps:
+ - uses: actions/checkout@v3
+ - name: "enrollment and renewal tests"
+ uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
From 52fcd72ad831d128f4655a353c786cf59d33e1fa Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:15:01 +0200
Subject: [PATCH 110/175] Changed behaviour of e2e workflow to run independent
on push or pull request
---
.github/workflows/e2e-tests.yml | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index cf04564..cbdee18 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -1,10 +1,8 @@
name: e2e tests
on:
- workflow_run:
- workflows: [tests]
- types:
- - completed
+ push:
+ pull_request:
jobs:
find-ca-test:
From a95e7eb18474ffceabe8f8b50e759d31ebe1635c Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:16:25 +0200
Subject: [PATCH 111/175] Added missing 'runs-on'
---
.github/workflows/e2e-tests.yml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index cbdee18..c4b7ec4 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -6,30 +6,35 @@ on:
jobs:
find-ca-test:
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "find CA by href or name and enroll"
uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
pkey-test:
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "pkey tests"
uses: ./.github/workflows/e2e/pkey-tests.yml
san-test:
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "san test"
uses: ./.github/workflows/e2e/san-test.yml
client-auth-test:
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "client auth test"
uses: ./.github/workflows/e2e/clientauth-test.yml
enrollment-and-renewal-test:
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "enrollment and renewal tests"
From 25fab1d8ae7fa655d52d511029bf6d054da7a7f3 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:38:34 +0200
Subject: [PATCH 112/175] Added ls for debugging
---
.github/workflows/e2e-tests.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index c4b7ec4..a1e80c8 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -9,6 +9,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+ - name: "list content"
+ run: ls -R
- name: "find CA by href or name and enroll"
uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
From aca5485f520145971fad22d2a7d178dc1986093b Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:40:51 +0200
Subject: [PATCH 113/175] Added additional flag for ls
---
.github/workflows/e2e-tests.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index a1e80c8..9eccb69 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -10,7 +10,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: "list content"
- run: ls -R
+ run: ls -Ra
- name: "find CA by href or name and enroll"
uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
From a26090b8384fb3d2b4136cbed93d891c23e14e54 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:53:14 +0200
Subject: [PATCH 114/175] Removed checkout step
---
.github/workflows/e2e-tests.yml | 37 +++++++++------------------------
1 file changed, 10 insertions(+), 27 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 9eccb69..4c9f2e8 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -6,38 +6,21 @@ on:
jobs:
find-ca-test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: "list content"
- run: ls -Ra
- - name: "find CA by href or name and enroll"
- uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
+ - name: "find CA by href or name and enroll"
+ uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
pkey-test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: "pkey tests"
- uses: ./.github/workflows/e2e/pkey-tests.yml
+ - name: "pkey tests"
+ uses: ./.github/workflows/e2e/pkey-tests.yml
san-test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: "san test"
- uses: ./.github/workflows/e2e/san-test.yml
+ - name: "san test"
+ uses: ./.github/workflows/e2e/san-test.yml
client-auth-test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: "client auth test"
- uses: ./.github/workflows/e2e/clientauth-test.yml
+ - name: "client auth test"
+ uses: ./.github/workflows/e2e/clientauth-test.yml
enrollment-and-renewal-test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: "enrollment and renewal tests"
- uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
+ - name: "enrollment and renewal tests"
+ uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
From 02ded4a76f6a5756271166cf7c67d0bb04683623 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:54:14 +0200
Subject: [PATCH 115/175] Fixed invalid syntax
---
.github/workflows/e2e-tests.yml | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 4c9f2e8..8b304ec 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -6,21 +6,16 @@ on:
jobs:
find-ca-test:
- - name: "find CA by href or name and enroll"
- uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
+ uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
pkey-test:
- - name: "pkey tests"
- uses: ./.github/workflows/e2e/pkey-tests.yml
+ uses: ./.github/workflows/e2e/pkey-tests.yml
san-test:
- - name: "san test"
- uses: ./.github/workflows/e2e/san-test.yml
+ uses: ./.github/workflows/e2e/san-test.yml
client-auth-test:
- - name: "client auth test"
- uses: ./.github/workflows/e2e/clientauth-test.yml
+ uses: ./.github/workflows/e2e/clientauth-test.yml
enrollment-and-renewal-test:
- - name: "enrollment and renewal tests"
- uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
+ uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
From ef64995b030b023bcbc80566e4be9531cb479c20 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:57:36 +0200
Subject: [PATCH 116/175] Moved e2e tests to main workflow directory
---
.github/workflows/{e2e => }/clientauth-test.yml | 0
.github/workflows/e2e-tests.yml | 5 +++++
.github/workflows/{e2e => }/enrollment-and-renewal-tests.yml | 0
.github/workflows/{e2e => }/find-ca-and-enroll-tests.yml | 0
.github/workflows/{e2e => }/pkey-tests.yml | 0
.github/workflows/{e2e => }/san-test.yml | 0
6 files changed, 5 insertions(+)
rename .github/workflows/{e2e => }/clientauth-test.yml (100%)
rename .github/workflows/{e2e => }/enrollment-and-renewal-tests.yml (100%)
rename .github/workflows/{e2e => }/find-ca-and-enroll-tests.yml (100%)
rename .github/workflows/{e2e => }/pkey-tests.yml (100%)
rename .github/workflows/{e2e => }/san-test.yml (100%)
diff --git a/.github/workflows/e2e/clientauth-test.yml b/.github/workflows/clientauth-test.yml
similarity index 100%
rename from .github/workflows/e2e/clientauth-test.yml
rename to .github/workflows/clientauth-test.yml
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 8b304ec..a6a997d 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -6,16 +6,21 @@ on:
jobs:
find-ca-test:
+ name: "find CA by href or name and enroll"
uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
pkey-test:
+ name: "pkey tests"
uses: ./.github/workflows/e2e/pkey-tests.yml
san-test:
+ name: "san test"
uses: ./.github/workflows/e2e/san-test.yml
client-auth-test:
+ name: "client auth test"
uses: ./.github/workflows/e2e/clientauth-test.yml
enrollment-and-renewal-test:
+ name: "enrollment and renewal tests"
uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
diff --git a/.github/workflows/e2e/enrollment-and-renewal-tests.yml b/.github/workflows/enrollment-and-renewal-tests.yml
similarity index 100%
rename from .github/workflows/e2e/enrollment-and-renewal-tests.yml
rename to .github/workflows/enrollment-and-renewal-tests.yml
diff --git a/.github/workflows/e2e/find-ca-and-enroll-tests.yml b/.github/workflows/find-ca-and-enroll-tests.yml
similarity index 100%
rename from .github/workflows/e2e/find-ca-and-enroll-tests.yml
rename to .github/workflows/find-ca-and-enroll-tests.yml
diff --git a/.github/workflows/e2e/pkey-tests.yml b/.github/workflows/pkey-tests.yml
similarity index 100%
rename from .github/workflows/e2e/pkey-tests.yml
rename to .github/workflows/pkey-tests.yml
diff --git a/.github/workflows/e2e/san-test.yml b/.github/workflows/san-test.yml
similarity index 100%
rename from .github/workflows/e2e/san-test.yml
rename to .github/workflows/san-test.yml
From d10c367c44783fda7d6b9ff62a007898d36c10b6 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 21:58:17 +0200
Subject: [PATCH 117/175] Fixed invalid directory in reusable workflows
---
.github/workflows/e2e-tests.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index a6a997d..6074484 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -7,20 +7,20 @@ on:
jobs:
find-ca-test:
name: "find CA by href or name and enroll"
- uses: ./.github/workflows/e2e/find-ca-and-enroll-tests.yml
+ uses: ./.github/workflows/find-ca-and-enroll-tests.yml
pkey-test:
name: "pkey tests"
- uses: ./.github/workflows/e2e/pkey-tests.yml
+ uses: ./.github/workflows/pkey-tests.yml
san-test:
name: "san test"
- uses: ./.github/workflows/e2e/san-test.yml
+ uses: ./.github/workflows/san-test.yml
client-auth-test:
name: "client auth test"
- uses: ./.github/workflows/e2e/clientauth-test.yml
+ uses: ./.github/workflows/clientauth-test.yml
enrollment-and-renewal-test:
name: "enrollment and renewal tests"
- uses: ./.github/workflows/e2e/enrollment-and-renewal-tests.yml
\ No newline at end of file
+ uses: ./.github/workflows/enrollment-and-renewal-tests.yml
\ No newline at end of file
From e71ce7d4048bd0b8c9486d4e69c5b4d49c3fd234 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 22:02:13 +0200
Subject: [PATCH 118/175] Fixed wrong usage of Makefile in san test
---
.../workflows/find-ca-and-enroll-tests.yml | 4 ++--
.github/workflows/san-test.yml | 20 +++++++------------
2 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/find-ca-and-enroll-tests.yml b/.github/workflows/find-ca-and-enroll-tests.yml
index 2b60cf1..266fb28 100644
--- a/.github/workflows/find-ca-and-enroll-tests.yml
+++ b/.github/workflows/find-ca-and-enroll-tests.yml
@@ -5,7 +5,7 @@ on:
jobs:
href-test:
- name: "find CA by href and enroll cert"
+ name: "href test"
runs-on: ubuntu-latest
services:
registry:
@@ -161,7 +161,7 @@ jobs:
path: ${{ github.workspace }}/artifact/upload/
name-test:
- name: "find CA by name and enroll cert"
+ name: "name test"
runs-on: ubuntu-latest
strategy:
fail-fast: false
diff --git a/.github/workflows/san-test.yml b/.github/workflows/san-test.yml
index fc907e7..c3bcb2e 100644
--- a/.github/workflows/san-test.yml
+++ b/.github/workflows/san-test.yml
@@ -21,15 +21,6 @@ jobs:
- uses: actions/setup-go@v3
- run: go version
- - name: "build ncm-issuer image"
- run: |
- make vendor
- make docker-build
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
-
- name: "get runner ip"
run: |
echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV
@@ -46,11 +37,14 @@ jobs:
echo RUNNER_UTS=$(date +%s) >> $GITHUB_ENV
- run: echo "unix timestamp is ${{ env.RUNNER_UTS }}"
- - name: "build plugin"
+ - name: "build ncm-issuer image"
+ run: |
+ make vendor
+ make docker-build
+
+ - name: "push ncm-issuer image to local registry"
run: |
- go mod vendor
- make docker_build_img
- make save
+ docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
- name: "install microk8s"
run: |
From 18ad4b869c29e331e391abb25c233ecaecbfcd93 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 6 Apr 2023 22:17:17 +0200
Subject: [PATCH 119/175] Added inheritance of secrets
---
.github/workflows/e2e-tests.yml | 5 +++++
.github/workflows/enrollment-and-renewal-tests.yml | 4 ++--
.github/workflows/pkey-tests.yml | 4 ++--
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 6074484..3b2458f 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -7,20 +7,25 @@ on:
jobs:
find-ca-test:
name: "find CA by href or name and enroll"
+ secrets: inherit
uses: ./.github/workflows/find-ca-and-enroll-tests.yml
pkey-test:
name: "pkey tests"
+ secrets: inherit
uses: ./.github/workflows/pkey-tests.yml
san-test:
name: "san test"
+ secrets: inherit
uses: ./.github/workflows/san-test.yml
client-auth-test:
name: "client auth test"
+ secrets: inherit
uses: ./.github/workflows/clientauth-test.yml
enrollment-and-renewal-test:
name: "enrollment and renewal tests"
+ secrets: inherit
uses: ./.github/workflows/enrollment-and-renewal-tests.yml
\ No newline at end of file
diff --git a/.github/workflows/enrollment-and-renewal-tests.yml b/.github/workflows/enrollment-and-renewal-tests.yml
index c2cce5b..e7b5bfc 100644
--- a/.github/workflows/enrollment-and-renewal-tests.yml
+++ b/.github/workflows/enrollment-and-renewal-tests.yml
@@ -5,7 +5,7 @@ on:
jobs:
issuer-test:
- name: "ncm-issuer (issuer) test"
+ name: "issuer test"
runs-on: ubuntu-latest
services:
registry:
@@ -181,7 +181,7 @@ jobs:
path: ${{ github.workspace }}/artifact/upload/
cluster-issuer-test:
- name: "ncm-issuer (cluster issuer) test"
+ name: "cluster test"
runs-on: ubuntu-latest
services:
registry:
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
index 2f85937..f9e4e69 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/pkey-tests.yml
@@ -5,7 +5,7 @@ on:
jobs:
ecdsa-test:
- name: "ecdsa tests"
+ name: "ecdsa test"
runs-on: ubuntu-latest
services:
registry:
@@ -187,7 +187,7 @@ jobs:
path: ${{ github.workspace }}/artifact/upload/
rsa-test:
- name: "rsa tests"
+ name: "rsa test"
runs-on: ubuntu-latest
services:
registry:
From b67b3bd69cdf6152824357fbc697ae86d77e0c69 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 7 Apr 2023 13:21:33 +0200
Subject: [PATCH 120/175] Added deugging outputs
---
.github/workflows/clientauth-test.yml | 3 +++
.github/workflows/enrollment-and-renewal-tests.yml | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index 3b50f34..130c22a 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -76,6 +76,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
+ cat helm/values.yaml | grep -i registry
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem --from-file=key=data/clientauth_key.pem --from-file=cert=data/clientauth_cert.pem
@@ -102,6 +103,8 @@ jobs:
sudo microk8s.helm3 list -A
sudo microk8s.kubectl get pods -A
sudo microk8s.kubectl -n ncm-issuer logs `sudo microk8s.kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'`|tail -25
+ POD_NAME=$(sudo microk8s.kubectl get pods -A | grep -i ncm-issuer | awk '{ print $2 }')
+ sudo microk8s.kubectl describe pod $POD_NAME -n ncm-issuer
- name: "create issuer"
run: |
diff --git a/.github/workflows/enrollment-and-renewal-tests.yml b/.github/workflows/enrollment-and-renewal-tests.yml
index e7b5bfc..50504d4 100644
--- a/.github/workflows/enrollment-and-renewal-tests.yml
+++ b/.github/workflows/enrollment-and-renewal-tests.yml
@@ -173,6 +173,7 @@ jobs:
mkdir -p ${{ github.workspace }}/artifact/upload
sudo cp -rp data/ ${{ github.workspace }}/artifact/data/
sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data
+
- name: "[ * ] uploading artificates"
uses: actions/upload-artifact@v2
if: ${{ failure() }}
@@ -181,7 +182,7 @@ jobs:
path: ${{ github.workspace }}/artifact/upload/
cluster-issuer-test:
- name: "cluster test"
+ name: "cluster issuer test"
runs-on: ubuntu-latest
services:
registry:
From 723fa879d8272a2d2f8f77b713d17ce6839505cc Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 7 Apr 2023 15:03:17 +0200
Subject: [PATCH 121/175] Added injecting insecure-registry to dockerd
---
.github/workflows/clientauth-test.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index 130c22a..eaec523 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -41,6 +41,17 @@ jobs:
echo K8S_VERSION=$(sudo microk8s.kubectl version --short=true|grep -Po 'Server Version: \K.*' -m 1) >> $GITHUB_ENV
- run: echo "k8s ${{ env.K8S_VERSION }}"
+ - name: "inject insecure-registry to docker"
+ run: |
+ OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
+ sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
+ sudo systemctl restart docker
+
+ - name: "sleep for 10s"
+ uses: juliangruber/sleep-action@v1
+ with:
+ time: 10s
+
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
From e4e975c0b552b8d8f8ecda0f195cbe71d9a31414 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 7 Apr 2023 15:04:25 +0200
Subject: [PATCH 122/175] Changed registry port in injection
---
.github/workflows/clientauth-test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index eaec523..e859dae 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -44,7 +44,7 @@ jobs:
- name: "inject insecure-registry to docker"
run: |
OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
- sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:32000\"] }' > /etc/docker/daemon.json"
+ sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:5000\"] }' > /etc/docker/daemon.json"
sudo systemctl restart docker
- name: "sleep for 10s"
From 675ab72fe2077ddc58ac62add6973cc0a1ee5ad7 Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 7 Apr 2023 15:44:07 +0200
Subject: [PATCH 123/175] Removed few version of k8s for debugging reasons
---
.github/workflows/clientauth-test.yml | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index e859dae..e5e0004 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -14,7 +14,8 @@ jobs:
- 5000:5000
strategy:
matrix:
- k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
+# k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
+ k8s-version: ['1.23', '1.24']
certmgr-version: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
steps:
- name: "checkout GIT"
@@ -41,17 +42,6 @@ jobs:
echo K8S_VERSION=$(sudo microk8s.kubectl version --short=true|grep -Po 'Server Version: \K.*' -m 1) >> $GITHUB_ENV
- run: echo "k8s ${{ env.K8S_VERSION }}"
- - name: "inject insecure-registry to docker"
- run: |
- OPTIONS=$(cat /etc/docker/daemon.json | tail -c +3 | head -c -3)
- sudo sh -c "echo '{ ${OPTIONS}, \"insecure-registries\": [\"localhost:5000\"] }' > /etc/docker/daemon.json"
- sudo systemctl restart docker
-
- - name: "sleep for 10s"
- uses: juliangruber/sleep-action@v1
- with:
- time: 10s
-
- name: "install cert-manager charts"
run: |
sudo microk8s.kubectl create namespace cert-manager
From 03bc045ac691da6bdb7bd9d5bbc16e4aded1af7f Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 13 Apr 2023 20:36:01 +0200
Subject: [PATCH 124/175] ci: add sonarcloud scanning workflow
---
.../{tests.yml => build-and-test.yml} | 0
.github/workflows/e2e-tests.yml | 31 -------------------
.github/workflows/sonarcloud.yml | 25 +++++++++++++++
3 files changed, 25 insertions(+), 31 deletions(-)
rename .github/workflows/{tests.yml => build-and-test.yml} (100%)
delete mode 100644 .github/workflows/e2e-tests.yml
create mode 100644 .github/workflows/sonarcloud.yml
diff --git a/.github/workflows/tests.yml b/.github/workflows/build-and-test.yml
similarity index 100%
rename from .github/workflows/tests.yml
rename to .github/workflows/build-and-test.yml
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
deleted file mode 100644
index 3b2458f..0000000
--- a/.github/workflows/e2e-tests.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: e2e tests
-
-on:
- push:
- pull_request:
-
-jobs:
- find-ca-test:
- name: "find CA by href or name and enroll"
- secrets: inherit
- uses: ./.github/workflows/find-ca-and-enroll-tests.yml
-
- pkey-test:
- name: "pkey tests"
- secrets: inherit
- uses: ./.github/workflows/pkey-tests.yml
-
- san-test:
- name: "san test"
- secrets: inherit
- uses: ./.github/workflows/san-test.yml
-
- client-auth-test:
- name: "client auth test"
- secrets: inherit
- uses: ./.github/workflows/clientauth-test.yml
-
- enrollment-and-renewal-test:
- name: "enrollment and renewal tests"
- secrets: inherit
- uses: ./.github/workflows/enrollment-and-renewal-tests.yml
\ No newline at end of file
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
new file mode 100644
index 0000000..98b77fb
--- /dev/null
+++ b/.github/workflows/sonarcloud.yml
@@ -0,0 +1,25 @@
+name: code scanning
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [opened, synchronize, reopened]
+ schedule:
+ - cron: '0 1 * * *'
+
+jobs:
+ sonarcloud:
+ name: SonarCloud
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: SonarCloud Scan
+ uses: SonarSource/sonarcloud-github-action@master
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
\ No newline at end of file
From b32e29c597d8334da7880f96861f04162b7117da Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 13 Apr 2023 20:46:47 +0200
Subject: [PATCH 125/175] feat: add logging replicas count in manager In
addition, the way of providing image details in helm chart is changed
---
helm/Chart.yaml | 7 +++++--
helm/templates/deployment/deployment.yaml | 7 +++++--
helm/values.yaml | 9 +++++++--
main.go | 1 +
4 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
index 9bfe7dc..044f2d7 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -1,5 +1,6 @@
apiVersion: v1
-appVersion: "1.0.4"
+
+name: ncm-issuer
description: A Helm chart for cert-manager external issuer with NCM (Netguard certficate
manager)
icon: https://cert-manager.io/images/high-level-overview.svg
@@ -8,6 +9,7 @@ keywords:
- cert-manager
- com.nokia.ncm.certifier
- com.nokia.neo/commitId :Id09c2c9d690aea6cd516490cb5b5e1b71caafd91
+
maintainers:
- email: sara.ryfczynska@nokia.com
name: Sara Ryfczynska
@@ -15,5 +17,6 @@ maintainers:
name: Dawid Machoczek
- name: Maxwell Jiang
- name: Lilian Liang
-name: ncm-issuer
+
+appVersion: 1.0.4
version: 1.1.0
\ No newline at end of file
diff --git a/helm/templates/deployment/deployment.yaml b/helm/templates/deployment/deployment.yaml
index 06aa20b..9feb6ce 100644
--- a/helm/templates/deployment/deployment.yaml
+++ b/helm/templates/deployment/deployment.yaml
@@ -33,12 +33,15 @@ spec:
{{- if and .Values.enableLeaderElection (gt (.Values.replicaCount | int64) 1) }}
- --leader-elect
{{- end }}
- image: {{ .Values.registry }}/ncm-issuer:{{ .Chart.Version }}
- imagePullPolicy: {{ .Values.imagePullPolicy }}
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.version }}
+ imagePullPolicy: {{ .Values.image.imagePullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports:
- containerPort: {{ .Values.metrics.port }}
+ env:
+ - name: REP_COUNT
+ value: "{{ .Values.replicaCount }}"
{{ if .Values.livenessProbe }}
livenessProbe:
httpGet:
diff --git a/helm/values.yaml b/helm/values.yaml
index f2d217a..ddeb8e7 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -1,8 +1,13 @@
-registry: docker.io/misiektoja
replicaCount: 1
priorityClassName: ""
+
+image:
+ repository: docker.io/misiektoja/ncm-issuer
+ tag: dev
+ imagePullPolicy: Always
+
imagePullSecrets: []
-imagePullPolicy: Always
+
resources:
# Limits to cap the resource usage in case of unexpected.
# NOTE! exceeding memory limit will cause pod to be killed by kubernetes.
diff --git a/main.go b/main.go
index 25f6404..458b53f 100644
--- a/main.go
+++ b/main.go
@@ -74,6 +74,7 @@ func main() {
"starting",
"chart-version", chartVersion,
"image-version", imageVersion,
+ "replica-count", os.Getenv("REP_COUNT"),
"enable-leader-election", enableLeaderElection,
"metrics-addr", metricsAddr,
)
From bdccbfe97a7aa1b0ab4ff1545ae4c6dea201a422 Mon Sep 17 00:00:00 2001
From: raczu
Date: Thu, 13 Apr 2023 20:49:17 +0200
Subject: [PATCH 126/175] ci: refactor old workflows to fit new pipelines
---
.github/workflows/build-and-test.yml | 56 ++++++++++++++++++-
.github/workflows/clientauth-test.yml | 24 +-------
.../enrollment-and-renewal-tests.yml | 19 +------
.../workflows/find-ca-and-enroll-tests.yml | 20 +------
.github/workflows/pkey-tests.yml | 19 +------
.github/workflows/san-test.yml | 19 +------
Dockerfile | 12 +---
Makefile | 6 +-
8 files changed, 67 insertions(+), 108 deletions(-)
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index a9a9817..5f82dc8 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -1,8 +1,11 @@
-name: tests
+name: build and test
on:
push:
+ branches:
+ - main
pull_request:
+ types: [opened, synchronized, reopened]
jobs:
go-versions:
@@ -13,6 +16,7 @@ jobs:
go-mod-version: ${{ steps.versions.outputs.go-mod-version }}
steps:
- uses: actions/checkout@v3
+
- uses: arnested/go-version-action@v1
id: versions
@@ -74,4 +78,52 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: "build ncm-issuer"
- run: make build
\ No newline at end of file
+ run: make build
+
+ docker:
+ name: "push to registry for e2e tests"
+ needs: [unit, golangci, build]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: "log in to docker hub"
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: "set up docker buildx"
+ uses: docker/setup-buildx-action@v2
+
+ - name: "build and push to docker hub"
+ uses: docker/build-push-action@v4
+ with:
+ context: .
+ file: ./Dockerfile
+ push: true
+ tags: ${{ secrets.DOCKER_USERNAME }}/ncm-issuer:dev
+
+ e2e:
+ name: "e2e tests"
+ needs: [docker]
+ steps:
+ - name: "find CA and enroll"
+ uses: ./.github/workflows/find-ca-and-enroll-tests.yml
+ secrets: inherit
+
+ - name: "private key"
+ uses: ./.github/workflows/pkey-tests.yml
+ secrets: inherit
+
+ - name: "san"
+ uses: ./.github/workflows/san-test.yml
+ secrets: inherit
+
+ - name: "client auth"
+ uses: ./.github/workflows/clientauth-test.yml
+ secrets: inherit
+
+ - name: "enrollment and renewal"
+ uses: ./.github/workflows/enrollment-and-renewal-tests.yml
+ secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/clientauth-test.yml b/.github/workflows/clientauth-test.yml
index e5e0004..4e8ec99 100644
--- a/.github/workflows/clientauth-test.yml
+++ b/.github/workflows/clientauth-test.yml
@@ -7,32 +7,14 @@ jobs:
client-auth-test:
name: "client auth test"
runs-on: ubuntu-latest
- services:
- registry:
- image: registry:2
- ports:
- - 5000:5000
strategy:
matrix:
-# k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
- k8s-version: ['1.23', '1.24']
+ k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
certmgr-version: ['1.5.5', '1.6.2', '1.8.2', '1.9.2', '1.11.0']
steps:
- name: "checkout GIT"
uses: actions/checkout@v2
- - uses: actions/setup-go@v3
- - run: go version
-
- - name: "build ncm-issuer image"
- run: |
- make vendor
- make docker-build
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
-
- name: "install microk8s"
run: |
sudo snap install microk8s --classic --channel=${{ matrix.k8s-version }}/stable
@@ -76,8 +58,8 @@ jobs:
echo "$CLIENTAUTH_KEY" > data/clientauth_key.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
- cat helm/values.yaml | grep -i registry
+ sed -i -E "s/tag: ([A-Za-z0-9]+(\.[A-Za-z0-9]+)+)|tag: ([A-Za-z]+)/tag: dev/" helm/values.yaml
+ cat helm/values.yaml | grep -i registry
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem --from-file=key=data/clientauth_key.pem --from-file=cert=data/clientauth_cert.pem
diff --git a/.github/workflows/enrollment-and-renewal-tests.yml b/.github/workflows/enrollment-and-renewal-tests.yml
index 50504d4..98986dc 100644
--- a/.github/workflows/enrollment-and-renewal-tests.yml
+++ b/.github/workflows/enrollment-and-renewal-tests.yml
@@ -7,11 +7,6 @@ jobs:
issuer-test:
name: "issuer test"
runs-on: ubuntu-latest
- services:
- registry:
- image: registry:2
- ports:
- - 5000:5000
strategy:
matrix:
k8s-version: ['1.21', '1.22', '1.23', '1.24', '1.25', '1.26']
@@ -20,18 +15,6 @@ jobs:
- name: "checkout GIT"
uses: actions/checkout@v2
- - uses: actions/setup-go@v3
- - run: go version
-
- - name: "build ncm-issuer image"
- run: |
- make vendor
- make docker-build
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
-
- name: "install microk8s"
run: |
sudo snap install microk8s --classic --channel=${{ matrix.k8sversion }}/stable
@@ -73,7 +56,7 @@ jobs:
echo "$NCM_CA_BUNDLE" > data/ca_bundle.pem
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
+ sed -i -E "s/tag: ([A-Za-z0-9]+(\.[A-Za-z0-9]+)+)|tag: ([A-Za-z]+)/tag: dev/" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
diff --git a/.github/workflows/find-ca-and-enroll-tests.yml b/.github/workflows/find-ca-and-enroll-tests.yml
index 266fb28..c2f4130 100644
--- a/.github/workflows/find-ca-and-enroll-tests.yml
+++ b/.github/workflows/find-ca-and-enroll-tests.yml
@@ -7,30 +7,12 @@ jobs:
href-test:
name: "href test"
runs-on: ubuntu-latest
- services:
- registry:
- image: registry:2
- ports:
- - 5000:5000
strategy:
fail-fast: false
steps:
- name: "checkout GIT"
uses: actions/checkout@v2
- - uses: actions/setup-go@v3
- - run: go version
-
- - name: "build ncm-issuer image"
- run: |
- make vendor
- make docker-build
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
-
-
- name: "install microk8s"
run: |
sudo snap install microk8s --classic
@@ -68,7 +50,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|CASNAME: SubCA|CASHREF: $NCM_CAHREF|g" data/ncm-issuer.yml
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
- sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
+ sed -i -E "s/tag: ([A-Za-z0-9]+(\.[A-Za-z0-9]+)+)|tag: ([A-Za-z]+)/tag: dev/" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
diff --git a/.github/workflows/pkey-tests.yml b/.github/workflows/pkey-tests.yml
index f9e4e69..00debe3 100644
--- a/.github/workflows/pkey-tests.yml
+++ b/.github/workflows/pkey-tests.yml
@@ -7,11 +7,6 @@ jobs:
ecdsa-test:
name: "ecdsa test"
runs-on: ubuntu-latest
- services:
- registry:
- image: registry:2
- ports:
- - 5000:5000
strategy:
matrix:
keysize: [256, 384, 521]
@@ -19,18 +14,6 @@ jobs:
- name: "checkout GIT"
uses: actions/checkout@v2
- - uses: actions/setup-go@v3
- - run: go version
-
- - name: "build ncm-issuer image"
- run: |
- make vendor
- make docker-build
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
-
- name: "install microk8s"
run: |
sudo snap install microk8s --classic
@@ -74,7 +57,7 @@ jobs:
cp .github/*.yml data/
sed -i "s|ncmSERVER: NCM_SRV|ncmSERVER: $NCM_HOST|g" data/ncm-issuer.yml
sed -i "s/rotationPolicy: Always/rotationPolicy: Always\n algorithm: ECDSA\n size: ${{ matrix.keysize }}/g" data/cert-resource.yml
- sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
+ sed -i -E "s/tag: ([A-Za-z0-9]+(\.[A-Za-z0-9]+)+)|tag: ([A-Za-z]+)/tag: dev/" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
diff --git a/.github/workflows/san-test.yml b/.github/workflows/san-test.yml
index c3bcb2e..73767eb 100644
--- a/.github/workflows/san-test.yml
+++ b/.github/workflows/san-test.yml
@@ -7,20 +7,12 @@ jobs:
san-test:
name: "san test"
runs-on: ubuntu-latest
- services:
- registry:
- image: registry:2
- ports:
- - 5000:5000
strategy:
fail-fast: false
steps:
- name: "checkout GIT"
uses: actions/checkout@v2
- - uses: actions/setup-go@v3
- - run: go version
-
- name: "get runner ip"
run: |
echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV
@@ -37,15 +29,6 @@ jobs:
echo RUNNER_UTS=$(date +%s) >> $GITHUB_ENV
- run: echo "unix timestamp is ${{ env.RUNNER_UTS }}"
- - name: "build ncm-issuer image"
- run: |
- make vendor
- make docker-build
-
- - name: "push ncm-issuer image to local registry"
- run: |
- docker images | grep -i ncm-issuer | awk '{print $1":"$2}' | xargs -I V sh -c 'docker tag V localhost:5000/V;docker push localhost:5000/V'
-
- name: "install microk8s"
run: |
sudo snap install microk8s --classic
@@ -84,7 +67,7 @@ jobs:
sed -i "s|- foo.bar.local|- foo.bar.local\n - ${{ env.RUNNER_NAME }}-${{ env.RUNNER_UTS }}.bar.local|g" data/cert-resource.yml
sed -i "s|renewBefore: 120h|ipAddresses:\n - 192.168.1.1\n - ${{ env.RUNNER_IP }}\n - fc00:bad:a55:3468::443\n renewBefore: 120h|g" data/cert-resource.yml
sed -i "s|renewBefore: 120h|uris:\n - spiffe://cluster.local/ns/spiffe/sa/example\n renewBefore: 120h|g" data/cert-resource.yml
- sed -i "s|docker.io/misiektoja|localhost:5000|g" helm/values.yaml
+ sed -i -E "s/tag: ([A-Za-z0-9]+(\.[A-Za-z0-9]+)+)|tag: ([A-Za-z]+)/tag: dev/" helm/values.yaml
sudo microk8s.kubectl create namespace ncm-issuer
sudo microk8s.kubectl create secret generic ncm-issuer -n ncm-issuer --from-literal=username=$NCM_USER --from-literal=usrPassword=$NCM_PASSWORD
sudo microk8s.kubectl create secret generic ncm-issuer-bundle -n ncm-issuer --from-file=cacert=data/ca_bundle.pem
diff --git a/Dockerfile b/Dockerfile
index 71c8a06..cad719a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,24 +2,18 @@
FROM golang:1.19.6 AS builder
WORKDIR /
-# COPY . ./
-
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
-COPY vendor/ vendor/
+RUN go mod download
# Copy the go source
COPY main.go main.go
COPY api/ api/
-COPY pkg/cfg pkg/cfg/
-COPY pkg/util pkg/util/
-COPY pkg/ncmapi pkg/ncmapi/
-COPY pkg/provisioner pkg/provisioner/
-COPY pkg/controllers pkg/controllers/
+COPY pkg/ pkg/
# Build
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o builds/manager main.go
FROM scratch
diff --git a/Makefile b/Makefile
index a3ab653..22b4646 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
APP_NAME ?= ncm-issuer
APP_VERSION ?= 1.0.4
-BUILD_VERSION ?= 1.1.0
+BUILD_VERSION ?= dev
IMG ?= ${APP_NAME}:${BUILD_VERSION}
ENVTEST_K8S_VERSION ?= 1.22
@@ -125,9 +125,9 @@ pack-app: docker-save
cp -rf builds/$(APP_NAME)-images/*.tgz builds/$(APP_NAME)/images/
cp -rf helm/* builds/$(APP_NAME)/charts/$(APP_NAME)/
cp -rf release_notes.txt builds/$(APP_NAME)/
- cd builds && tar czvf ../${APP_NAME}-${APP_VERSION}-${BUILD_VERSION}.tgz $(APP_NAME)
+ cd builds && tar czvf ../${APP_NAME}-${APP_VERSION}-${BUILD_VERSION}.tar.gz $(APP_NAME)
clean:
rm -rf builds
- rm -rf ncm-issuer*.tgz
+ rm -rf ncm-issuer*.tar.gz
From a8f49a694ed86f6cf6c1610b273a99d7686164fb Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 14 Apr 2023 12:35:55 +0200
Subject: [PATCH 127/175] ci: add missing sonarcloud properties file
---
sonar-project.properties | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 sonar-project.properties
diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000..7e4380b
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,12 @@
+sonar.projectKey=nokia_ncm-issuer
+sonar.organization=nokia-open-source
+
+# This is the name and version displayed in the SonarCloud UI.
+#sonar.projectName=ncm-issuer
+#sonar.projectVersion=1.0
+
+# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
+#sonar.sources=.
+
+# Encoding of the source code. Default is default system encoding
+#sonar.sourceEncoding=UTF-8
\ No newline at end of file
From a8927734aadf166953a4a62b93a79020ac97524c Mon Sep 17 00:00:00 2001
From: raczu
Date: Fri, 21 Apr 2023 19:45:43 +0200
Subject: [PATCH 128/175] refactor: improve api selection algorithm
The previous way of selecting API was inefficient
and causes a lot of unnecessary requests to
not healthy endpoint. The new selection
algorithm is intented to check given APIs health
and make the request to health one - it is following
the rule the first alive is selected.
---
helm/templates/deployment/deployment.yaml | 2 +-
.../certificaterequest_controller.go | 16 +-
.../certificaterequest_controller_test.go | 20 +-
pkg/controllers/issuer_controller.go | 13 +-
pkg/controllers/util.go | 5 +
pkg/ncmapi/client.go | 2 +
pkg/ncmapi/ncmapi.go | 174 +++++++++----
pkg/ncmapi/ncmapi_test.go | 243 ++++++++++++++----
pkg/provisioner/ncm.go | 18 +-
pkg/provisioner/ncm_test.go | 10 +-
pkg/provisioner/provisioner.go | 1 +
test/unit/gen/ncm.go | 2 +
test/unit/gen/ncmapi.go | 4 +
13 files changed, 383 insertions(+), 127 deletions(-)
diff --git a/helm/templates/deployment/deployment.yaml b/helm/templates/deployment/deployment.yaml
index 9feb6ce..767bc68 100644
--- a/helm/templates/deployment/deployment.yaml
+++ b/helm/templates/deployment/deployment.yaml
@@ -33,7 +33,7 @@ spec:
{{- if and .Values.enableLeaderElection (gt (.Values.replicaCount | int64) 1) }}
- --leader-elect
{{- end }}
- image: {{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.version }}
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.imagePullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 3b09498..5d53a90 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -42,8 +42,8 @@ import (
)
const (
- GetCAsRequeueTime = time.Second * 30
- CSRRequeueTime = time.Minute
+ APIErrorRequeueTime = time.Second * 30
+ CSRRequeueTime = time.Minute
labelUnr = "unrecognised"
labelEnr = "enrollment"
@@ -264,12 +264,12 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
log.Info("Performing renewing operation", "certificate", cr.Annotations[cmapi.CertificateNameKey])
ca, tls, certID, err := p.Renew(cr, string(secretCertID.Data["cert-id"]))
if err != nil {
- if errors.Is(err, provisioner.ErrFailedGetCAs) {
+ if errorContains(err, "not reachable NCM API") {
log.Error(err, "Could not established connection with NCM API")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get CAs during renewal")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to establish connection with NCM API err: %v", err)
crmetrics.CertificateRequestFails.WithLabelValues(labelRen, labelTrue).Inc()
- return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, nil
+ return ctrl.Result{RequeueAfter: APIErrorRequeueTime}, nil
}
log.Error(err, "Failed to renew certificate")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to renew certificate err: %v", err)
@@ -295,12 +295,12 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
ca, tls, certID, err := p.Sign(cr)
if err != nil {
switch {
- case errors.Is(err, provisioner.ErrFailedGetCAs):
+ case errorContains(err, "not reachable NCM API"):
log.Error(err, "Could not established connection with NCM API")
- _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to get CAs during signing")
+ _ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to establish connection with NCM API err: %v", err)
crmetrics.CertificateRequestFails.WithLabelValues(labelEnr, labelTrue).Inc()
- return ctrl.Result{RequeueAfter: GetCAsRequeueTime}, nil
+ return ctrl.Result{RequeueAfter: APIErrorRequeueTime}, nil
case errors.Is(err, provisioner.ErrCSRNotAccepted):
log.Error(err, "CSR status in NCM is not yet expected one")
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CSR in NCM has not yet been approved")
diff --git a/pkg/controllers/certificaterequest_controller_test.go b/pkg/controllers/certificaterequest_controller_test.go
index bc7d558..ed98047 100644
--- a/pkg/controllers/certificaterequest_controller_test.go
+++ b/pkg/controllers/certificaterequest_controller_test.go
@@ -32,6 +32,10 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
+var (
+ errAPINotReachable = errors.New("not reachable NCM API")
+)
+
func TestCertificateRequestReconcile(t *testing.T) {
type testCase struct {
name string
@@ -668,7 +672,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
expectedConditionReason: cmapi.CertificateRequestReasonFailed,
},
{
- name: "failed-get-cas-during-signing",
+ name: "not-reachable-api-during-signing",
namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
objects: []client.Object{
@@ -778,10 +782,10 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
provisioner: gen.NewFakeProvisioner(
- gen.SetFakeProvisionerSignError(provisioner.ErrFailedGetCAs)),
- err: provisioner.ErrFailedGetCAs,
+ gen.SetFakeProvisionerSignError(errAPINotReachable)),
+ err: errAPINotReachable,
expectedResult: ctrl.Result{
- RequeueAfter: GetCAsRequeueTime,
+ RequeueAfter: APIErrorRequeueTime,
},
expectedConditionStatus: cmmeta.ConditionFalse,
expectedConditionReason: cmapi.CertificateRequestReasonPending,
@@ -1693,7 +1697,7 @@ func TestCertificateRequestReconcile(t *testing.T) {
expectedConditionReason: cmapi.CertificateRequestReasonIssued,
},
{
- name: "failed-get-cas-during-renewal",
+ name: "not-reachable-api-during-renewal",
namespacedName: types.NamespacedName{Namespace: "ncm-ns", Name: "cr"},
issuerName: types.NamespacedName{Namespace: "ncm-ns", Name: "ncm-issuer"},
objects: []client.Object{
@@ -1800,10 +1804,10 @@ func TestCertificateRequestReconcile(t *testing.T) {
},
},
provisioner: gen.NewFakeProvisioner(
- gen.SetFakeProvisionerRenewError(provisioner.ErrFailedGetCAs)),
- err: provisioner.ErrFailedGetCAs,
+ gen.SetFakeProvisionerRenewError(errAPINotReachable)),
+ err: errAPINotReachable,
expectedResult: ctrl.Result{
- RequeueAfter: GetCAsRequeueTime,
+ RequeueAfter: APIErrorRequeueTime,
},
expectedConditionStatus: cmmeta.ConditionFalse,
expectedConditionReason: cmapi.CertificateRequestReasonPending,
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index 8e43371..91bdc0e 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -19,6 +19,8 @@ package controllers
import (
"context"
"fmt"
+ "sigs.k8s.io/controller-runtime/pkg/event"
+ "sigs.k8s.io/controller-runtime/pkg/predicate"
"github.com/go-logr/logr"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
@@ -234,7 +236,12 @@ func (r *IssuerReconciler) SetupWithManager(mgr ctrl.Manager) error {
return err
}
- return ctrl.NewControllerManagedBy(mgr).
- For(issuerType).
- Complete(r)
+ return ctrl.NewControllerManagedBy(mgr).For(issuerType).WithEventFilter(predicate.Funcs{
+ DeleteFunc: func(e event.DeleteEvent) bool {
+ namespacedName := types.NamespacedName{Namespace: e.Object.GetNamespace(), Name: e.Object.GetName()}
+ r.Provisioners.Delete(namespacedName)
+ r.Log.Info("Removing stored provisioner for deleted issuer", "namespace", namespacedName.Namespace, "name", namespacedName.Name)
+ return false
+ },
+ }).Complete(r)
}
diff --git a/pkg/controllers/util.go b/pkg/controllers/util.go
index 66745f2..6ab9700 100644
--- a/pkg/controllers/util.go
+++ b/pkg/controllers/util.go
@@ -2,6 +2,7 @@ package controllers
import (
"fmt"
+ "strings"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
@@ -82,3 +83,7 @@ func validateCertificateRequest(cr *cmapi.CertificateRequest) error {
return nil
}
+
+func errorContains(err error, str string) bool {
+ return strings.Contains(err.Error(), str)
+}
diff --git a/pkg/ncmapi/client.go b/pkg/ncmapi/client.go
index d707d21..605a50b 100644
--- a/pkg/ncmapi/client.go
+++ b/pkg/ncmapi/client.go
@@ -12,4 +12,6 @@ type ExternalClient interface {
DownloadCertificate(path string) (*CertificateDownloadResponse, error)
DownloadCertificateInPEM(path string) ([]byte, error)
RenewCertificate(path string, duration *metav1.Duration, profileID string) (*RenewCertificateResponse, error)
+ StartHealthChecker()
+ StopHealthChecker()
}
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 90f5a1a..80d0237 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -5,6 +5,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/json"
+ "errors"
"fmt"
"io"
"mime/multipart"
@@ -13,6 +14,7 @@ import (
"os"
"path/filepath"
"strings"
+ "sync"
"time"
"github.com/go-logr/logr"
@@ -26,29 +28,58 @@ const (
DefaultHTTPTimeout = 10
CAsPath = "/v1/cas"
CSRPath = "/v1/requests"
+ healthy = "healthy"
+ unhealthy = "unhealthy"
)
+// ServerURL is used to store NCM API url and health status.
+type ServerURL struct {
+ url string
+ health string
+ mu sync.RWMutex
+}
+
+func NewServerURL(url string) *ServerURL {
+ return &ServerURL{url: url, health: healthy}
+}
+
+func (s *ServerURL) isHealthy() bool {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+ return s.health == healthy
+}
+
+func (s *ServerURL) setHealthy(isHealthy bool) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if isHealthy {
+ s.health = healthy
+ return
+ }
+ s.health = unhealthy
+}
+
// Client is a client used to communicate with the NCM API.
type Client struct {
- // NCMServer is a main NCM API server address
- NCMServer string
+ // mainAPI is a ServerURL which stores the url to NCM API
+ // and its healthiness.
+ mainAPI *ServerURL
+
+ // backupAPI is a ServerURL which stores the url to secondary
+ // NCM API in case of the lack of connection to the main
+ // one and its healthiness (can be empty).
+ backupAPI *ServerURL
- // NCMServer2 is a secondary NCM API server address
- // in case of the lack of connection to the main one (can be empty)
- NCMServer2 string
+ // stopChecking is used to stop checking the health of NCM APIs.
+ stopChecking chan bool
- // user is a user used for authentication to NCM API
+ // user is a user used for authentication to NCM API.
user string
- // password is a password used for authentication to NCM API
+ // password is a password used for authentication to NCM API.
password string
- // allowRetry determines whether, in the case of lack of the connection
- // to the main server (no response within a certain time period
- // or 5XX status code), there is an address of a second server to which
- // client can send the same request
- allowRetry bool
-
// useProfileIDForRenew determines whether the profile ID should be used
// during a certificate renewal operation
useProfileIDForRenew bool
@@ -124,14 +155,16 @@ func (a *APIError) Error() string {
// NewClient creates a new client used to perform requests to
// the NCM API.
func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
- NCMServerURL, err := url.Parse(cfg.NCMServer)
- if err != nil {
+ if _, err := url.Parse(cfg.NCMServer); err != nil {
return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
}
- NCMServer2URL, err := url.Parse(cfg.NCMServer2)
- if err != nil {
- return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
+ var backupAPI *ServerURL
+ if cfg.NCMServer2 != "" {
+ if _, err := url.Parse(cfg.NCMServer2); err != nil {
+ return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
+ }
+ backupAPI = NewServerURL(cfg.NCMServer2)
}
client, err := configureHTTPClient(cfg)
@@ -140,16 +173,16 @@ func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
}
c := &Client{
- NCMServer: NCMServerURL.String(),
- NCMServer2: NCMServer2URL.String(),
- allowRetry: cfg.NCMServer2 != "",
+ mainAPI: NewServerURL(cfg.NCMServer),
+ backupAPI: backupAPI,
+ stopChecking: make(chan bool),
user: cfg.Username,
password: cfg.Password,
useProfileIDForRenew: cfg.UseProfileIDForRenew,
client: client,
log: log,
}
-
+ c.StartHealthChecker()
return c, nil
}
@@ -202,34 +235,23 @@ func configureHTTPClient(cfg *cfg.NCMConfig) (*http.Client, error) {
return client, nil
}
-func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
- NCMServerURL, _ := url.Parse(c.NCMServer)
- NCMServerURL.Path = path
-
- req, err := http.NewRequest(method, NCMServerURL.String(), body)
- if err != nil {
- return nil, &ClientError{Reason: "cannot create new request", ErrorMessage: err}
- }
-
+func (c *Client) setHeaders(req *http.Request) {
req.SetBasicAuth(c.user, c.password)
req.Header.Set("Accept", "application/json")
req.Header.Set("Accept-Language", "en_US")
-
- return req, nil
}
-func (c *Client) retryRequest(req *http.Request) (*http.Response, error) {
- c.log.Info("retrying request to secondary NCM API", "serverURL", c.NCMServer2)
- NCMServer2URL, _ := url.Parse(c.NCMServer2)
- req.URL.Host = NCMServer2URL.Host
+func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {
+ parsedURL, _ := url.Parse(c.mainAPI.url)
+ parsedURL.Path = path
- resp, err := c.client.Do(req)
+ req, err := http.NewRequest(method, parsedURL.String(), body)
if err != nil {
- return nil, &ClientError{Reason: "cannot perform request", ErrorMessage: err}
+ return nil, &ClientError{Reason: "cannot create new request", ErrorMessage: err}
}
- c.log.Info("received response from secondary NCM API", "serverURL", c.NCMServer2, "status", resp.StatusCode)
+ c.setHeaders(req)
- return resp, nil
+ return req, nil
}
func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
@@ -254,29 +276,67 @@ func (c *Client) validateResponse(resp *http.Response) ([]byte, error) {
}
func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
- resp, err := c.client.Do(req)
- if err != nil {
- c.log.Info("main NCM API seems not responding", "serverURL", c.NCMServer, "err", err)
- if c.allowRetry {
- resp, err = c.retryRequest(req)
- if err != nil {
- return nil, err
- }
- return resp, err
+ if c.mainAPI.isHealthy() {
+ resp, err := c.client.Do(req)
+ if err != nil {
+ c.log.Error(err, "Main NCM API seems not responding", "url", c.mainAPI.url)
+ c.mainAPI.setHealthy(false)
+ return nil, &ClientError{Reason: "not reachable NCM API", ErrorMessage: err}
}
- return nil, err
- }
+ return resp, nil
- if c.allowRetry && resp.StatusCode >= 500 && resp.StatusCode < 600 {
- c.log.Info("main NCM API returned server error status code", "serverURL", c.NCMServer, "status", resp.StatusCode)
- resp, err = c.retryRequest(req)
+ } else if c.backupAPI != nil && c.backupAPI.isHealthy() {
+ parsedURL, _ := url.Parse(c.backupAPI.url)
+ req.URL.Host = parsedURL.Host
+
+ resp, err := c.client.Do(req)
if err != nil {
- return nil, err
+ c.log.Error(err, "Backup NCM API seems not responding", "url", c.backupAPI.url)
+ c.backupAPI.setHealthy(false)
+ return nil, &ClientError{Reason: "not reachable NCM API", ErrorMessage: err}
}
return resp, nil
}
- return resp, nil
+ return nil, &ClientError{Reason: "not reachable NCM APIs", ErrorMessage: errors.New("neither main NCM API nor backup NCM API are healthy")}
+}
+
+func (c *Client) StartHealthChecker() {
+ ticker := time.NewTicker(10 * time.Second)
+ c.log.Info("Starting health status checker")
+ go func() {
+ for {
+ select {
+ case <-c.stopChecking:
+ ticker.Stop()
+ return
+ case <-ticker.C:
+ c.mainAPI.setHealthy(c.isAPIHealthy(c.mainAPI.url))
+ if c.backupAPI != nil {
+ c.backupAPI.setHealthy(c.isAPIHealthy(c.backupAPI.url))
+ }
+ }
+ }
+ }()
+}
+
+// isAPIHealthy sends request for CAs to determine whether
+// NCM API is responding or not.
+func (c *Client) isAPIHealthy(apiUrl string) bool {
+ parsedURL, _ := url.Parse(apiUrl)
+ parsedURL.Path = CAsPath
+ req, _ := http.NewRequest(http.MethodGet, parsedURL.String(), strings.NewReader(url.Values{}.Encode()))
+ c.setHeaders(req)
+
+ if resp, err := c.client.Do(req); err != nil || resp.StatusCode >= 500 && resp.StatusCode < 600 {
+ return false
+ }
+ return true
+}
+
+func (c *Client) StopHealthChecker() {
+ c.log.Info("Stopping health status checker")
+ close(c.stopChecking)
}
func (c *Client) GetCAs() (*CAsResponse, error) {
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 47ceb98..0bd1bbc 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -80,6 +80,22 @@ Fcw3AnfkJ3p2
}
)
+func compareClients(c1, c2 *Client) bool {
+ if c1.mainAPI.url != c2.mainAPI.url {
+ return false
+ }
+
+ if c1.useProfileIDForRenew != c2.useProfileIDForRenew {
+ return false
+ }
+
+ if !reflect.DeepEqual(c1.client, c2.client) {
+ return false
+ }
+
+ return true
+}
+
func TestNewClientCreation(t *testing.T) {
type testCase struct {
name string
@@ -119,7 +135,7 @@ func TestNewClientCreation(t *testing.T) {
t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
}
- if tc.expectedClient != nil && !reflect.DeepEqual(tc.expectedClient, c) {
+ if tc.expectedClient != nil && !compareClients(tc.expectedClient, c) {
t.Fatalf("%s failed; created and expected client is not the same", tc.name)
}
}
@@ -162,9 +178,9 @@ func TestNewClientCreation(t *testing.T) {
},
err: nil,
expectedClient: &Client{
- NCMServer: "http://ncm-server.local",
- user: "ncm-user",
- password: "ncm-user-password",
+ mainAPI: NewServerURL("http://ncm-server.local"),
+ user: "ncm-user",
+ password: "ncm-user-password",
client: &http.Client{
Timeout: DefaultHTTPTimeout * time.Second,
},
@@ -181,9 +197,9 @@ func TestNewClientCreation(t *testing.T) {
},
err: nil,
expectedClient: &Client{
- NCMServer: "https://ncm-server.local",
- user: "ncm-user",
- password: "ncm-user-password",
+ mainAPI: NewServerURL("https://ncm-server.local"),
+ user: "ncm-user",
+ password: "ncm-user-password",
client: &http.Client{
Timeout: DefaultHTTPTimeout * time.Second,
Transport: &http.Transport{
@@ -203,9 +219,9 @@ func TestNewClientCreation(t *testing.T) {
},
err: nil,
expectedClient: &Client{
- NCMServer: "https://ncm-server.local",
- user: "ncm-user",
- password: "ncm-user-password",
+ mainAPI: NewServerURL("https://ncm-server.local"),
+ user: "ncm-user",
+ password: "ncm-user-password",
client: &http.Client{
Timeout: DefaultHTTPTimeout * time.Second,
Transport: &http.Transport{
@@ -230,9 +246,9 @@ func TestNewClientCreation(t *testing.T) {
},
err: nil,
expectedClient: &Client{
- NCMServer: "https://ncm-server.local",
- user: "ncm-user",
- password: "ncm-user-password",
+ mainAPI: NewServerURL("https://ncm-server.local"),
+ user: "ncm-user",
+ password: "ncm-user-password",
client: &http.Client{
Timeout: DefaultHTTPTimeout * time.Second,
Transport: &http.Transport{
@@ -379,6 +395,177 @@ func TestValidateResponse(t *testing.T) {
}
}
+func TestIsAPIHealthy(t *testing.T) {
+ type testCase struct {
+ name string
+ handler http.HandlerFunc
+ expectedIsHealthy bool
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ svr := httptest.NewServer(tc.handler)
+ defer svr.Close()
+
+ config := &cfg.NCMConfig{
+ NCMServer: svr.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+
+ c, _ := NewClient(config, testr.New(t))
+ isHealthy := c.isAPIHealthy(c.mainAPI.url)
+ if isHealthy != tc.expectedIsHealthy {
+ t.Fatalf("%s failed; expected API health to be %T; got %T", tc.name, tc.expectedIsHealthy, isHealthy)
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "api-is-healthy",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(cas)
+ }),
+ expectedIsHealthy: true,
+ },
+ {
+ name: "api-is-not-healthy",
+ handler: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ apiError := APIError{
+ Message: "Internal Server Error",
+ Status: 500,
+ StatusMessage: "Internal Server Error",
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ json.NewEncoder(w).Encode(apiError)
+ }),
+ expectedIsHealthy: false,
+ },
+ }
+
+ for _, tc := range testCases {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
+func TestDoRequest(t *testing.T) {
+ type testCase struct {
+ name string
+ handlerMainAPI http.HandlerFunc
+ handlerBackupAPI http.HandlerFunc
+ isBackupAPI bool
+ err error
+ }
+
+ run := func(t *testing.T, tc testCase) {
+ svrMain := httptest.NewServer(tc.handlerMainAPI)
+ defer svrMain.Close()
+
+ var config *cfg.NCMConfig
+ if tc.isBackupAPI {
+ svrBackup := httptest.NewServer(tc.handlerBackupAPI)
+ defer svrBackup.Close()
+ config = &cfg.NCMConfig{
+ NCMServer: svrMain.URL,
+ NCMServer2: svrBackup.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+ } else {
+ config = &cfg.NCMConfig{
+ NCMServer: svrMain.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ }
+ }
+
+ c, _ := NewClient(config, testr.New(t))
+ req, _ := c.newRequest(http.MethodGet, CAsPath, strings.NewReader(url.Values{}.Encode()))
+ _, err := c.doRequest(req)
+
+ if tc.err != nil && err != nil && !strings.Contains(err.Error(), tc.err.Error()) {
+ t.Errorf("%s failed; expected error containing %s; got %s", tc.name, tc.err.Error(), err.Error())
+ }
+ }
+
+ testCases := []testCase{
+ {
+ name: "main-api-is-healthy",
+ handlerMainAPI: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(cas)
+ }),
+ },
+ {
+ name: "main-api-is-not-healthy",
+ handlerMainAPI: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ apiError := APIError{
+ Message: "Internal Server Error",
+ Status: 500,
+ StatusMessage: "Internal Server Error",
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ json.NewEncoder(w).Encode(apiError)
+ }),
+ err: errors.New("not reachable NCM API"),
+ },
+ {
+ name: "backup-api-is-healthy",
+ handlerMainAPI: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ apiError := APIError{
+ Message: "Internal Server Error",
+ Status: 500,
+ StatusMessage: "Internal Server Error",
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusInternalServerError)
+ json.NewEncoder(w).Encode(apiError)
+ }),
+ handlerBackupAPI: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(cas)
+ }),
+ },
+ {
+ name: "none-api-is-healthy",
+ handlerMainAPI: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(cas)
+ }),
+ handlerBackupAPI: http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ json.NewEncoder(w).Encode(cas)
+ }),
+ err: errors.New("neither main NCM API nor backup NCM API are healthy"),
+ },
+ }
+
+ for _, tc := range testCases {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ run(t, tc)
+ })
+ }
+}
+
func TestGetCAs(t *testing.T) {
type testCase struct {
name string
@@ -550,33 +737,3 @@ func TestGetCA(t *testing.T) {
})
}
}
-
-//func TestSendCSR(t *testing.T) {
-// type testCase struct {
-// name string
-// }
-//}
-//
-//func TestCheckCSRStatus(t *testing.T) {
-// type testCase struct {
-// name string
-// }
-//}
-//
-//func TestDownloadCertificate(t *testing.T) {
-// type testCase struct {
-// name string
-// }
-//}
-//
-//func TestDownloadCertificateInPEM(t *testing.T) {
-// type testCase struct {
-// name string
-// }
-//}
-//
-//func TestRenewCertificate(t *testing.T) {
-// type testCase struct {
-// name string
-// }
-//}
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
index 72bf89a..29d0f55 100644
--- a/pkg/provisioner/ncm.go
+++ b/pkg/provisioner/ncm.go
@@ -26,7 +26,6 @@ const (
)
var (
- ErrFailedGetCAs = errors.New("failed to get CAs")
ErrCSRNotAccepted = errors.New("CSR has not been accepted yet")
ErrCSRRejected = errors.New("CSR has been rejected")
ErrCSRCheckLimitExceeded = errors.New("CSR has not been accepted for too long")
@@ -63,11 +62,20 @@ func (pm *ProvisionersMap) AddOrReplace(namespacedName types.NamespacedName, pro
} else {
// The existing provisioner has been found, but IssuerReconcile
// was triggered again, which may involve a change in configuration.
+ pm.Provisioners[namespacedName].Retire()
delete(pm.Provisioners, namespacedName)
pm.Provisioners[namespacedName] = provisioner
}
}
+func (pm *ProvisionersMap) Delete(namespacedName types.NamespacedName) {
+ pm.mu.Lock()
+ defer pm.mu.Unlock()
+
+ pm.Provisioners[namespacedName].Retire()
+ delete(pm.Provisioners, namespacedName)
+}
+
// Provisioner allows Sign or Renew certificate using NCMClient.
type Provisioner struct {
NCMConfig *cfg.NCMConfig
@@ -103,7 +111,7 @@ func NewProvisioner(ncmCfg *cfg.NCMConfig, log logr.Logger) (*Provisioner, error
func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string, error) {
casResponse, err := p.NCMClient.GetCAs()
if err != nil {
- return nil, nil, "", ErrFailedGetCAs
+ return nil, nil, "", fmt.Errorf("failed to get CAs, err: %w", err)
}
signingCA, found := findCA(casResponse, p.NCMConfig.CAsHref, p.NCMConfig.CAsName)
@@ -207,7 +215,7 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
func (p *Provisioner) Renew(cr *cmapi.CertificateRequest, certID string) ([]byte, []byte, string, error) {
casResponse, err := p.NCMClient.GetCAs()
if err != nil {
- return nil, nil, "", ErrFailedGetCAs
+ return nil, nil, "", fmt.Errorf("failed to get CAs, err: %w", err)
}
singingCA, found := findCA(casResponse, p.NCMConfig.CAsHref, p.NCMConfig.CAsName)
@@ -236,6 +244,10 @@ func (p *Provisioner) Renew(cr *cmapi.CertificateRequest, certID string) ([]byte
return ca, tls, renewCertResp.Certificate, nil
}
+func (p *Provisioner) Retire() {
+ p.NCMClient.StopHealthChecker()
+}
+
// getChainAndWantedCA gets PEM chain and CA certificate using NCMClient, those
// values are needed for both Sign and Renew operations. The order of bytes
// in PEM chain is defined by NCMConfig which also defines which CA certificate
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index a6e1cab..1e38bbc 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -54,6 +54,8 @@ var (
Request: []byte("-----BEGIN CERTIFICATE-----\nR3Qu3St...\n-----END CERTIFICATE-----\n"),
},
}
+
+ errFailedGetCAs = errors.New("failed to get CAs")
)
func TestFindCA(t *testing.T) {
@@ -337,14 +339,14 @@ func TestSign(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
- gen.SetFakeClientGetCAsError(ErrFailedGetCAs)),
+ gen.SetFakeClientGetCAsError(errFailedGetCAs)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
log: testr.New(t),
},
- err: ErrFailedGetCAs,
+ err: errFailedGetCAs,
expectedCA: []byte(""),
expectedTLS: []byte(""),
},
@@ -783,14 +785,14 @@ func TestRenew(t *testing.T) {
CAsHref: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
- gen.SetFakeClientGetCAsError(ErrFailedGetCAs)),
+ gen.SetFakeClientGetCAsError(errFailedGetCAs)),
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
mu: sync.RWMutex{},
},
log: testr.New(t),
},
- err: ErrFailedGetCAs,
+ err: errFailedGetCAs,
expectedCA: []byte(""),
expectedTLS: []byte(""),
},
diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go
index 1a3f46f..f640a84 100644
--- a/pkg/provisioner/provisioner.go
+++ b/pkg/provisioner/provisioner.go
@@ -7,4 +7,5 @@ import (
type ExternalProvisioner interface {
Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string, error)
Renew(cr *cmapi.CertificateRequest, certID string) ([]byte, []byte, string, error)
+ Retire()
}
diff --git a/test/unit/gen/ncm.go b/test/unit/gen/ncm.go
index 1aa1429..4729192 100644
--- a/test/unit/gen/ncm.go
+++ b/test/unit/gen/ncm.go
@@ -56,3 +56,5 @@ func (fp *FakeProvisioner) Sign(*cmapi.CertificateRequest) ([]byte, []byte, stri
func (fp *FakeProvisioner) Renew(*cmapi.CertificateRequest, string) ([]byte, []byte, string, error) {
return fp.RenewFn()
}
+
+func (fp *FakeProvisioner) Retire() {}
diff --git a/test/unit/gen/ncmapi.go b/test/unit/gen/ncmapi.go
index ff253a6..e980274 100644
--- a/test/unit/gen/ncmapi.go
+++ b/test/unit/gen/ncmapi.go
@@ -204,3 +204,7 @@ func (fc *FakeClient) DownloadCertificateInPEM(path string) ([]byte, error) {
func (fc *FakeClient) RenewCertificate(string, *metav1.Duration, string) (*ncmapi.RenewCertificateResponse, error) {
return fc.RenewCertificateFn()
}
+
+func (fc *FakeClient) StartHealthChecker() {}
+
+func (fc *FakeClient) StopHealthChecker() {}
From c142cbc2696c61b6a18e9271dea9a82637e1f08d Mon Sep 17 00:00:00 2001
From: raczu
Date: Sun, 23 Apr 2023 22:01:11 +0200
Subject: [PATCH 129/175] feat: add possibility to configure http client
timeout and health checker interval
There are new fields in the issuer's kinds to allow
defining the values of newly added configuration
options. Additionally, to better group the fields
responsible for various funcionalitites, a refactor
was made. The previous exisiting option, whose
way of definition has changed, can still be given
in the old way but the newest is prefered.
---
api/v1/clusterissuer_types.go | 12 +-
api/v1/issuer_types.go | 136 +++++++---
api/v1/zz_generated.deepcopy.go | 40 ++-
...tmanager.ncm.nokia.com_clusterissuers.yaml | 143 +++++++++--
.../certmanager.ncm.nokia.com_issuers.yaml | 143 +++++++++--
config/rbac/role.yaml | 11 -
...tmanager.ncm.nokia.com_clusterissuers.yaml | 153 +++++++++---
.../certmanager.ncm.nokia.com_issuers.yaml | 153 +++++++++---
main.go | 6 +-
pkg/cfg/ncmcfg.go | 144 ++++++++---
.../certificaterequest_controller.go | 8 +-
.../certificaterequest_controller_test.go | 235 ++++++++++++------
pkg/controllers/issuer_controller.go | 28 +--
pkg/controllers/issuer_controller_test.go | 84 +++++--
pkg/controllers/util.go | 8 +-
pkg/ncmapi/client.go | 4 +-
pkg/ncmapi/ncmapi.go | 32 +--
pkg/ncmapi/ncmapi_test.go | 131 ++++++----
pkg/provisioner/ncm.go | 4 +-
pkg/provisioner/ncm_test.go | 139 +++++++----
pkg/provisioner/util.go | 2 +-
test/unit/gen/ncmapi.go | 3 +-
22 files changed, 1180 insertions(+), 439 deletions(-)
diff --git a/api/v1/clusterissuer_types.go b/api/v1/clusterissuer_types.go
index c423670..383e655 100644
--- a/api/v1/clusterissuer_types.go
+++ b/api/v1/clusterissuer_types.go
@@ -20,12 +20,14 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-//+kubebuilder:object:root=true
-//+kubebuilder:subresource:status
-//+kubebuilder:resource:scope=Cluster,shortName=external-clusterissuer
-
// ClusterIssuer is the Schema for the clusterissuers API
-// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[0].status`
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,shortName=ncm-clusterissuer
+// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=`.metadata.creationTimestamp`
+// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[0].status`
+// +kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[0].reason`
+// +kubebuilder:printcolumn:name="Message",type=string,JSONPath=`.status.conditions[0].message`
type ClusterIssuer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
diff --git a/api/v1/issuer_types.go b/api/v1/issuer_types.go
index 3960723..a844b84 100644
--- a/api/v1/issuer_types.go
+++ b/api/v1/issuer_types.go
@@ -17,48 +17,83 @@ limitations under the License.
package v1
import (
+ core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// IssuerSpec defines the desired state of Issuer.
type IssuerSpec struct {
- // Define external NCM REST API URL here, as of now http/https are supported
- NCMServer string `json:"ncmSERVER"`
-
+ // !DEPRECATED from build version 1.1.0
// +optional
- // Secondary external NCM REST API URL in case of lack of connection to the main one
- NCMServer2 string `json:"ncmSERVER2"`
-
- // The name of the logical CA on the NCM instance.
- // make sure the names are unique across whole NCM installation
- CAsName string `json:"CASNAME"`
+ NCMServer string `json:"ncmSERVER,omitempty"`
+ // !DEPRECATED from build version 1.1.0
+ // +optional
+ NCMServer2 string `json:"ncmSERVER2,omitempty"`
- CAsHREF string `json:"CASHREF"`
- LittleEndian bool `json:"littleEndian"`
- ReenrollmentOnRenew bool `json:"reenrollmentOnRenew"`
- UseProfileIDForRenew bool `json:"useProfileIDForRenew"`
- NoRoot bool `json:"noRoot"`
- ChainInSigner bool `json:"chainInSigner"`
- OnlyEECert bool `json:"onlyEECert"`
+ // CAName is a name of an existing CA in the NCM API, which
+ // will be used to issue certificates.
+ // +optional
+ CAName string `json:"caName,omitempty"`
- // The secret which contains REST API username and password
- AuthSecretName string `json:"secretName"`
+ // CAID is a unique identifier for existing CA in the NCM API,
+ // which will be used to issue certificates.
+ // +kubebuilder:validation:Pattern=[\w=_\-]+$
+ // +optional
+ CAID string `json:"caID,omitempty"`
+ // !DEPRECATED from build version 1.1.0
+ // +optional
+ CAsName string `json:"CASNAME,omitempty"`
+ // !DEPRECATED from build version 1.1.0
+ // +optional
+ CAsHREF string `json:"CASHREF,omitempty"`
+
+ // LittleEndian specifies the byte order, setting it to true
+ // will ensure that bytes are stored in LE order otherwise
+ // BE order will be used.
+ // +kubebuilder:default=false
+ LittleEndian bool `json:"littleEndian,omitempty"`
+
+ // !DEPRECATED from build version 1.1.0 (use PK policy in CRT kind instead)
+ // +kubebuilder:default=false
+ ReenrollmentOnRenew bool `json:"reenrollmentOnRenew,omitempty"`
+
+ // UseProfileIDForRenew determines whether the profile ID should be used
+ // during a certificate renewal operation
+ // +kubebuilder:default=false
+ UseProfileIDForRenew bool `json:"useProfileIDForRenew,omitempty"`
+
+ // NoRoot determines whether issuing CA certificate should be included
+ // in issued certificate CA field instead of root CA certificate.
+ // +kubebuilder:default=false
+ NoRoot bool `json:"noRoot,omitempty"`
+
+ // ChainInSigner determines whether certificate chain should be included in
+ // issued certificate CA field (intermediate certificates +
+ // singing CA certificate + root CA certificate).
+ // +kubebuilder:default=false
+ ChainInSigner bool `json:"chainInSigner,omitempty"`
+
+ // OnlyEECert determines whether only end-entity certificate should be included
+ // in issued certificate TLS field.
+ // +kubebuilder:default=false
+ OnlyEECert bool `json:"onlyEECert,omitempty"`
+
+ // ProfileID is an entity profile ID in NCM API.
// +optional
- // ProfileID API parameter
ProfileID string `json:"profileId,omitempty"`
+ // Provisioner contains NCM provisioner configuration.
// +optional
- // The secret which contains TLS configuration to external NCM server
- // the secret must contain 3 fields:
- // CA certificate for root CA certificate; key, cert for client CA certificate and key pair.
- //
- // for https connection,
- // if the field is empty, InsecureSkipVerify is used.
- // if the field is with CA certificate only, CA certificate is used.
- // if the field are with CA certificate, key, cert and mTLS is used.
- TLSSecretName string `json:"tlsSecretName"`
+ Provisioner *NCMProvisioner `json:"provisioner,omitempty"`
+ // !DEPRECATED from build version 1.1.0
+ // +optional
+ TLSSecretName string `json:"tlsSecretName"`
+ // !DEPRECATED from build version 1.1.0
+ // +optional
+ AuthSecretName string `json:"secretName,omitempty"`
+ // !DEPRECATED from build version 1.1.0
// +optional
AuthNamespace string `json:"authNameSpace,omitempty"`
}
@@ -69,12 +104,14 @@ type IssuerStatus struct {
Conditions []IssuerCondition `json:"conditions,omitempty"`
}
-//+kubebuilder:object:root=true
-//+kubebuilder:subresource:status
-
// Issuer is the Schema for the issuers API
-// +kubebuilder:resource:shortName=external-issuer
-// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[0].status`
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:shortName=ncm-issuer
+// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=`.metadata.creationTimestamp`
+// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[0].status`
+// +kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[0].reason`
+// +kubebuilder:printcolumn:name="Message",type=string,JSONPath=`.status.conditions[0].message`
type Issuer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -92,6 +129,39 @@ type IssuerList struct {
Items []Issuer `json:"items"`
}
+type NCMProvisioner struct {
+ // MainAPI is the URL to the main NCM API.
+ MainAPI string `json:"mainAPI"`
+
+ // BackupAPI is the URL to the backup NCM API in case of
+ // the lack of connection to the main one.
+ // +optional
+ BackupAPI string `json:"backupAPI,omitempty"`
+
+ // HTTPClientTimeout is a maximum amount of time that the
+ // HTTP client will wait for a response from NCM API before
+ // aborting the request. By default, timeout is set to 10 seconds.
+ // +kubebuilder:default="10s"
+ HTTPClientTimeout metav1.Duration `json:"httpClientTimeout,omitempty"`
+
+ // HealthCheckerInterval is the time interval between each
+ // NCM API health check. By default, interval is set to 1 minute.
+ // +kubebuilder:default="1m"
+ HealthCheckerInterval metav1.Duration `json:"healthCheckerInterval,omitempty"`
+
+ // AuthRef is a reference to a Secret containing the credentials
+ // (user and password) needed for making requests to NCM API.
+ AuthRef *core.SecretReference `json:"authRef"`
+
+ // TLSRef is a reference to a Secret containing CA bundle used to
+ // verify connections to the NCM API. If the secret reference is not
+ // specified and selected protocol is HTTPS, InsecureSkipVerify
+ // will be used. Otherwise, TLS or mTLS connection will be used,
+ // depending on provided data.
+ // +optional
+ TLSRef *core.SecretReference `json:"tlsRef,omitempty"`
+}
+
// IssuerCondition contains condition information for an Issuer.
type IssuerCondition struct {
// Type of the condition, currently ('Ready').
diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go
index fcc9996..6bc0c8b 100644
--- a/api/v1/zz_generated.deepcopy.go
+++ b/api/v1/zz_generated.deepcopy.go
@@ -1,7 +1,8 @@
+//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
-Copyright 2022.
+Copyright 2021.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,6 +22,7 @@ limitations under the License.
package v1
import (
+ corev1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -29,7 +31,7 @@ func (in *ClusterIssuer) DeepCopyInto(out *ClusterIssuer) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
@@ -88,7 +90,7 @@ func (in *Issuer) DeepCopyInto(out *Issuer) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
@@ -164,6 +166,11 @@ func (in *IssuerList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IssuerSpec) DeepCopyInto(out *IssuerSpec) {
*out = *in
+ if in.Provisioner != nil {
+ in, out := &in.Provisioner, &out.Provisioner
+ *out = new(NCMProvisioner)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IssuerSpec.
@@ -197,3 +204,30 @@ func (in *IssuerStatus) DeepCopy() *IssuerStatus {
in.DeepCopyInto(out)
return out
}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NCMProvisioner) DeepCopyInto(out *NCMProvisioner) {
+ *out = *in
+ out.HTTPClientTimeout = in.HTTPClientTimeout
+ out.HealthCheckerInterval = in.HealthCheckerInterval
+ if in.AuthRef != nil {
+ in, out := &in.AuthRef, &out.AuthRef
+ *out = new(corev1.SecretReference)
+ **out = **in
+ }
+ if in.TLSRef != nil {
+ in, out := &in.TLSRef, &out.TLSRef
+ *out = new(corev1.SecretReference)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NCMProvisioner.
+func (in *NCMProvisioner) DeepCopy() *NCMProvisioner {
+ if in == nil {
+ return nil
+ }
+ out := new(NCMProvisioner)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/config/crd/bases/certmanager.ncm.nokia.com_clusterissuers.yaml b/config/crd/bases/certmanager.ncm.nokia.com_clusterissuers.yaml
index b86d24b..41746b8 100644
--- a/config/crd/bases/certmanager.ncm.nokia.com_clusterissuers.yaml
+++ b/config/crd/bases/certmanager.ncm.nokia.com_clusterissuers.yaml
@@ -1,10 +1,9 @@
-
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.4.1
+ controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: clusterissuers.certmanager.ncm.nokia.com
spec:
@@ -14,13 +13,22 @@ spec:
listKind: ClusterIssuerList
plural: clusterissuers
shortNames:
- - external-clusterissuer
+ - ncm-clusterissuer
singular: clusterissuer
scope: Cluster
versions:
- additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
- jsonPath: .status.conditions[0].status
- name: READY
+ name: Ready
+ type: string
+ - jsonPath: .status.conditions[0].reason
+ name: Reason
+ type: string
+ - jsonPath: .status.conditions[0].message
+ name: Message
type: string
name: v1
schema:
@@ -40,36 +48,129 @@ spec:
metadata:
type: object
spec:
- description: IssuerSpec defines the desired state of Issuer
+ description: IssuerSpec defines the desired state of Issuer.
properties:
+ CASHREF:
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
CASNAME:
- description: the name of the logical CA on the NCM instance. make
- sure the names are unique across whole NCM installation
+ description: '!DEPRECATED from build version 1.1.0'
type: string
authNameSpace:
+ description: '!DEPRECATED from build version 1.1.0'
type: string
+ caID:
+ description: CAID is a unique identifier for existing CA in the NCM
+ API, which will be used to issue certificates.
+ pattern: '[\w=_\-]+$'
+ type: string
+ caName:
+ description: CAName is a name of an existing CA in the NCM API, which
+ will be used to issue certificates.
+ type: string
+ chainInSigner:
+ default: false
+ description: ChainInSigner determines whether certificate chain should
+ be included in issued certificate CA field (intermediate certificates
+ + singing CA certificate + root CA certificate).
+ type: boolean
+ littleEndian:
+ default: false
+ description: LittleEndian specifies the byte order, setting it to
+ true will ensure that bytes are stored in LE order otherwise BE
+ order will be used.
+ type: boolean
ncmSERVER:
- description: Define external NCM REST API URL here, as of now http/https
- are supported
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
+ ncmSERVER2:
+ description: '!DEPRECATED from build version 1.1.0'
type: string
+ noRoot:
+ default: false
+ description: NoRoot determines whether issuing CA certificate should
+ be included in issued certificate CA field instead of root CA certificate.
+ type: boolean
+ onlyEECert:
+ default: false
+ description: OnlyEECert determines whether only end-entity certificate
+ should be included in issued certificate TLS field.
+ type: boolean
profileId:
- description: ProfileId API parameter
+ description: ProfileID is an entity profile ID in NCM API.
type: string
+ provisioner:
+ description: Provisioner contains NCM provisioner configuration.
+ properties:
+ authRef:
+ description: AuthRef is a reference to a Secret containing the
+ credentials (user and password) needed for making requests to
+ NCM API.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ backupAPI:
+ description: BackupAPI is the URL to the backup NCM API in case
+ of the lack of connection to the main one.
+ type: string
+ healthCheckerInterval:
+ default: 1m
+ description: HealthCheckerInterval is the time interval between
+ each NCM API health check. By default, interval is set to 1
+ minute.
+ type: string
+ httpClientTimeout:
+ default: 10s
+ description: HTTPClientTimeout is a maximum amount of time that
+ the HTTP client will wait for a response from NCM API before
+ aborting the request. By default, timeout is set to 10 seconds.
+ type: string
+ mainAPI:
+ description: MainAPI is the URL to the main NCM API.
+ type: string
+ tlsRef:
+ description: TLSRef is a reference to a Secret containing CA bundle
+ used to verify connections to the NCM API. If the secret reference
+ is not specified and selected protocol is HTTPS, InsecureSkipVerify
+ will be used. Otherwise, TLS or mTLS connection will be used,
+ depending on provided data.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ required:
+ - authRef
+ - mainAPI
+ type: object
+ reenrollmentOnRenew:
+ default: false
+ description: '!DEPRECATED from build version 1.1.0 (use PK policy
+ in CRT kind instead)'
+ type: boolean
secretName:
- description: the secret which contains REST API username and password
+ description: '!DEPRECATED from build version 1.1.0'
type: string
tlsSecretName:
- description: "the secret which contains TLS configuration to external
- NCM server the secret must contain 3 fields: cacert for root CA;
- key, cert for client CA and key pair. \n for https connection, if
- the field is absent, InsecureSkipVerify is used. if the field is
- with cacert only, cacert is used. if the field are with cacert,
- key,cert, mtls is used."
+ description: '!DEPRECATED from build version 1.1.0'
type: string
- required:
- - CASNAME
- - ncmSERVER
- - secretName
+ useProfileIDForRenew:
+ default: false
+ description: UseProfileIDForRenew determines whether the profile ID
+ should be used during a certificate renewal operation
+ type: boolean
type: object
status:
description: IssuerStatus defines the observed state of Issuer
diff --git a/config/crd/bases/certmanager.ncm.nokia.com_issuers.yaml b/config/crd/bases/certmanager.ncm.nokia.com_issuers.yaml
index ec603b0..9335818 100644
--- a/config/crd/bases/certmanager.ncm.nokia.com_issuers.yaml
+++ b/config/crd/bases/certmanager.ncm.nokia.com_issuers.yaml
@@ -1,10 +1,9 @@
-
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.4.1
+ controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: issuers.certmanager.ncm.nokia.com
spec:
@@ -14,13 +13,22 @@ spec:
listKind: IssuerList
plural: issuers
shortNames:
- - external-issuer
+ - ncm-issuer
singular: issuer
scope: Namespaced
versions:
- additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
- jsonPath: .status.conditions[0].status
- name: READY
+ name: Ready
+ type: string
+ - jsonPath: .status.conditions[0].reason
+ name: Reason
+ type: string
+ - jsonPath: .status.conditions[0].message
+ name: Message
type: string
name: v1
schema:
@@ -40,36 +48,129 @@ spec:
metadata:
type: object
spec:
- description: IssuerSpec defines the desired state of Issuer
+ description: IssuerSpec defines the desired state of Issuer.
properties:
+ CASHREF:
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
CASNAME:
- description: the name of the logical CA on the NCM instance. make
- sure the names are unique across whole NCM installation
+ description: '!DEPRECATED from build version 1.1.0'
type: string
authNameSpace:
+ description: '!DEPRECATED from build version 1.1.0'
type: string
+ caID:
+ description: CAID is a unique identifier for existing CA in the NCM
+ API, which will be used to issue certificates.
+ pattern: '[\w=_\-]+$'
+ type: string
+ caName:
+ description: CAName is a name of an existing CA in the NCM API, which
+ will be used to issue certificates.
+ type: string
+ chainInSigner:
+ default: false
+ description: ChainInSigner determines whether certificate chain should
+ be included in issued certificate CA field (intermediate certificates
+ + singing CA certificate + root CA certificate).
+ type: boolean
+ littleEndian:
+ default: false
+ description: LittleEndian specifies the byte order, setting it to
+ true will ensure that bytes are stored in LE order otherwise BE
+ order will be used.
+ type: boolean
ncmSERVER:
- description: Define external NCM REST API URL here, as of now http/https
- are supported
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
+ ncmSERVER2:
+ description: '!DEPRECATED from build version 1.1.0'
type: string
+ noRoot:
+ default: false
+ description: NoRoot determines whether issuing CA certificate should
+ be included in issued certificate CA field instead of root CA certificate.
+ type: boolean
+ onlyEECert:
+ default: false
+ description: OnlyEECert determines whether only end-entity certificate
+ should be included in issued certificate TLS field.
+ type: boolean
profileId:
- description: ProfileId API parameter
+ description: ProfileID is an entity profile ID in NCM API.
type: string
+ provisioner:
+ description: Provisioner contains NCM provisioner configuration.
+ properties:
+ authRef:
+ description: AuthRef is a reference to a Secret containing the
+ credentials (user and password) needed for making requests to
+ NCM API.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ backupAPI:
+ description: BackupAPI is the URL to the backup NCM API in case
+ of the lack of connection to the main one.
+ type: string
+ healthCheckerInterval:
+ default: 1m
+ description: HealthCheckerInterval is the time interval between
+ each NCM API health check. By default, interval is set to 1
+ minute.
+ type: string
+ httpClientTimeout:
+ default: 10s
+ description: HTTPClientTimeout is a maximum amount of time that
+ the HTTP client will wait for a response from NCM API before
+ aborting the request. By default, timeout is set to 10 seconds.
+ type: string
+ mainAPI:
+ description: MainAPI is the URL to the main NCM API.
+ type: string
+ tlsRef:
+ description: TLSRef is a reference to a Secret containing CA bundle
+ used to verify connections to the NCM API. If the secret reference
+ is not specified and selected protocol is HTTPS, InsecureSkipVerify
+ will be used. Otherwise, TLS or mTLS connection will be used,
+ depending on provided data.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ required:
+ - authRef
+ - mainAPI
+ type: object
+ reenrollmentOnRenew:
+ default: false
+ description: '!DEPRECATED from build version 1.1.0 (use PK policy
+ in CRT kind instead)'
+ type: boolean
secretName:
- description: the secret which contains REST API username and password
+ description: '!DEPRECATED from build version 1.1.0'
type: string
tlsSecretName:
- description: "the secret which contains TLS configuration to external
- NCM server the secret must contain 3 fields: cacert for root CA;
- key, cert for client CA and key pair. \n for https connection, if
- the field is absent, InsecureSkipVerify is used. if the field is
- with cacert only, cacert is used. if the field are with cacert,
- key,cert, mtls is used."
+ description: '!DEPRECATED from build version 1.1.0'
type: string
- required:
- - CASNAME
- - ncmSERVER
- - secretName
+ useProfileIDForRenew:
+ default: false
+ description: UseProfileIDForRenew determines whether the profile ID
+ should be used during a certificate renewal operation
+ type: boolean
type: object
status:
description: IssuerStatus defines the observed state of Issuer
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index f88fdfd..5abf748 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -1,4 +1,3 @@
-
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@@ -14,16 +13,6 @@ rules:
- get
- list
- watch
- - create
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates
- verbs:
- - get
- - list
- - watch
- apiGroups:
- cert-manager.io
resources:
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
index c74bfb2..41746b8 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_clusterissuers.yaml
@@ -1,10 +1,9 @@
-{{ if .Values.crdEnabled }}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.4.1
+ controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: clusterissuers.certmanager.ncm.nokia.com
spec:
@@ -14,13 +13,22 @@ spec:
listKind: ClusterIssuerList
plural: clusterissuers
shortNames:
- - external-clusterissuer
+ - ncm-clusterissuer
singular: clusterissuer
scope: Cluster
versions:
- additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
- jsonPath: .status.conditions[0].status
- name: READY
+ name: Ready
+ type: string
+ - jsonPath: .status.conditions[0].reason
+ name: Reason
+ type: string
+ - jsonPath: .status.conditions[0].message
+ name: Message
type: string
name: v1
schema:
@@ -40,53 +48,129 @@ spec:
metadata:
type: object
spec:
- description: IssuerSpec defines the desired state of Issuer
+ description: IssuerSpec defines the desired state of Issuer.
properties:
+ CASHREF:
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
CASNAME:
- description: the name of the logical CA on the NCM instance. make
- sure the names are unique across whole NCM installation
+ description: '!DEPRECATED from build version 1.1.0'
type: string
- CASHREF:
+ authNameSpace:
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
+ caID:
+ description: CAID is a unique identifier for existing CA in the NCM
+ API, which will be used to issue certificates.
+ pattern: '[\w=_\-]+$'
+ type: string
+ caName:
+ description: CAName is a name of an existing CA in the NCM API, which
+ will be used to issue certificates.
type: string
- littleEndian:
- type: boolean
- reenrollmentOnRenew:
- type: boolean
- useProfileIDForRenew:
- type: boolean
- noRoot:
- type: boolean
chainInSigner:
+ default: false
+ description: ChainInSigner determines whether certificate chain should
+ be included in issued certificate CA field (intermediate certificates
+ + singing CA certificate + root CA certificate).
type: boolean
- onlyEECert:
+ littleEndian:
+ default: false
+ description: LittleEndian specifies the byte order, setting it to
+ true will ensure that bytes are stored in LE order otherwise BE
+ order will be used.
type: boolean
- authNameSpace:
- type: string
ncmSERVER:
- description: Define external NCM REST API URL here, as of now http/https
- are supported
+ description: '!DEPRECATED from build version 1.1.0'
type: string
ncmSERVER2:
- description: Define secondary external NCM REST API URL in case of the lack of
- connection to the main one
+ description: '!DEPRECATED from build version 1.1.0'
type: string
+ noRoot:
+ default: false
+ description: NoRoot determines whether issuing CA certificate should
+ be included in issued certificate CA field instead of root CA certificate.
+ type: boolean
+ onlyEECert:
+ default: false
+ description: OnlyEECert determines whether only end-entity certificate
+ should be included in issued certificate TLS field.
+ type: boolean
profileId:
- description: ProfileId API parameter
+ description: ProfileID is an entity profile ID in NCM API.
type: string
+ provisioner:
+ description: Provisioner contains NCM provisioner configuration.
+ properties:
+ authRef:
+ description: AuthRef is a reference to a Secret containing the
+ credentials (user and password) needed for making requests to
+ NCM API.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ backupAPI:
+ description: BackupAPI is the URL to the backup NCM API in case
+ of the lack of connection to the main one.
+ type: string
+ healthCheckerInterval:
+ default: 1m
+ description: HealthCheckerInterval is the time interval between
+ each NCM API health check. By default, interval is set to 1
+ minute.
+ type: string
+ httpClientTimeout:
+ default: 10s
+ description: HTTPClientTimeout is a maximum amount of time that
+ the HTTP client will wait for a response from NCM API before
+ aborting the request. By default, timeout is set to 10 seconds.
+ type: string
+ mainAPI:
+ description: MainAPI is the URL to the main NCM API.
+ type: string
+ tlsRef:
+ description: TLSRef is a reference to a Secret containing CA bundle
+ used to verify connections to the NCM API. If the secret reference
+ is not specified and selected protocol is HTTPS, InsecureSkipVerify
+ will be used. Otherwise, TLS or mTLS connection will be used,
+ depending on provided data.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ required:
+ - authRef
+ - mainAPI
+ type: object
+ reenrollmentOnRenew:
+ default: false
+ description: '!DEPRECATED from build version 1.1.0 (use PK policy
+ in CRT kind instead)'
+ type: boolean
secretName:
- description: the secret which contains REST API username and password
+ description: '!DEPRECATED from build version 1.1.0'
type: string
tlsSecretName:
- description: "the secret which contains TLS configuration to external
- NCM server the secret must contain 3 fields: cacert for root CA;
- key, cert for client CA and key pair. \n for https connection, if
- the field is absent, InsecureSkipVerify is used. if the field is
- with cacert only, cacert is used. if the field are with cacert,
- key,cert, mtls is used."
+ description: '!DEPRECATED from build version 1.1.0'
type: string
- required:
- - ncmSERVER
- - secretName
+ useProfileIDForRenew:
+ default: false
+ description: UseProfileIDForRenew determines whether the profile ID
+ should be used during a certificate renewal operation
+ type: boolean
type: object
status:
description: IssuerStatus defines the observed state of Issuer
@@ -144,4 +228,3 @@ status:
plural: ""
conditions: []
storedVersions: []
-{{ end }}
diff --git a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
index e6a431f..9335818 100644
--- a/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
+++ b/helm/templates/crds/certmanager.ncm.nokia.com_issuers.yaml
@@ -1,10 +1,9 @@
-{{ if .Values.crdEnabled }}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.4.1
+ controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: issuers.certmanager.ncm.nokia.com
spec:
@@ -14,13 +13,22 @@ spec:
listKind: IssuerList
plural: issuers
shortNames:
- - external-issuer
+ - ncm-issuer
singular: issuer
scope: Namespaced
versions:
- additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
- jsonPath: .status.conditions[0].status
- name: READY
+ name: Ready
+ type: string
+ - jsonPath: .status.conditions[0].reason
+ name: Reason
+ type: string
+ - jsonPath: .status.conditions[0].message
+ name: Message
type: string
name: v1
schema:
@@ -40,53 +48,129 @@ spec:
metadata:
type: object
spec:
- description: IssuerSpec defines the desired state of Issuer
+ description: IssuerSpec defines the desired state of Issuer.
properties:
+ CASHREF:
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
CASNAME:
- description: the name of the logical CA on the NCM instance. make
- sure the names are unique across whole NCM installation
+ description: '!DEPRECATED from build version 1.1.0'
type: string
- CASHREF:
+ authNameSpace:
+ description: '!DEPRECATED from build version 1.1.0'
+ type: string
+ caID:
+ description: CAID is a unique identifier for existing CA in the NCM
+ API, which will be used to issue certificates.
+ pattern: '[\w=_\-]+$'
+ type: string
+ caName:
+ description: CAName is a name of an existing CA in the NCM API, which
+ will be used to issue certificates.
type: string
- littleEndian:
- type: boolean
- reenrollmentOnRenew:
- type: boolean
- useProfileIDForRenew:
- type: boolean
- noRoot:
- type: boolean
chainInSigner:
+ default: false
+ description: ChainInSigner determines whether certificate chain should
+ be included in issued certificate CA field (intermediate certificates
+ + singing CA certificate + root CA certificate).
type: boolean
- onlyEECert:
+ littleEndian:
+ default: false
+ description: LittleEndian specifies the byte order, setting it to
+ true will ensure that bytes are stored in LE order otherwise BE
+ order will be used.
type: boolean
- authNameSpace:
- type: string
ncmSERVER:
- description: Define external NCM REST API URL here, as of now http/https
- are supported
+ description: '!DEPRECATED from build version 1.1.0'
type: string
ncmSERVER2:
- description: Define secondary external NCM REST API URL in case of the
- lack of connection to the main one
+ description: '!DEPRECATED from build version 1.1.0'
type: string
+ noRoot:
+ default: false
+ description: NoRoot determines whether issuing CA certificate should
+ be included in issued certificate CA field instead of root CA certificate.
+ type: boolean
+ onlyEECert:
+ default: false
+ description: OnlyEECert determines whether only end-entity certificate
+ should be included in issued certificate TLS field.
+ type: boolean
profileId:
- description: ProfileId API parameter
+ description: ProfileID is an entity profile ID in NCM API.
type: string
+ provisioner:
+ description: Provisioner contains NCM provisioner configuration.
+ properties:
+ authRef:
+ description: AuthRef is a reference to a Secret containing the
+ credentials (user and password) needed for making requests to
+ NCM API.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ backupAPI:
+ description: BackupAPI is the URL to the backup NCM API in case
+ of the lack of connection to the main one.
+ type: string
+ healthCheckerInterval:
+ default: 1m
+ description: HealthCheckerInterval is the time interval between
+ each NCM API health check. By default, interval is set to 1
+ minute.
+ type: string
+ httpClientTimeout:
+ default: 10s
+ description: HTTPClientTimeout is a maximum amount of time that
+ the HTTP client will wait for a response from NCM API before
+ aborting the request. By default, timeout is set to 10 seconds.
+ type: string
+ mainAPI:
+ description: MainAPI is the URL to the main NCM API.
+ type: string
+ tlsRef:
+ description: TLSRef is a reference to a Secret containing CA bundle
+ used to verify connections to the NCM API. If the secret reference
+ is not specified and selected protocol is HTTPS, InsecureSkipVerify
+ will be used. Otherwise, TLS or mTLS connection will be used,
+ depending on provided data.
+ properties:
+ name:
+ description: name is unique within a namespace to reference
+ a secret resource.
+ type: string
+ namespace:
+ description: namespace defines the space within which the
+ secret name must be unique.
+ type: string
+ type: object
+ required:
+ - authRef
+ - mainAPI
+ type: object
+ reenrollmentOnRenew:
+ default: false
+ description: '!DEPRECATED from build version 1.1.0 (use PK policy
+ in CRT kind instead)'
+ type: boolean
secretName:
- description: the secret which contains REST API username and password
+ description: '!DEPRECATED from build version 1.1.0'
type: string
tlsSecretName:
- description: "the secret which contains TLS configuration to external
- NCM server the secret must contain 3 fields: cacert for root CA;
- key, cert for client CA and key pair. \n for https connection, if
- the field is absent, InsecureSkipVerify is used. if the field is
- with cacert only, cacert is used. if the field are with cacert,
- key,cert, mtls is used."
+ description: '!DEPRECATED from build version 1.1.0'
type: string
- required:
- - ncmSERVER
- - secretName
+ useProfileIDForRenew:
+ default: false
+ description: UseProfileIDForRenew determines whether the profile ID
+ should be used during a certificate renewal operation
+ type: boolean
type: object
status:
description: IssuerStatus defines the observed state of Issuer
@@ -144,4 +228,3 @@ status:
plural: ""
conditions: []
storedVersions: []
-{{ end }}
diff --git a/main.go b/main.go
index 458b53f..88253e7 100644
--- a/main.go
+++ b/main.go
@@ -99,7 +99,7 @@ func main() {
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Clock: clock.RealClock{},
- Recorder: mgr.GetEventRecorderFor("external-clusterIssuer-controller"),
+ Recorder: mgr.GetEventRecorderFor("ncm-clusterissuer-controller"),
Provisioners: provisioners,
Log: ctrl.Log.WithName("controllers").WithName("ClusterIssuer"),
}).SetupWithManager(mgr); err != nil {
@@ -112,7 +112,7 @@ func main() {
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Clock: clock.RealClock{},
- Recorder: mgr.GetEventRecorderFor("external-issuer-controller"),
+ Recorder: mgr.GetEventRecorderFor("ncm-issuer-controller"),
Provisioners: provisioners,
Log: ctrl.Log.WithName("controllers").WithName("Issuer"),
}).SetupWithManager(mgr); err != nil {
@@ -124,7 +124,7 @@ func main() {
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
Clock: clock.RealClock{},
- Recorder: mgr.GetEventRecorderFor("certificateRequests-controller"),
+ Recorder: mgr.GetEventRecorderFor("certificaterequests-controller"),
Provisioners: provisioners,
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
diff --git a/pkg/cfg/ncmcfg.go b/pkg/cfg/ncmcfg.go
index edcd3a7..f9078a7 100644
--- a/pkg/cfg/ncmcfg.go
+++ b/pkg/cfg/ncmcfg.go
@@ -2,21 +2,29 @@ package cfg
import (
"fmt"
+ "reflect"
"strings"
+ "time"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
ncmutil "github.com/nokia/ncm-issuer/pkg/util"
core "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/types"
+)
+
+const (
+ DefaultHTTPTimeout = 10 * time.Second
+ DefaultHealthCheckerInterval = time.Minute
)
// NCMConfig stores the configuration which defines the behaviour of ncm-issuer.
type NCMConfig struct {
- // NCMServer is a main NCM API server address.
- NCMServer string
+ // MainAPI is a main NCM API server address.
+ MainAPI string
- // NCMServer2 is a secondary NCM API server address
+ // BackupAPI is a secondary NCM API server address
// in case of the lack of connection to the main one (can be empty).
- NCMServer2 string
+ BackupAPI string
// Username is a username used for authentication to NCM API.
Username string
@@ -24,11 +32,13 @@ type NCMConfig struct {
// Password is a password used for authentication to NCM API.
Password string
- // CAsName is a CA certificate name which will issue generated certificates.
- CAsName string
+ // CAName is a name for an existing CA in NCM API, which will
+ // be used to issue certificates.
+ CAName string
- // CAsHREF is a CA certificate href which will issue generated certificates.
- CAsHref string
+ // CAID is a unique identifier for an existing CA in NCM API,
+ // which will be used to issue certificates.
+ CAID string
// ReenrollmentOnRenew determines whether during renewal certificate
// should be re-enrolled instead of renewed.
@@ -56,8 +66,22 @@ type NCMConfig struct {
// in tls.crt.
OnlyEECert bool
- // TLSSecretName is a secret which contains TLS configuration for the NCM API
- TLSSecretName string
+ // HTTPClientTimeout is a maximum amount of time that the
+ // HTTP client will wait for a response from NCM API before
+ // aborting the request.
+ HTTPClientTimeout time.Duration
+
+ // HealthCheckerInterval is the time interval between each
+ // NCM API health check.
+ HealthCheckerInterval time.Duration
+
+ // AuthNamespacedName is a NamespacedName that points to a secret
+ // which contains authentication data needed for making requests to NCM API.
+ AuthNamespacedName types.NamespacedName
+
+ // TLSNamespacedName is a NamespacedName that points to a secret
+ // which contains TLS configuration for the NCM API
+ TLSNamespacedName types.NamespacedName
// CACert is a TLS CA certificate.
CACert string
@@ -77,27 +101,42 @@ type NCMConfig struct {
}
func Initialise(issuerSpec *ncmv1.IssuerSpec) *NCMConfig {
- return &NCMConfig{
- NCMServer: strings.TrimSuffix(issuerSpec.NCMServer, "/"),
- NCMServer2: strings.TrimSuffix(issuerSpec.NCMServer2, "/"),
- Username: "",
- Password: "",
- CAsName: issuerSpec.CAsName,
- CAsHref: issuerSpec.CAsHREF,
- ReenrollmentOnRenew: issuerSpec.ReenrollmentOnRenew,
- ProfileID: issuerSpec.ProfileID,
- UseProfileIDForRenew: issuerSpec.UseProfileIDForRenew,
- LittleEndian: issuerSpec.LittleEndian,
- NoRoot: issuerSpec.NoRoot,
- ChainInSigner: issuerSpec.ChainInSigner,
- OnlyEECert: issuerSpec.OnlyEECert,
- TLSSecretName: issuerSpec.TLSSecretName,
- CACert: "",
- Key: "",
- Cert: "",
- InsecureSkipVerify: true,
- MTLS: false,
+ config := &NCMConfig{
+ Username: "",
+ Password: "",
+ CAName: issuerSpec.CAName,
+ CAID: issuerSpec.CAID,
+ ReenrollmentOnRenew: issuerSpec.ReenrollmentOnRenew,
+ ProfileID: issuerSpec.ProfileID,
+ UseProfileIDForRenew: issuerSpec.UseProfileIDForRenew,
+ LittleEndian: issuerSpec.LittleEndian,
+ NoRoot: issuerSpec.NoRoot,
+ ChainInSigner: issuerSpec.ChainInSigner,
+ OnlyEECert: issuerSpec.OnlyEECert,
+ HTTPClientTimeout: DefaultHTTPTimeout,
+ HealthCheckerInterval: DefaultHealthCheckerInterval,
+ AuthNamespacedName: types.NamespacedName{},
+ TLSNamespacedName: types.NamespacedName{},
+ CACert: "",
+ Key: "",
+ Cert: "",
+ InsecureSkipVerify: true,
+ MTLS: false,
+ }
+
+ if p := issuerSpec.Provisioner; p != nil {
+ config.MainAPI = strings.TrimSuffix(p.MainAPI, "/")
+ config.BackupAPI = strings.TrimSuffix(p.BackupAPI, "/")
+ config.HTTPClientTimeout = time.Duration(p.HTTPClientTimeout.Nanoseconds())
+ config.HealthCheckerInterval = time.Duration(p.HealthCheckerInterval.Nanoseconds())
+ config.AuthNamespacedName.Namespace, config.AuthNamespacedName.Name = p.AuthRef.Namespace, p.AuthRef.Name
+ if p.TLSRef != nil {
+ config.TLSNamespacedName.Namespace, config.TLSNamespacedName.Name = p.TLSRef.Namespace, p.TLSRef.Name
+ }
}
+
+ config.handleDeprecatedFields(issuerSpec)
+ return config
}
func (cfg *NCMConfig) AddAuthenticationData(secret *core.Secret) {
@@ -146,22 +185,59 @@ func (cfg *NCMConfig) AddTLSData(secret *core.Secret) error {
return nil
}
+func (cfg *NCMConfig) InjectNamespace(namespace string) {
+ if cfg.AuthNamespacedName.Namespace == "" {
+ cfg.AuthNamespacedName.Namespace = namespace
+ }
+
+ if cfg.TLSNamespacedName.Name != "" && cfg.TLSNamespacedName.Namespace == "" {
+ cfg.TLSNamespacedName.Namespace = namespace
+ }
+}
+
func (cfg *NCMConfig) Validate() error {
- if cfg.NCMServer == "" {
- return fmt.Errorf("incorrect NCM API address: missing ncmSERVER address")
+ if cfg.MainAPI == "" {
+ return fmt.Errorf("incorrect NCM API data: missing main API url")
}
if cfg.Username == "" || cfg.Password == "" {
return fmt.Errorf("incorrect authentication data: missing username or usrpassword")
}
- if cfg.CAsName == "" && cfg.CAsHref == "" {
+ if cfg.CAName == "" && cfg.CAID == "" {
return fmt.Errorf("incorrect signing CA certificate data: missing CANAME or CAHREF")
}
- if cfg.TLSSecretName != "" && cfg.CACert == "" && cfg.Key == "" && cfg.Cert == "" {
+ if !reflect.DeepEqual(cfg.TLSNamespacedName, types.NamespacedName{}) && cfg.CACert == "" && cfg.Key == "" && cfg.Cert == "" {
return fmt.Errorf("incorrect TLS data: missing cacert, key or cert in TLS secret")
}
return nil
}
+
+func (cfg *NCMConfig) handleDeprecatedFields(issuerSpec *ncmv1.IssuerSpec) {
+ if cfg.MainAPI == "" {
+ cfg.MainAPI = strings.TrimSuffix(issuerSpec.NCMServer, "/")
+ }
+
+ if cfg.BackupAPI == "" {
+ cfg.BackupAPI = strings.TrimSuffix(issuerSpec.NCMServer2, "/")
+ }
+
+ if cfg.CAName == "" {
+ cfg.CAName = issuerSpec.CAsName
+ }
+
+ if cfg.CAID == "" {
+ cfg.CAID = issuerSpec.CAsHREF
+ }
+
+ if reflect.DeepEqual(cfg.AuthNamespacedName, types.NamespacedName{}) {
+ cfg.AuthNamespacedName.Namespace = issuerSpec.AuthNamespace
+ cfg.AuthNamespacedName.Name = issuerSpec.AuthSecretName
+ }
+
+ if reflect.DeepEqual(cfg.TLSNamespacedName, types.NamespacedName{}) {
+ cfg.TLSNamespacedName.Name = issuerSpec.TLSSecretName
+ }
+}
diff --git a/pkg/controllers/certificaterequest_controller.go b/pkg/controllers/certificaterequest_controller.go
index 5d53a90..0e0a324 100644
--- a/pkg/controllers/certificaterequest_controller.go
+++ b/pkg/controllers/certificaterequest_controller.go
@@ -219,7 +219,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}
- secretName := cr.Annotations[cmapi.CertificateNameKey] + "-details"
+ crtSecret := cr.Annotations[cmapi.CertificateNameKey] + "-details"
// At the very beginning we should check the basic conditions that determines
// whether the operation of certificate renewal should take place
@@ -231,7 +231,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
isSecretWithCertID := false
secretCertID := &core.Secret{}
- if err = r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: secretName}, secretCertID); err != nil {
+ if err = r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: crtSecret}, secretCertID); err != nil {
if apierrors.IsNotFound(err) {
// This means that secret needed for renewal operations does not exist,
// and we should perform re-enrollment operation instead
@@ -278,7 +278,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, err
}
- secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
+ secretCertID = GetCertIDSecret(req.Namespace, crtSecret, certID)
if err = r.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update secret err: %v", err)
@@ -328,7 +328,7 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
}
}
- secretCertID = GetCertIDSecret(req.Namespace, secretName, certID)
+ secretCertID = GetCertIDSecret(req.Namespace, crtSecret, certID)
if isSecretWithCertID {
if err = r.Update(ctx, secretCertID); err != nil {
_ = r.setStatus(ctx, cr, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to update secret err: %v", err)
diff --git a/pkg/controllers/certificaterequest_controller_test.go b/pkg/controllers/certificaterequest_controller_test.go
index ed98047..075b7bc 100644
--- a/pkg/controllers/certificaterequest_controller_test.go
+++ b/pkg/controllers/certificaterequest_controller_test.go
@@ -10,6 +10,7 @@ import (
"errors"
"strings"
"testing"
+ "time"
"github.com/go-logr/logr/testr"
"github.com/google/go-cmp/cmp"
@@ -175,10 +176,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
},
&v1.Secret{
@@ -228,10 +234,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
},
&v1.Secret{
@@ -280,10 +291,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
},
&v1.Secret{
@@ -334,10 +350,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
},
&v1.Secret{
@@ -575,10 +596,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -641,10 +667,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -714,10 +745,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -833,10 +869,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -952,10 +993,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1068,10 +1114,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1184,10 +1235,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1300,10 +1356,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1415,10 +1476,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1521,10 +1587,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1624,10 +1695,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-cluster-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: metav1.NamespaceDefault,
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: metav1.NamespaceDefault,
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1739,10 +1815,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1855,10 +1936,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
@@ -1967,10 +2053,15 @@ func TestCertificateRequestReconcile(t *testing.T) {
Name: "ncm-cluster-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: metav1.NamespaceDefault,
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: metav1.NamespaceDefault,
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
Status: ncmv1.IssuerStatus{
Conditions: []ncmv1.IssuerCondition{
diff --git a/pkg/controllers/issuer_controller.go b/pkg/controllers/issuer_controller.go
index 91bdc0e..69f1410 100644
--- a/pkg/controllers/issuer_controller.go
+++ b/pkg/controllers/issuer_controller.go
@@ -19,8 +19,7 @@ package controllers
import (
"context"
"fmt"
- "sigs.k8s.io/controller-runtime/pkg/event"
- "sigs.k8s.io/controller-runtime/pkg/predicate"
+ "reflect"
"github.com/go-logr/logr"
ncmv1 "github.com/nokia/ncm-issuer/api/v1"
@@ -36,6 +35,8 @@ import (
"k8s.io/utils/clock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/event"
+ "sigs.k8s.io/controller-runtime/pkg/predicate"
)
// IssuerReconciler reconciles a Issuer object.
@@ -93,19 +94,11 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, nil
}
- secretName := types.NamespacedName{
- Name: issuerSpec.AuthSecretName,
- }
-
- secretName.Namespace, err = GetSecretNamespace(issuer, req)
- if err != nil {
- log.Error(err, "Unexpected issuer type. Not retrying.")
- return ctrl.Result{}, nil
- }
-
+ NCMCfg := cfg.Initialise(issuerSpec)
+ NCMCfg.InjectNamespace(GetSecretNamespace(issuer, req))
authSecret := &core.Secret{}
- if err = r.Get(ctx, secretName, authSecret); err != nil {
- log.Error(err, "Failed to retrieve auth secret", "namespace", secretName.Namespace, "name", secretName.Name)
+ if err = r.Get(ctx, NCMCfg.AuthNamespacedName, authSecret); err != nil {
+ log.Error(err, "Failed to retrieve auth secret", "namespace", NCMCfg.AuthNamespacedName.Namespace, "name", NCMCfg.AuthNamespacedName.Name)
if apierrors.IsNotFound(err) {
_ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "Failed to retrieve auth secret err: %v", err)
} else {
@@ -115,12 +108,11 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}
- NCMCfg := cfg.Initialise(issuerSpec)
NCMCfg.AddAuthenticationData(authSecret)
- if NCMCfg.TLSSecretName != "" {
+ if !reflect.DeepEqual(NCMCfg.TLSNamespacedName, types.NamespacedName{}) {
tlsSecret := &core.Secret{}
- if err = r.Get(ctx, client.ObjectKey{Namespace: secretName.Namespace, Name: NCMCfg.TLSSecretName}, tlsSecret); err != nil {
- log.Error(err, "Failed to retrieve TLS secret", "namespace", secretName.Namespace, "name", NCMCfg.TLSSecretName)
+ if err = r.Get(ctx, NCMCfg.TLSNamespacedName, tlsSecret); err != nil {
+ log.Error(err, "Failed to retrieve TLS secret", "namespace", NCMCfg.TLSNamespacedName.Namespace, "name", NCMCfg.TLSNamespacedName.Name)
if apierrors.IsNotFound(err) {
_ = r.SetStatus(ctx, issuer, ncmv1.ConditionFalse, "NotFound", "Failed to retrieve auth secret err: %v", err)
} else {
diff --git a/pkg/controllers/issuer_controller_test.go b/pkg/controllers/issuer_controller_test.go
index 6d71ca6..5b595a8 100644
--- a/pkg/controllers/issuer_controller_test.go
+++ b/pkg/controllers/issuer_controller_test.go
@@ -112,8 +112,12 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ Provisioner: &ncmv1.NCMProvisioner{
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ },
},
},
},
@@ -141,9 +145,13 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ },
},
},
&v1.Secret{
@@ -178,9 +186,15 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
- TLSSecretName: "ncm-tls-secret",
+ Provisioner: &ncmv1.NCMProvisioner{
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ TLSRef: &v1.SecretReference{
+ Name: "ncm-tls-secret",
+ },
+ },
},
},
&v1.Secret{
@@ -215,11 +229,17 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
- TLSSecretName: "ncm-tls-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ TLSRef: &v1.SecretReference{
+ Name: "ncm-tls-secret",
+ },
+ },
},
},
&v1.Secret{
@@ -264,10 +284,14 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:-8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:-8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ },
},
},
&v1.Secret{
@@ -305,10 +329,15 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: "ncm-ns",
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local:8081",
+ AuthRef: &v1.SecretReference{
+ Namespace: "ncm-ns",
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
},
&v1.Secret{
@@ -345,10 +374,15 @@ func TestIssuerReconcile(t *testing.T) {
Name: "ncm-cluster-issuer",
},
Spec: ncmv1.IssuerSpec{
- NCMServer: "https://ncm-server.local:8081",
- CAsName: "ncmCA",
- AuthNamespace: v1.NamespaceDefault,
- AuthSecretName: "ncm-auth-secret",
+ CAName: "ncmCA",
+ Provisioner: &ncmv1.NCMProvisioner{
+ MainAPI: "https://ncm-server.local",
+ AuthRef: &v1.SecretReference{
+ Namespace: v1.NamespaceDefault,
+ Name: "ncm-auth-secret",
+ },
+ HealthCheckerInterval: metav1.Duration{Duration: time.Minute},
+ },
},
},
&v1.Secret{
diff --git a/pkg/controllers/util.go b/pkg/controllers/util.go
index 6ab9700..2d48e77 100644
--- a/pkg/controllers/util.go
+++ b/pkg/controllers/util.go
@@ -24,17 +24,17 @@ func GetSpecAndStatus(issuer client.Object) (*ncmv1.IssuerSpec, *ncmv1.IssuerSta
}
}
-func GetSecretNamespace(issuer client.Object, req ctrl.Request) (string, error) {
+func GetSecretNamespace(issuer client.Object, req ctrl.Request) string {
switch t := issuer.(type) {
case *ncmv1.Issuer:
- return req.Namespace, nil
+ return req.Namespace
case *ncmv1.ClusterIssuer:
if t.Spec.AuthNamespace == "" {
t.Spec.AuthNamespace = metav1.NamespaceDefault
}
- return t.Spec.AuthNamespace, nil
+ return t.Spec.AuthNamespace
default:
- return "", fmt.Errorf("not an issuer type: %t", t)
+ return ""
}
}
diff --git a/pkg/ncmapi/client.go b/pkg/ncmapi/client.go
index 605a50b..05e58ed 100644
--- a/pkg/ncmapi/client.go
+++ b/pkg/ncmapi/client.go
@@ -1,6 +1,8 @@
package ncmapi
import (
+ "time"
+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -12,6 +14,6 @@ type ExternalClient interface {
DownloadCertificate(path string) (*CertificateDownloadResponse, error)
DownloadCertificateInPEM(path string) ([]byte, error)
RenewCertificate(path string, duration *metav1.Duration, profileID string) (*RenewCertificateResponse, error)
- StartHealthChecker()
+ StartHealthChecker(interval time.Duration)
StopHealthChecker()
}
diff --git a/pkg/ncmapi/ncmapi.go b/pkg/ncmapi/ncmapi.go
index 80d0237..c6b1c67 100644
--- a/pkg/ncmapi/ncmapi.go
+++ b/pkg/ncmapi/ncmapi.go
@@ -25,11 +25,10 @@ import (
)
const (
- DefaultHTTPTimeout = 10
- CAsPath = "/v1/cas"
- CSRPath = "/v1/requests"
- healthy = "healthy"
- unhealthy = "unhealthy"
+ CAsPath = "/v1/cas"
+ CSRPath = "/v1/requests"
+ healthy = "healthy"
+ unhealthy = "unhealthy"
)
// ServerURL is used to store NCM API url and health status.
@@ -155,16 +154,16 @@ func (a *APIError) Error() string {
// NewClient creates a new client used to perform requests to
// the NCM API.
func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
- if _, err := url.Parse(cfg.NCMServer); err != nil {
+ if _, err := url.Parse(cfg.MainAPI); err != nil {
return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
}
var backupAPI *ServerURL
- if cfg.NCMServer2 != "" {
- if _, err := url.Parse(cfg.NCMServer2); err != nil {
+ if cfg.BackupAPI != "" {
+ if _, err := url.Parse(cfg.BackupAPI); err != nil {
return nil, &ClientError{Reason: "cannot create new API client", ErrorMessage: err}
}
- backupAPI = NewServerURL(cfg.NCMServer2)
+ backupAPI = NewServerURL(cfg.BackupAPI)
}
client, err := configureHTTPClient(cfg)
@@ -173,7 +172,7 @@ func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
}
c := &Client{
- mainAPI: NewServerURL(cfg.NCMServer),
+ mainAPI: NewServerURL(cfg.MainAPI),
backupAPI: backupAPI,
stopChecking: make(chan bool),
user: cfg.Username,
@@ -182,16 +181,17 @@ func NewClient(cfg *cfg.NCMConfig, log logr.Logger) (*Client, error) {
client: client,
log: log,
}
- c.StartHealthChecker()
+
+ c.StartHealthChecker(cfg.HealthCheckerInterval)
return c, nil
}
// configureHTTPClient configures http.Client used for connection
// to NCM API according to NCM config.
func configureHTTPClient(cfg *cfg.NCMConfig) (*http.Client, error) {
- if !strings.HasPrefix(cfg.NCMServer, "https") {
+ if !strings.HasPrefix(cfg.MainAPI, "https") {
client := &http.Client{
- Timeout: DefaultHTTPTimeout * time.Second,
+ Timeout: cfg.HTTPClientTimeout,
}
return client, nil
@@ -226,7 +226,7 @@ func configureHTTPClient(cfg *cfg.NCMConfig) (*http.Client, error) {
// Creates an HTTPS client and supply it with created CA pool
// (and client CA if mTLS is enabled)
client := &http.Client{
- Timeout: DefaultHTTPTimeout * time.Second,
+ Timeout: cfg.HTTPClientTimeout,
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
@@ -301,8 +301,8 @@ func (c *Client) doRequest(req *http.Request) (*http.Response, error) {
return nil, &ClientError{Reason: "not reachable NCM APIs", ErrorMessage: errors.New("neither main NCM API nor backup NCM API are healthy")}
}
-func (c *Client) StartHealthChecker() {
- ticker := time.NewTicker(10 * time.Second)
+func (c *Client) StartHealthChecker(interval time.Duration) {
+ ticker := time.NewTicker(interval)
c.log.Info("Starting health status checker")
go func() {
for {
diff --git a/pkg/ncmapi/ncmapi_test.go b/pkg/ncmapi/ncmapi_test.go
index 0bd1bbc..686dc3d 100644
--- a/pkg/ncmapi/ncmapi_test.go
+++ b/pkg/ncmapi/ncmapi_test.go
@@ -144,7 +144,9 @@ func TestNewClientCreation(t *testing.T) {
{
name: "malformed-main-ncm-api-url",
config: &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local:-8081",
+ MainAPI: "https://ncm-server.local:-8081",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
},
err: errors.New("cannot create new API client"),
expectedClient: nil,
@@ -152,8 +154,10 @@ func TestNewClientCreation(t *testing.T) {
{
name: "malformed-backup-ncm-api-url",
config: &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- NCMServer2: "https://ncm-backup-server.local:-8081",
+ MainAPI: "https://ncm-server.local",
+ BackupAPI: "https://ncm-backup-server.local:-8081",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
},
err: errors.New("cannot create new API client"),
expectedClient: nil,
@@ -161,10 +165,12 @@ func TestNewClientCreation(t *testing.T) {
{
name: "cert-and-key-for-mtls-do-not-exist",
config: &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- CACert: rootCA,
- Key: "ncm-certificate-key.pem",
- Cert: "ncm-certificate.pem",
+ MainAPI: "https://ncm-server.local",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CACert: rootCA,
+ Key: "ncm-certificate-key.pem",
+ Cert: "ncm-certificate.pem",
},
err: errors.New("no such file or directory"),
expectedClient: nil,
@@ -172,9 +178,11 @@ func TestNewClientCreation(t *testing.T) {
{
name: "ncm-client-success-insecure-connection",
config: &cfg.NCMConfig{
- NCMServer: "http://ncm-server.local",
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: "http://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
},
err: nil,
expectedClient: &Client{
@@ -182,7 +190,7 @@ func TestNewClientCreation(t *testing.T) {
user: "ncm-user",
password: "ncm-user-password",
client: &http.Client{
- Timeout: DefaultHTTPTimeout * time.Second,
+ Timeout: 10 * time.Second,
},
log: testr.New(t),
},
@@ -190,10 +198,12 @@ func TestNewClientCreation(t *testing.T) {
{
name: "ncm-client-success-insecure-skip-verify",
config: &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- Username: "ncm-user",
- Password: "ncm-user-password",
- InsecureSkipVerify: true,
+ MainAPI: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ InsecureSkipVerify: true,
},
err: nil,
expectedClient: &Client{
@@ -201,7 +211,7 @@ func TestNewClientCreation(t *testing.T) {
user: "ncm-user",
password: "ncm-user-password",
client: &http.Client{
- Timeout: DefaultHTTPTimeout * time.Second,
+ Timeout: 10 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
@@ -212,18 +222,21 @@ func TestNewClientCreation(t *testing.T) {
{
name: "ncm-client-success-tls-connection",
config: &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- Username: "ncm-user",
- Password: "ncm-user-password",
- CACert: rootCA,
+ MainAPI: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CACert: rootCA,
},
err: nil,
expectedClient: &Client{
mainAPI: NewServerURL("https://ncm-server.local"),
user: "ncm-user",
password: "ncm-user-password",
+
client: &http.Client{
- Timeout: DefaultHTTPTimeout * time.Second,
+ Timeout: 10 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: CACertPool,
@@ -236,13 +249,15 @@ func TestNewClientCreation(t *testing.T) {
{
name: "ncm-client-success-mtls-connection",
config: &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- Username: "ncm-user",
- Password: "ncm-user-password",
- CACert: rootCA,
- MTLS: true,
- Cert: certFile.Name(),
- Key: certKey.Name(),
+ MainAPI: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CACert: rootCA,
+ MTLS: true,
+ Cert: certFile.Name(),
+ Key: certKey.Name(),
},
err: nil,
expectedClient: &Client{
@@ -250,7 +265,7 @@ func TestNewClientCreation(t *testing.T) {
user: "ncm-user",
password: "ncm-user-password",
client: &http.Client{
- Timeout: DefaultHTTPTimeout * time.Second,
+ Timeout: 10 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: CACertPool,
@@ -280,9 +295,11 @@ func TestNewRequestCreation(t *testing.T) {
run := func(t *testing.T, tc testCase) {
config := &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
c, _ := NewClient(config, testr.New(t))
@@ -330,9 +347,11 @@ func TestValidateResponse(t *testing.T) {
run := func(t *testing.T, tc testCase) {
config := &cfg.NCMConfig{
- NCMServer: "https://ncm-server.local",
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: "https://ncm-server.local",
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
c, _ := NewClient(config, testr.New(t))
@@ -407,9 +426,11 @@ func TestIsAPIHealthy(t *testing.T) {
defer svr.Close()
config := &cfg.NCMConfig{
- NCMServer: svr.URL,
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: svr.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
c, _ := NewClient(config, testr.New(t))
@@ -473,16 +494,20 @@ func TestDoRequest(t *testing.T) {
svrBackup := httptest.NewServer(tc.handlerBackupAPI)
defer svrBackup.Close()
config = &cfg.NCMConfig{
- NCMServer: svrMain.URL,
- NCMServer2: svrBackup.URL,
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: svrMain.URL,
+ BackupAPI: svrBackup.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
} else {
config = &cfg.NCMConfig{
- NCMServer: svrMain.URL,
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: svrMain.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
}
@@ -579,9 +604,11 @@ func TestGetCAs(t *testing.T) {
defer svr.Close()
config := &cfg.NCMConfig{
- NCMServer: svr.URL,
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: svr.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
c, _ := NewClient(config, testr.New(t))
@@ -665,9 +692,11 @@ func TestGetCA(t *testing.T) {
defer svr.Close()
config := &cfg.NCMConfig{
- NCMServer: svr.URL,
- Username: "ncm-user",
- Password: "ncm-user-password",
+ MainAPI: svr.URL,
+ Username: "ncm-user",
+ Password: "ncm-user-password",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
}
c, _ := NewClient(config, testr.New(t))
diff --git a/pkg/provisioner/ncm.go b/pkg/provisioner/ncm.go
index 29d0f55..a0d7da3 100644
--- a/pkg/provisioner/ncm.go
+++ b/pkg/provisioner/ncm.go
@@ -114,7 +114,7 @@ func (p *Provisioner) Sign(cr *cmapi.CertificateRequest) ([]byte, []byte, string
return nil, nil, "", fmt.Errorf("failed to get CAs, err: %w", err)
}
- signingCA, found := findCA(casResponse, p.NCMConfig.CAsHref, p.NCMConfig.CAsName)
+ signingCA, found := findCA(casResponse, p.NCMConfig.CAID, p.NCMConfig.CAName)
if !found {
return nil, nil, "", fmt.Errorf("CA certificate with the given HREF or NAME has not been found")
}
@@ -218,7 +218,7 @@ func (p *Provisioner) Renew(cr *cmapi.CertificateRequest, certID string) ([]byte
return nil, nil, "", fmt.Errorf("failed to get CAs, err: %w", err)
}
- singingCA, found := findCA(casResponse, p.NCMConfig.CAsHref, p.NCMConfig.CAsName)
+ singingCA, found := findCA(casResponse, p.NCMConfig.CAID, p.NCMConfig.CAName)
if !found {
return nil, nil, "", fmt.Errorf("CA certificate with the given HREF or NAME has not been found")
}
diff --git a/pkg/provisioner/ncm_test.go b/pkg/provisioner/ncm_test.go
index 1e38bbc..e8e7ee2 100644
--- a/pkg/provisioner/ncm_test.go
+++ b/pkg/provisioner/ncm_test.go
@@ -5,6 +5,7 @@ import (
"strings"
"sync"
"testing"
+ "time"
"github.com/go-logr/logr/testr"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
@@ -61,15 +62,15 @@ var (
func TestFindCA(t *testing.T) {
type testCase struct {
name string
- CAsHref string
- CAsName string
+ CAID string
+ CAName string
CAsResponse *ncmapi.CAsResponse
isFindable bool
expectedCA *ncmapi.CAResponse
}
run := func(t *testing.T, tc testCase) {
- _, found := findCA(tc.CAsResponse, tc.CAsHref, tc.CAsName)
+ _, found := findCA(tc.CAsResponse, tc.CAID, tc.CAName)
if tc.isFindable != found {
t.Fatalf("%s failed; expected (not) to find CA certificate; got %t; want %t", tc.name, found, tc.isFindable)
@@ -79,48 +80,48 @@ func TestFindCA(t *testing.T) {
testCases := []testCase{
{
name: "cas-name-success",
- CAsHref: "",
- CAsName: "ncmCA2",
+ CAID: "",
+ CAName: "ncmCA2",
CAsResponse: CAsResponse,
isFindable: true,
expectedCA: &crt2,
},
{
name: "cas-href-success",
- CAsHref: "Mn012Se",
- CAsName: "",
+ CAID: "Mn012Se",
+ CAName: "",
CAsResponse: CAsResponse,
isFindable: true,
expectedCA: &crt1,
},
{
name: "cas-name-case-sensitive",
- CAsHref: "",
- CAsName: "NCMca2",
+ CAID: "",
+ CAName: "NCMca2",
CAsResponse: CAsResponse,
isFindable: false,
expectedCA: &ncmapi.CAResponse{},
},
{
name: "cas-href-case-sensitive",
- CAsHref: "mN012sE",
- CAsName: "",
+ CAID: "mN012sE",
+ CAName: "",
CAsResponse: CAsResponse,
isFindable: false,
expectedCA: &ncmapi.CAResponse{},
},
{
name: "found-ca-not-active",
- CAsHref: "efG312Ed",
- CAsName: "ncmCA3",
+ CAID: "efG312Ed",
+ CAName: "ncmCA3",
CAsResponse: CAsResponse,
isFindable: false,
expectedCA: &ncmapi.CAResponse{},
},
{
name: "empty-cas-name-and-href",
- CAsHref: "",
- CAsName: "",
+ CAID: "",
+ CAName: "",
CAsResponse: CAsResponse,
isFindable: false,
expectedCA: &ncmapi.CAResponse{},
@@ -146,7 +147,10 @@ func TestGetChainAndWantedCA(t *testing.T) {
run := func(t *testing.T, tc testCase) {
p := &Provisioner{
- NCMConfig: &cfg.NCMConfig{},
+ NCMConfig: &cfg.NCMConfig{
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ },
NCMClient: tc.fakeClient,
pendingCSRs: &PendingCSRsMap{
pendingCSRs: map[string]*PendingCSR{},
@@ -243,15 +247,20 @@ func TestPreparingCAAndTLS(t *testing.T) {
testCases := []testCase{
{
- name: "all-manipulation-data-set-to-false",
- config: &cfg.NCMConfig{},
+ name: "all-manipulation-data-set-to-false",
+ config: &cfg.NCMConfig{
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ },
expectedCA: rootCA,
expectedTLS: append(leafCert, append(signingCA, interCA...)...),
},
{
name: "littleendian-set-to-true",
config: &cfg.NCMConfig{
- LittleEndian: true,
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ LittleEndian: true,
},
expectedCA: rootCA,
expectedTLS: append(interCA, append(signingCA, leafCert...)...),
@@ -259,7 +268,9 @@ func TestPreparingCAAndTLS(t *testing.T) {
{
name: "chaininsigner-set-to-true",
config: &cfg.NCMConfig{
- ChainInSigner: true,
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ ChainInSigner: true,
},
expectedCA: append(signingCA, append(interCA, rootCA...)...),
expectedTLS: append(leafCert, append(signingCA, interCA...)...),
@@ -267,8 +278,10 @@ func TestPreparingCAAndTLS(t *testing.T) {
{
name: "littleendian-and-chaininsigner-set-to-true",
config: &cfg.NCMConfig{
- LittleEndian: true,
- ChainInSigner: true,
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ LittleEndian: true,
+ ChainInSigner: true,
},
expectedCA: append(rootCA, append(interCA, signingCA...)...),
expectedTLS: append(interCA, append(signingCA, leafCert...)...),
@@ -276,7 +289,9 @@ func TestPreparingCAAndTLS(t *testing.T) {
{
name: "onlyeecert-set-to-true",
config: &cfg.NCMConfig{
- OnlyEECert: true,
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ OnlyEECert: true,
},
expectedCA: rootCA,
expectedTLS: leafCert,
@@ -284,8 +299,10 @@ func TestPreparingCAAndTLS(t *testing.T) {
{
name: "chaininsigner-and-onlyeecert-set-to-true",
config: &cfg.NCMConfig{
- ChainInSigner: true,
- OnlyEECert: true,
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ ChainInSigner: true,
+ OnlyEECert: true,
},
expectedCA: append(signingCA, append(interCA, rootCA...)...),
expectedTLS: leafCert,
@@ -336,7 +353,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAsError(errFailedGetCAs)),
@@ -355,7 +374,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "eFgEf12",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "eFgEf12",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -377,7 +398,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -400,7 +423,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -424,7 +449,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -448,7 +475,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -472,7 +501,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -496,7 +527,9 @@ func TestSign(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -556,7 +589,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -583,7 +618,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -610,7 +647,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -637,7 +676,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -664,7 +705,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -691,7 +734,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -718,7 +763,9 @@ func TestHandlingCSR(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -782,7 +829,9 @@ func TestRenew(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAsError(errFailedGetCAs)),
@@ -801,7 +850,9 @@ func TestRenew(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
@@ -825,7 +876,9 @@ func TestRenew(t *testing.T) {
cr: &cr,
p: &Provisioner{
NCMConfig: &cfg.NCMConfig{
- CAsHref: "Mn012Se",
+ HTTPClientTimeout: 10 * time.Second,
+ HealthCheckerInterval: time.Minute,
+ CAID: "Mn012Se",
},
NCMClient: gen.NewFakeClient(
gen.SetFakeClientGetCAs(CAsResponse),
diff --git a/pkg/provisioner/util.go b/pkg/provisioner/util.go
index 21241eb..9031365 100644
--- a/pkg/provisioner/util.go
+++ b/pkg/provisioner/util.go
@@ -9,7 +9,7 @@ import (
)
func findCA(casResponse *ncmapi.CAsResponse, casHref, casName string) (*ncmapi.CAResponse, bool) {
- hrefRegex := regexp.MustCompile(`[\d\w=_\-]+$`)
+ hrefRegex := regexp.MustCompile(`[\w=_\-]+$`)
for _, ca := range casResponse.CAList {
if strings.EqualFold(ca.Status, "active") {
if casHref != "" {
diff --git a/test/unit/gen/ncmapi.go b/test/unit/gen/ncmapi.go
index e980274..c62c72b 100644
--- a/test/unit/gen/ncmapi.go
+++ b/test/unit/gen/ncmapi.go
@@ -3,6 +3,7 @@ package gen
import (
"fmt"
"strings"
+ "time"
"github.com/nokia/ncm-issuer/pkg/ncmapi"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -205,6 +206,6 @@ func (fc *FakeClient) RenewCertificate(string, *metav1.Duration, string) (*ncmap
return fc.RenewCertificateFn()
}
-func (fc *FakeClient) StartHealthChecker() {}
+func (fc *FakeClient) StartHealthChecker(interval time.Duration) {}
func (fc *FakeClient) StopHealthChecker() {}
From f4338ca63323d60e467b3740cbf71b95f782e4ad Mon Sep 17 00:00:00 2001
From: raczu
Date: Tue, 25 Apr 2023 22:24:24 +0200
Subject: [PATCH 130/175] docs: update README
---
README.md | 407 ++++++++++++++++++++++---------------
assets/ncm-issuer-logo.png | Bin 0 -> 472247 bytes
2 files changed, 241 insertions(+), 166 deletions(-)
create mode 100644 assets/ncm-issuer-logo.png
diff --git a/README.md b/README.md
index 1005ff5..8f4298c 100644
--- a/README.md
+++ b/README.md
@@ -1,225 +1,300 @@
-# NCM Issuer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-NCM Issuer cert-manager plugin allows to integrate with [Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/) PKI system.
-
-Cert-manager is a native Kubernetes certificate management controller which allows applications to get their certificates from a variety of CAs (Certification Authorities). It ensures certificates are valid and up to date, it also attempts to renew certificates at a configured time before expiration.
-
-## Requirements
-
-### To build
-
-- **[Golang](https://go.dev/doc/install)** 1.19.6
-- **[Make](https://www.gnu.org/software/make/)**
-- **[Docker](https://docs.docker.com/engine/install/)** >= 20.10.0
-
-> **IMPORTANT:** if you use CentOS/RedHat/Fedora do not use the default one, but install docker-ce
-
-### To use
-
-- **[NCM 21 release](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/)** (or higher)
-- **[kubernetes](https://kubernetes.io/)** 1.18-1.26
-- **[cert-manager](https://cert-manager.io/docs/installation/)** >= 1.0.0
-- **[Helm](https://helm.sh/docs/intro/install/)** v3
-
-## Build from source
-
-Building process generates a docker image that can be loaded at target machine.
-
-1. Download the source code
-2. Vendor dependencies
-
- ```bash
- $ go mod vendor
- ```
-
-3. Create an image
-
- ```bash
- $ make docker_build_img
- ```
-
-4. Save the image
-
- ```bash
- $ make save
- ```
-
-The image of NCM Issuer will be saved in ./builds/ncm-issuer-images/ directory.
-
-## Installation
-
-NCM Issuer uses Helm chart in installation process. You can read more about Helm [here](https://helm.sh/).
-
-1. Load an image with NCM Issuer (however charts already point to public docker registry, so it should be loaded automatically)
-
- ```bash
- $ docker load -i IMAGE_NAME
- ```
-
-2. Create a namespace for NCM Issuer resources
-
- ```bash
- $ kubectl create namespace ncm-issuer
- ```
-
-3. Install package using Helm
-
- ```bash
- $ helm install -n ncm-issuer ncm-issuer ./helm/.
- ```
-
-To check if the package has been installed properly type:
-
+
+
+# NCM-ISSUER
+
+![Release](https://img.shields.io/github/v/release/nokia/ncm-issuer)
+![Build version](https://img.shields.io/docker/v/misiektoja/ncm-issuer/latest?label=build-version)
+
+[![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=nokia_ncm-issuer)](https://sonarcloud.io/summary/new_code?id=nokia_ncm-issuer)
+[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=nokia_ncm-issuer&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=nokia_ncm-issuer)
+[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=nokia_ncm-issuer&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=nokia_ncm-issuer)
+[![Go Report Card](https://goreportcard.com/badge/github.com/nokia/ncm-issuer)](https://goreportcard.com/report/github.com/nokia/ncm-issuer)
+
+
+
+
+
+NCM-ISSUER is a [Kubernetes](https://kuberenets.io) controller (external [cert-manager](https://cert-manager.io/) issuer) that allows to integrate with
+[Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/)
+PKI system to sign certificate requests. The use of integration with NCM makes it easy to obtain certificates for
+applications and to ensure that they are valid and up to date.
+
+## Table of contents
+
+* [Prerequisites](#prerequisites)
+* [Installation and configuration](#installation-and-configuration)
+ * [Installing using Helm](#installing-using-helm)
+ * [Using own (local or remote) registry](#using-own--local-or-remote--registry)
+ * [Configuration](#configuration)
+ * [NCM API credentials](#ncm-api-credentials)
+ * [TLS without client authentication](#tls-without-client-authentication)
+ * [TLS with client authentication](#tls-with-client-authentication)
+* [Custom resource definitions (CRDs)](#custom-resource-definitions--crds-)
+ * [Issuer resource](#issuer-resource)
+ * [ClusterIssuer resource](#clusterissuer-resource)
+ * [Issuer and ClusterIssuer fields overview](#issuer-and-clusterissuer-fields-overview)
+* [Usage](#usage)
+ * [Create an Issuer](#create-an-issuer)
+ * [Signing certificate](#signing-certificate)
+ * [Renewing or reenrolling certificate](#renewing-or-reenrolling-certificate)
+
+## Prerequisites
+Prerequisites for building and using NCM-ISSUER:
+
+* [NCM](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/) release 21 or later,
+* [Kubernetes](https://kuberenets.io) version 1.18 or later,
+* [cert-manager](https://cert-manager.io/) version 1.0.0 or later,
+* [Docker](https://docs.docker.com/engine/install/) version 20.10.0 or later,
+* [Helm](https://helm.sh/docs/intro/install/) v3.
+
+**:warning: Warning:** Install docker-re instead of default if you are using CentOS, RedHat or Fedora!
+
+## Installation and configuration
+
+### Installing using Helm
+The easiest way to install NCM-ISSUER in Kubernetes cluster is to use Helm.
+
+At the very beginning it is necessary to create namespace for NCM-ISSUER:
```bash
-$ helm list -n ncm-issuer
+$ kubectl create namespace ncm-issuer
```
-Output of this command should look like this:
-
+And then install it using the command:
```bash
-ncm-issuer ncm-issuer 1 2023-03-10 17:36:12.120909878 +0200 CEST deployed ncm-issuer-1.0.3 1.0.2
+$ helm install ncm-issuer -n ncm-issuer ./helm/.
```
-Great! Everything is working right now!
-
-## Configuration
-
-NCM Issuer requires to create some k8s secrets with credentials to NCM REST API and TLS client configuration.
-
-### NCM REST API credentials
-
+On the other hand, if you did not use `git`, but downloaded the packaged version of NCM-ISSUER use:
```bash
-$ kubectl create secret generic SECRET_NAME -n NAMESPACE --from-literal=username=USERNAME --from-literal=usrPassword=PASSWORD
+$ helm install ncm-issuer -n ncm-issuer ./ncm-issuer/charts/ncm-issuer/.
```
-### TLS without client auth
+#### Using own (local or remote) registry
+In case you want to use your own registry, just change the value pointing to a specific registry
+in the `values.yaml` file in directory that contains Helm files. Then just repeat the steps
+mentioned above.
+However, if you do not know where to get image from, because you cloned the repository
+just use the command:
```bash
-$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem
+$ make docker-build
```
-### TLS with client auth
-
+or (if you also want to save image)
```bash
-$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem --from-file=key=CLIENT_AUTH_PKEY.pem --from-file=cert=CLIENT_AUTH_CERT.pem
+$ make docker-save
```
+Saved image should appear in the path `./builds/ncm-issuer-images/`.
-You can check if the secret has been properly created by running this command:
+### Configuration
+To make the NCM-ISSUER work properly, it is necessary to create few Kubernetes secrets
+that contains credentials to NCM API and TLS configuration.
+#### NCM API credentials
```bash
-$ kubectl -n NAMESPACE describe secrets SECRET_NAME
+$ kubectl create secret generic SECRET-NAME -n NAMESPACE --from-literal=username=USERNAME --from-literal=usrPassword=PASSWORD
```
-## Usage
+#### TLS without client authentication
+```bash
+$ kubectl create -n NAMESPACE secret generic SECRET-NAME --from-file=cacert=CA-FOR-REST-API.pem
+```
-NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities, but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.
+#### TLS with client authentication
+```bash
+$ kubectl create -n NAMESPACE secret generic SECRET-NAME --from-file=cacert=CA-FOR-REST-API.pem --from-file=key=CLIENT-AUTH-PKEY.pem --from-file=cert=CLIENT-AUTH-CERT.pem
+```
-### Create an issuer or cluster issuer
+To make sure that specific secret have been created correctly, you can check this
+by using command:
+```bash
+$ kubectl -n NAMESPACE describe secrets SECRET-NAME
+```
-Issuer .yaml file with all available options:
+## Custom resource definitions (CRDs)
+### Issuer resource
+Below is an example `yaml` file containing `Issuer` definition:
```yaml
apiVersion: certmanager.ncm.nokia.com/v1
-kind: Issuer (or ClusterIssuer)
+kind: Issuer
metadata:
- name: ISSUER_NAME
- namespace: NAMESPACE_NAME
+ name: example-ncm-issuer
+ namespace: ncm-ns
spec:
- secretName: SECRET_NAME_WITH_REST_CREDS
- tlsSecretName: SECRET_NAME_WITH_TLS_CERT
- CASNAME: CERTIFICATE_NAME_FROM_NCM
- CASHREF: HREF_FROM_NCM
- ncmSERVER: ADDR_TO_NCM
- profileId: PROFILE_ID
- reenrollmentOnRenew: false (or true)
- useProfileIDForRenew: false (or true)
- noRoot: false (or true)
- # below available since 1.0.3-1.0.2
- ncmSERVER2: ADDR_TO_NCM2
- chainInSigner: false (or true)
- onlyEECert: false (or true)
+ caName: ncm-ca
+ caID: e1DefAscx
+ provisioner:
+ mainAPI: https://nokia-ncm.local
+ backupAPI: https://nokia-backup-ncm.local
+ httpClientTimeout: 10s
+ healthCheckerInterval: 1m
+ authRef:
+ name: ncm-rest-auth
+ namespace: ncm-ns
+ tlsRef:
+ name: ncm-tls
+ namespace: ncm-ns
+ profileId: 101
+ useProfileIDForRenew: true
+ noRoot: true
+ littleEndian: true
+ chainInSigner: false
+ onlyEECert: true
```
-For **kind** variable use either Issuer for namespaced one or ClusterIssuer for cluster level issuer.
-
-For **name** variable use some descriptive name of your choice for your issuing CA. This name will be used by your CNFs / applications.
-
-For **namespace** use the one you have created before.
-
-For **secretName** use the secret name with NCM REST API endpoint credentials.
-
-For **tlsSecretName** use the secret name with TLS certificate.
-
-For **CASNAME** use the CA name from NCM web UI visible under 'CA Hierarchy'. Please do not use CA's CN or DN, but CA name as plainly visible in the UI.
+**:warning: Warning:** With release `1.0.4-1.1.0` the name of some fields in `Issuer` has changed, but old names are
+still supported and can be used (this applies to: `CASNAME`, `CASHREF`, `ncmSERVER`, `ncmSERVER2`, `secretName`,
+`tlsSecretName`, `authNameSpace`).
-For **ncmSERVER** specify your NCM REST API service URL.
+### ClusterIssuer resource
+With the `ClusterIssuer`, the definition does not differ from that presented
+with `Issuer`, and the only differences are in the field `kind` and the non-existence of field
+`.metadata.namspace` for `Cluster` scope reasons.
-If the **ncmSERVER2** field is defined, it will try to make the same query to the second provided NCM REST API service URL in case of lack of connection to the main one.
-
-If the **profileId** field is defined, then the profile ID will be set in enrollment requests, so it is included in the issued certificates.
-
-Setting the **chainInSigner** field to "true" ensure that CA certificate chain will be included in **ca.crt** (intermediate CA certificates + issuing CA certificate + root CA certificate).
-
-Setting the **onlyEECert** field to "true" ensure that only end-entity certificate will be included in **tls.crt** (without issuing CA certificate).
-
-Setting the **useProfileIDForRenew** field to “true” is necessary to include the defined profileID value in the */update* request during the renewal process. Otherwise, certificate update operations won’t include it.
+```yaml
+apiVersion: certmanager.ncm.nokia.com/v1
+kind: ClusterIssuer
+metadata:
+ name: example-ncm-clusterissuer
+spec:
+ ...
+```
-Setting the **reenrollmentOnRenew** field to “true” will force new enrollment of the certificate when renewal process is executed. In this case NCM Issuer uses the NCM */requests* REST API endpoint to get a renewed certificate. By default (when this field is not included or set to “false”) the */update* NCM REST API endpoint is used to renew the certificate (it is the default recommended setting).
+### Issuer and ClusterIssuer fields overview
+
+| Field | Description | Supported from |
+|:------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------:|
+| `.spec.caName` | Name of an existing CA in the NCM API, which will be used to issue certificates | 1.0.4-1.1.0 |
+| `.spec.caID` | Unique identifier for existing CA in the NCM API, which will be used to issue certificates | 1.0.4-1.1.0 |
+| `.spec.provisioner.mainAPI` | The URL to the main NCM API | 1.0.4-1.1.0 |
+| `.spec.provisioner.backupAPI` | The URL to the backup NCM API in case of the lack of connection to the main one | 1.0.4-1.1.0 |
+| `.spec.provisioner.httpClientTimeout` | Maximum amount of time that the HTTP client will wait for a response from NCM API before aborting the request | 1.0.4-1.1.0 |
+| `.spec.provisioner.healthCheckerInterval` | The time interval between each NCM API health check | 1.0.4-1.1.0 |
+| `.spec.provisioner.authRef` | Reference to a Secret containing the credentials (user and password) needed for making requests to NCM API | 1.0.4-1.1.0 |
+| `.spec.provisioner.tlsRef` | Reference to a Secret containing CA bundle used to verify connections to the NCM API. If the secret reference is not specified and selected protocol is HTTPS, InsecureSkipVerify will be used. Otherwise, TLS or mTLS connection will be used, depending on provided data | 1.0.4-1.1.0 |
+| `.spec.profileId` | Entity profile ID in NCM API | 1.0.1-1.0.0 |
+| `.spec.noRoot` | Determines whether issuing CA certificate should be included in issued certificate CA field instead of root CA certificate | 1.0.1-1.0.0 |
+| `.spec.littleEndian` | LittleEndian specifies the byte order, setting it to true will ensure that bytes are stored in LE order otherwise BE order will be used | 1.0.1-1.0.0 |
+| `.spec.chainInSigner` | Determines whether certificate chain should be included in issued certificate CA field (intermediate certificates + singing CA certificate + root CA certificate) | 1.0.3-1.0.2 |
+| `.spec.onlyEECert` | Determines whether only end-entity certificate should be included in issued certificate TLS field | 1.0.3-1.0.2 |
+
+**:x: Deprecated:** The following fields are not recommended to be used!
+
+| Field | Description | Supported from |
+|:----------------------------|:------------------------------------------------------------------------------------------------------------|:--------------:|
+| `.spec.CASNAME` | Name of an existing CA in the NCM API, which will be used to issue certificates | 1.0.1-1.0.0 |
+| `.spec.CASHREF` | Unique identifier for existing CA in the NCM API, which will be used to issue certificates | 1.0.1-1.0.0 |
+| `.spec.ncmSERVER` | The URL to the main NCM API | 1.0.1-1.0.0 |
+| `.spec.ncmSERVER2` | The URL to the backup NCM API in case of the lack of connection to the main one | 1.0.3-1.0.2 |
+| `.spec.SecretName` | The name of Secret which contains the credentials (user and password) needed for making requests to NCM API | 1.0.1-1.0.0 |
+| `.spec.authNameSpace` | The name of namespace in which Secret to NCM API credentials can be found | 1.0.1-1.0.0 |
+| `.spec.tlsSecretName` | The name of Secret which contains CA bundle used to verify connections to the NCM API | 1.0.1-1.0.0 |
+| `.spec.reenrollmentOnRenew` | Determines whether during renewal, certificate should be re-enrolled instead of renewed | 1.0.1-1.0.0 |
-The **noRoot** field is responsible for controlling the value of ca.crt secret. By default (when this field is not included or set to “false”) Root CA of the certificate is saved to the ca.crt. If noRoot field is set to “true” then issuer of the certificate is saved there.
+## Usage
-To create an issuer from created .yaml file type:
+### Create an Issuer
+Once the deployment is up and running, you are ready to create your first `Issuer`!
+The following is an example `Issuer` created for the namespace `example-ncm-ns`:
```bash
-$ kubectl apply -f issuer.yaml
+$ cat << EOF | kubectl apply -f -
+apiVersion: certmanager.ncm.nokia.com/v1
+kind: Issuer
+metadata:
+ name: example-ncm-issuer
+ namespace: example-ncm-ns
+spec:
+ caName: ncm-ca
+ provisioner:
+ mainAPI: https://nokia-ncm.local
+ authRef:
+ name: ncm-rest-auth
+ namespace: example-ncm-ns
+EOF
```
-### Enroll a certificate
-
-To enroll a certificate just follow instructions from [cert-manager site](https://cert-manager.io/docs/usage/). The enroll process is exactly the same!
-
-Sample .yaml file to enroll NCM issued certificate:
+After creating the `Issuer`, we should now be able to check its status:
+```bash
+$ kubectl get ncmissuers -n example-ncm-ns
+NAME AGE READY REASON MESSAGE
+example-ncm-issuer 3s True Verified Signing CA verified and ready to sign certificates
+```
+The above output tells us that our `Issuer` is ready to sign certificates!
-```yaml
+### Signing certificate
+Once the `Issuer` was successfully created, it is now time to sign the first certificate:
+```bash
+$ cat << EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
- name: NCM_CERTIFICATE_NAME
- namespace: APPLICATION_NAMESPACE_NAME
+ name: example-ncm-certificate
+ namespace: example-ncm-ns
spec:
- commonName: CERTIFICATE_COMMON_NAME
+ commonName: example-ncm-certificate-nokia-ncm.local
dnsNames:
- - CERTIFICATE_SAN_DNS
+ - example-ncm-certificate-nokia-ncm.local
+ subject:
+ countries:
+ - PL
+ organizationalUnits:
+ - Security
+ organizations:
+ - Nokia
+ usage:
+ - server auth
+ - data encipherment
+ secretName: example-ncm-certificate-nokia-ncm-tls
issuerRef:
group: certmanager.ncm.nokia.com
kind: Issuer
- name: ISSUER_NAME
- secretName: SECRET_NAME_FOR_NCM_CERTIFICATE
+ name: example-ncm-issuer
+EOF
```
+Then we can check the status of our newly issued certificate:
```bash
-$ kubectl apply -f certificate.yaml
+$ kubectl get certificates -n example-ncm-ns
+NAME READY SECRET AGE
+example-ncm-certificate True example-ncm-certificate-nokia-ncm-tls 17s
```
-### Troubleshooting
+and whether it has been exported to referenced Secret:
+```bash
+$ kubectl get secrets -n example-ncm-ns
+NAME TYPE DATA AGE
+default-token-g2f47 kubernetes.io/service-account-token 3 18m
+example-ncm-certificate-details Opaque 1 22s
+example-ncm-certificate-nokia-ncm-tls kubernetes.io/tls 3 22s
+```
+Additionally, in NCM GUI we can also find our newly issued certificate.
+
+### Renewing or reenrolling certificate
+When it comes to renewing or reenrolling certificates, NCM-ISSUER will take care of this and
+do it earlier enough before the certificate expires (the timing of chosen operation,
+depends on the defined values in `Certificate` resource).
+
+You can define what operation NCM-ISSUER should perform in such a case by
+setting certain PK rotation policy in `Certificate` resource.
-In case of issues despite checking status of created resources, you could also check ncm-issuer pod logs:
+| Field | Operation | Value |
+|:---------------------------------:|:------------:|:-----------------------------:|
+| `.spec.privateKey.rotationPolicy` | Reenrollment | "Always" |
+| `.spec.privateKey.rotationPolicy` | Renewal | "Never" or not even specified |
+However, you can also trigger renewal or reenrolling operation manually using the command:
+```bash
+$ kubectl cert-manager renew certificate-name -n namespace-name
+```
+
+## Troubleshooting
+In case of any problem, besides checking the status of created resources,
+you can also check the `ncm-issuer` pod logs:
```bash
$ kubectl -n ncm-issuer logs -f `kubectl get pods -A -l app=ncm-issuer -o jsonpath='{.items[0].metadata.name}'`
```
+
+(back to top)
\ No newline at end of file
diff --git a/assets/ncm-issuer-logo.png b/assets/ncm-issuer-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..f18b47e16118fb213ea75764b04fb35c1934bb09
GIT binary patch
literal 472247
zcmeFZhgVZe_dg5)DHf^}r33*1sR}4kgG!eoy%#|Qr1wsUh;$H;E}$SF9hBY@MY<3H
zX;P)PP=x>?$$RkLtK4UOe}BPyvsOGO!_1tSJ-dGPK1MuHSG;ic@>v1`f(yz@a#{og
zWWX&M0T~H!d0#Mi9k>v>Ybo9(DC=Wh0e(EQHc)=7rbfW~tJ@hu5(1)=E(9RppUVVi
ze%%ugs1P#!zSkn;`O_!Nj)3^@K1RUxr-7h1^BS(4BzbqT0!q@MU+55CH*Eu$_*9hk=@^gq5?S;KN7GmeztkjxHyo2&8-@
zfLljvkB4kNjt)-l5}l^CyXWj?&2~%hy5MzonX_zc
zY*KEI9!qG+Df~Sg_$AG5>*3)dAtdDO?JejnBIxX9BXmPtTwLh7u#m8@0MJ9g-Pg(E
zp^t!*JI7y>{4^}2
zvJ$d(uy(X|@^BZrA$UXR{~G6E_xR5Wo!tK>2S6C1lfMANuK%CIlwCZmL;*_4`vB|t
zdw;+}t$sb%-Q$tasSZNI*RS6exGpRpEH3nWf57sk9$86v*m*cu|03M){rsZf9S4tp
zx1RJrA%TP431uZ59y-}bv-=1|nYY?ju3Y)%jTynUsF{_6hk
zY5r>c_v}(a|Hne4PPQ*$sAcW$?BIEF05Ug3gr$BFh!`s=-
zUgy`5{2%oEfA;-*zQ1UDif8{4h+pRbNQBH;DWTueC39AMQqP!xK$bvR?v9QR;rgWA
z3)7`E#>LH7jUHkROtu6L!NiCQv+OiRJepC~NS_y)4!)1S)R_q0c762{`gVOisfbgz
zEAH*tGMzRLv@9xVMvCuL~AD7cmpvXA~Jw5=npKC7Z+f^dcb*@nwIp28`3v
zJXYO1FMd6bGgm0keDdHcC;q}
z$+xepMqP`s^y6C`r;m#&j!SzY)9#q7+0VpO-0s)xRykBuu*-C#q&EdTl5B45{Ka^|
zalx_tOXk4$-6nHiBh2?|rcF=10?)?DquEgdk!JrNcXw}#h-fby7UbuzCUR@!Z*On=
z`S~^YZf^Z(9eQ%N^?SoG>n=OVzZs?CA#r-t(S;ASUN8T>YX@mq0LqM6+-+Wg4R1lb
z!|~31Uyle)-6<&2Gw@k%HbsrH`7^_oG^g{=qNUSb!l
z3hy+rz>agkn495tJ)SH`?a4U1`<2|-96@@kg(y$c4yzmHI&E6I!y}OmO?nrH0(3|8
zwG9Q6LOyDh53YD)u&GsnsRKh?^%epj*%CO@pTS<~yr4bX&i-cRQyeF4)6r_Nr;ecQ
zA|{^mY18!o(9Z>VCOvA)zeSgc^WSi_u`!!@oS4ARI55O)arjV-bkAKDQrn3n#4>+D
zmd+TL4v$)VT^-Ks_mJlGl6MH;0!@>$pNC5hC#@}Q#(wn`EkO=Ob&=(3DEtiMU0iAR
zpCo%;%f37nxg;(NzJsamV2+8qDaVP;*LK_8&EP6uD{xgRzW0c9-o~{_obU<+sZ1I#
z`5;aYTzng$X?ig?wE*m_Abf|#nmV#A^;!biz@Co~H_aEtyLSX{R8Z}j7WH`CgtSWt
z&dWXJ33Iu&=hxG^z0G4^kxEPBW(|8%Dse|g-8O+}v7n&XB!Z2bT2)o`Te$+=({1g7
z^s~hEYav!0v8C&C-7SkljQ@u05su^zpU)kQOFTG7{cnNu=lp77uc&-zDNqNuL1yiA
zC-E&9SwK?8;*u9inMdOuNK&3Qt^vK?Puqw=(261dBOAIx4{GPXDbpOJP7rhCl}QvcT0Mz#HrM*bU9q^
zsfYApQx+}R?6%4mG4Q5oq_3dDCq&-6yIX#|MLnerfv%%v;z1-E@Wf2~03nVj
znrzY2P**SGr1*l=w^t@wLS~n{rJUg-CknIFRvbwn*~$4I*7!}JAQe!i}
zKh4tx5tB5Qsj7JJ%DL9KF_#lRR9rgz^XKb2R!ywB>86tIOYRF*7$&yIe<=$pe=k`ZLg~cBh45
zOvv`OQvrX6QM2eJY>%Qnmbdmhgz@SeIED;IMEzBo3O1feJ)a%97rXR2h&b5&5G!of
zNDn6;AI#?2N`4DVwaOciRl)j9MY-mEl2y^4JFMp+y1|fL>aLkIGjt$j7EL);-@spf
zv3W{s{tbWiI7-6%{)-_0+m#UwqIhr^(uw5VuB({MvjdoA9;0{Sf&DqOP-
z^J(D*m7(P=pvG168|`bcGdO|ej6L;pqU1!|hF{`x4Gyoz#e2MG%XLAvkX>^w3
zCSjP{Tf31J;dIulJZjaWu`KtoynT@9m9TykZPL-y%+ROtF
zX&0RlBJZPlL-1*vxA9iiy>(8#>}$j6{mBL+Bxrct?&AOpc#&Hp%V8n;xLyZJv7=b=
z!Lzw2Kj$ibpX}w7xqe%2e
zvRcgvlWzU7JXE;sCVLfj0sE$6_f#6sft659@D{S(gY#4))o2mu@cS*&qrqJyWLm;!
z%ffZ>OWLqU)gn?YW4!f;4mAwN2n`MZkuN{fxlP@xh7;%34aBba|-xOS4
zG_|wi2B$Rzgjz#?aBz1h&f_N4A#ra-P0UaV>%S;FqfVwoP)8d%eCL!@5Q5NmUz7g?
z%LLR#%Y2C<+p1+p7$^kaXpqvFvo?&~%e@LE<^ZdBZrf^p14qg9gJakhT5N~ld^s^z
zm7u(%&9=1nF{Nx3!zfvbWy-lFL4BG|Qwo#F5%+kDT@?@UEvygL=pwU^c+$ee^#-O?
z{+`goL-l5>4%>^6j-fAKR6TLWhk(SE0cIv^B#D-2$M)YUcAV-3feVu@{gu;t2-e8E
zmHZytkM)?L%$V)BM9b1D!IYo1bEWboKafB&aQCg#o^=b
zz3CzCM+?MLNwO64V!Fh$U2F-ii@9!yBqe&En@&p21_i6C#}hcVEV$nJad+KnpR3+C
zu2)v+?D;kKkB%DXP^W@#b`geA>aQ&KH?>IpOEP6=9Emvznl40lo#qNQmyt6&H|@5Q
z>9N$y&e`Cap025%2D)mL+89}01r50wd_Nf`ke}Y?b`G?0)>Rl3mPy8SYprh0{|ON>
z*@Q1F=iRK0Pu^2mm8k930D*@2+e~y)ZVSN^&4{RY{w);`A*wFI$#Wqqs|s!iqlMt*
zom>g8^#@-B#b^4m+3Zi*bPJBN^GsL&NB_Bqok?fI#&ak}Y8R*{`R}h^LuNbIws+_o
z{j42FO^Satr_T+!mXsZ-_fbQ^3=vZKHIRBJBb>lO^69hsFK`$Etd!%$2mkc>-~-mq
zE<*h|{~s|2K|VKHxYgzFenqe5_|=<^F!(oD-tYf_uyAvGzlz4>zPqf|+uN%fZ=%DZ
zd(&bqz>@jeDa8;Y+d^*jFCHKSdEb3q-ySUsz4Wox($X@AF3`U=C%~IxO5=iYDazV(
z8jK3ej(v^$nDZ{XaP23|$JwSSE1C_;oz-U|dM;cjDW0CZ=*2H5*`o^VtHrG?H6|LfO$|&V5HU|5R&<{Muu}Z{;
z;BdP{&&UBR^_#}#UZY6BY29Rd(MYFc$4D;Uti;{GoCNCoyq2=6gTE7C*UadgRoF23
zLH7~qI%AANy(Pj#=X|Q}jTx2)&GLW57@O65K#W7F1K2C98r^Of3awKbuT1dw`7@qUkPQrSM2v3?k8-$jC#L~ba!|6>SgG2lThSdX;V
zmV7&R+DR`Fg9UK3pIX?7qyAntK9*I00&p%BW{SfHu%#145YX}5jSc3cg|gHo4tdjn
z+uaTjY5`1k^i?m#7f|;6+Kh!cFcC2JRPqpN$3R}JSh?xUPBf4
z?DRLNXpG2j4{B0iB5VgGm}sG@snc-Kg)OG911z!dizSk=0FEFM
z4seDCK3+IUL*Wv>wf{Y&`=FqiFewC!Dm}Yc2h3Q}b;eDMp!HzE_3}pUp
z?I^=a-ZihNsF;?PHpJxW%)$0tywvOQU^Seti_f2DIvL7>5CVyYe{>+Qo!YBg$rku5
zY5(qi+i$TJ>i*(+lh(S@^dGZA`t^VQ2w#$-H6Ep%(}~VxygmFYdvJoeRt
zTArRoU*6ncxvVVnav7m(!~^A7Vw^rmc0DWC*M?&alY>qT8CD)&7{iLo>&|48&ifABdv_2
zkefGmqb*q~9X`ZLnVUH`F$7kWmq$11N=;shyCGz*0FsR-I`*~A*(=u2zqhP*B%8&0XYbX;uToQ@)7=xr_{9hF
z-?{xzhu^KT7EoDYn+sxAo#TcqQ|Esyk^6$(h?bMy^eGdF8(MtT$Ym_PBXohDVc=cu
ztLOL6+0`|rDqzhn3!24sq$ZmS3AHsfKhE;|7H8Mf>z4cDwV_7hs~01U=?}hg^3P)p
zC!IJ&CjyA=8)xGYlXN^e=9ywgOHb
z4QOMdu)^z)>RZ#aKnVv(Z)60rpR#5M1?q77;@q|$tsOl)y%XI6n58I72g~cJ%lZp*
zg^YomPxHZ%A%`B(lnM_#g`bMmTf^<&$GAP;{1|jgU?D^HNaX>9bhbxbjBc{>TNmMR
zAq(G~4>^LtJ@aqKzbz322DQ+?1{f{6Vy|~_
zXSe#ne(zvLXojr+2ZZrR_0FO+#{23pZgFvk5*hO>c=V8IbBV|<_6BQ4NH^uS)bpe+
zKBW5tyuiH=u}OBmxOUE`c=32PZi=7f=J#9I&e>7LVMF=ibt*2#>2pNP_+9>d+r&s!
zSN*y{ByosAez!95jm4rf;t$!%-K`;d`}U66Q|~FwsOqF)CRf?GiA`cP#%iM)j;r56
zU2{qz!LbTa&T^r_cbdecf{tAR5OIs(;3V+V@$uxmQ!$Fc65vXWogytD)0<{&=8Eza
zco%U1aBzaS=hLekqib7wD9iZTur{bCl)dF@V2}Ce@%?AfEZ&Z!4u7-7rsjj<=I6f@004
z4UkVPAf!wB1vX_#sF!@O#cE%%__;}`mrR6*ulQd;yLVkUY~ee{0_E=KZz9K=sxNEw
zCV}*R+=Yw7@A+Ms{=S#l`?76c+ay)w*W<9flI9|j3f)A@7V$X^y
z6USeCfz;lJWux@mXqL|Itp%V+L%Y|??46sXeTj_#J&4_OVN(m|3dNw;_R7uFo9$Bu
zE$n12>{#ircajseG8Xq&6pB_1NZ%789KqAG^5Kq#5y2u*B$AMCb8s%7S7a`UOo6GB$o32NGbhj38^?k8U=x5S~4efu6H?iWp$W4l?g)H4)Z@D2J+ksp(rh*mH^kQ
z4_~j8u{B&XSWC8`GNsXJO?vyRnmBam8LZS6ZXH+8Of1rVqEPwLKs850K~nYK1hB{@pI^Iw;!pn;!I~Udcj=eL=xiz9
z_cxgqj@{RA8+R`k8{MZ=l--}Zv1oy}0WDd`*>ZEp4n!=K<=$E;xJvpXLpFeTqsOb3
zeAYYPOOz1DJOQ4T&Zz0#(8w%AZBKbTQ9OrBVuK1ER5Uo4DN-COR=~;E%Szo7)5S~t
zg|>3ZiJX-IfF}5H_)L(9ImN~j=hFk{I%d=Ja=Ne}5AlisUqPBPWpDG&Im_k9>M*9l
z2RP5qZ=6-YE+j>Q)OJ3q$iu1~r!cwIZT_4u8qe2V&Q4C5Wm*sI6!8tx88&AsE?SE}
z&(M5kVp-5)kH{--zx(m;9g|Vj2@r~vIYsr}{X+&a2U!@qkqCYNlB+nwN8I+p!hT;~
zo;sZ0dnja;Llb+OmyH2J$Dj<3VC&rQDSL@0k?Mku3W^cpQVTmv47FA5emh@Wc;STII_dQ$qtB0%@!`CrhUArV)eSRoQ}QwjYm;UNw2&s@qWzwU2D$_6wpY=8t6ZRp_)D{9%`RhPv
zyCKlqoRwT|q8hbiuF%#C2V6}6
z#d=1ruDLp8tP*HzYqy>Rr`-g;GN&1SO%~Bx>ghtW4mu?T-g2*_gQ4+6xJjp4)7~#0
z5?CD8+7v>g8Bw5Z8X))`5yW#OF-2$06gQ(+HtsY!1FD}0GOW=v+Ep~fZBP1VxE>)s
ziZ*Y?f6JUoYxi1@O~Cd0x2i21Is+EFnr41_229cj)j#8;PGfMNs!m+l!qI5st_34G
zK}e{*-O4PJ8Xc_7z5HebsQIu*je$5fNN7mY@pT~pvN?Vm079)ds|7~V}-o_F}6TmcPY(1J8Dc6Je|?FGLReZfb;I9x5u0*@|l
zy9B+~@)%AvU5kG`?F7GVI?^1)Ahe(DzfrI0(VR$2$VpVPHfX!_duz8cfZ)E@OM!**
z_o>2quYDyxrUc8FsH>`0B_}6KVBb%$cw)U7bhj&k?H2c6-Y!gCiMRa$DfPs+W2q)=
z`ysdDB@)N=yZ04cpiib-Z^$G_^moH)^DsT?+zY-@w%F{jMc39PUPzG+wj0j|;C4Mxyrd
zAC8hUyUgLO2P87I@Tlza)t?%XdVbZ@s4PRDy`crAQ6?1B?K50A4ktrV3^(o>5_ZM*TRWU;RgnMiE3jHz^
z()Y@drfwHx5Ad0WmpYljeR=>_%ZUnp#eChU&-5Jstt6sk!B=YcmyiG=S;!^M<}LQ3
z_^hbu+4)r>@sEhDpmTD6TXP5+z6?6OLp2R^pzlR2i3Yy5!xjsdHo}04$
zF&(k29t&c+6)a2pHZJ+l`sLE5L&g)8J?HTcaJzmu_G5>(_Y=kFaqTe{4eOWdapBNt
z%?-#?Y;o^l_3|{q(wHDkoiWInWLLk4Z*C;%c6HY4=!K|BYiJyW*~Tipym-1rRDiW2k_i)t`B4!=SP>vTZ*rZLEN_rMJxTCFUJYvCWi*F;+NR&9*cpn
zp#xYM2mmTSM;PS=AA2Sw60&!L;kVqLB5bXhV*m%lgPUq@Pb?_4tmW9!D0-E!S?N5Z
zpy21@8`+VBwO8<2^j)R6rMZ_Zanor0J7zken(-C?MlV!)+)BMLVp+O$^3(4P5tG$L
zEQ*|RC`0ydm3S>;ER=@OPna`ZYqDk;*6t~p`I5!x|R%zvpO;d!VwtG)!w|h^dNF)xb@!?EbAPWQ7c;>J3uJgm#-rc=`XZtY(uo(Ud
zy_;;%H67}CG9^8OCu&me?+$N^3C&u|-LKCGz86MuA(!tp;Pxw?wi>l;Unib5h935+
z{Pv}S31HrQ4}fBWw^E*~I^W!;N7AygHitdewu^M}@dh6|ay4cE5FJO^){9qf@^aj9
z(%sw+sJ{rkbmw?@RPJ&{eYxEbq#iAs9(1tHwKbiVs)FJ{nadsGCK4bx!)w!UKb13>
z&291z;sDO5_nLfFF$%x9W>?Aw8*(Bpx&wKN$5vgOB;_~t;V_lNhIs5HF=VU~w&sN{
zD_B%$SyUH?-c};<5$a6-
z4I+;UgPh(wrfH*O{~$mUo-lS6X(K7j@ouS8?Re}%Ue89#m!8d#jqiB-$~~mQSExBL
zmYaPU9Bjwt=RuKSnl5p(o1jusifyloN5;D~YtS<|AyC$4Y<)hl{u_
z*35yu0dSnpJeRyi)lBrZ*pnA$sQC?A%p0lS9yL3$(38So?(-wmWZ()n(dop#4-;S#
zor$c3e=8Lr*i?BP{T^p6xCUL(dbyFks^L+*daqCr=OOnDLjC4P0s9PG8-X`9ocfUF
zRv{B-?JeaA0GyZ&4G~hxJQSr&ayt+Y%t_j4k8R}VVCPDY&Kzxy*}cC4oS7m_EaZrK
z0!fHtboU0;^TB=$?0t*d03~x!vvHsK0{7w-=*v`VE@sfqYy^x5aRO-L%UI7O@!KO+
zO$N9o!ydz&bEHrVJ%dJEOw5H?AX}D5_{eN9^&MI0x3UQ6XX~P-{w*rLBk?I4<3e5WOKX
zPK>FA{Pg+mx>ZPq+f<#C^tu^AQ2z}IAoBVNMBPl(bcA^Cfjw42kg*yY>HcnSRYTw8
zh~jGq4QTa5Z