updated Dockerfile to use latest Alpine image, optimized logging and updated documentation

This commit is contained in:
Jens-U. Mozdzen
2022-07-03 23:48:49 +02:00
parent ecfaaacf38
commit 6f180147ac
6 changed files with 64 additions and 56 deletions

View File

@@ -1,4 +1,4 @@
FROM golang:1.16-alpine AS build_deps FROM golang:1.17-alpine AS build_deps
RUN apk add --no-cache git RUN apk add --no-cache git
@@ -15,7 +15,7 @@ COPY . .
RUN CGO_ENABLED=0 go build -o webhook -ldflags '-w -extldflags "-static"' . RUN CGO_ENABLED=0 go build -o webhook -ldflags '-w -extldflags "-static"' .
FROM alpine:3.9 FROM alpine
RUN apk add --no-cache ca-certificates RUN apk add --no-cache ca-certificates

View File

@@ -3,7 +3,7 @@ ARCH ?= $(shell go env GOARCH)
PROVIDER := "variomedia" PROVIDER := "variomedia"
IMAGE_NAME := "${REGISTRY}cert-manager-webhook-${PROVIDER}" IMAGE_NAME := "${REGISTRY}cert-manager-webhook-${PROVIDER}"
IMAGE_TAG := "latest" IMAGE_TAG := "2.0.0"
OUT := $(shell pwd)/_out OUT := $(shell pwd)/_out
@@ -30,9 +30,12 @@ clean: clean-kubebuilder
clean-kubebuilder: clean-kubebuilder:
rm -Rf _test/kubebuilder rm -Rf _test/kubebuilder
build: build: test
docker build -t "$(IMAGE_NAME):$(IMAGE_TAG)" . docker build -t "$(IMAGE_NAME):$(IMAGE_TAG)" .
push: build
docker push $(IMAGE_NAME):$(IMAGE_TAG)
.PHONY: rendered-manifest.yaml .PHONY: rendered-manifest.yaml
rendered-manifest.yaml: rendered-manifest.yaml:
helm template \ helm template \

View File

@@ -49,25 +49,15 @@ webhook to complete ACME challenge validations and obtain certificates.
The Variomedia AG webhook implementation is based on the example webhook provided The Variomedia AG webhook implementation is based on the example webhook provided
by the cert-manager project (https://github.com/cert-manager/webhook-example). by the cert-manager project (https://github.com/cert-manager/webhook-example).
### Creating your own repository ### Using your own repository
The GitHub version of the Variomedia webhook implementation is focussed on providing The GitHub version of the Variomedia webhook implementation is focussed on providing
an implementation in a decentral container registry, i.e. "Harbor". The Docker image an implementation in a decentral container registry, i.e. "Harbor". The Docker image
is currently *not* published on docker.io. is currently *not* published on docker.io.
Once you have your registry up & running (which is not part of this README description),
you can build your local copy of the software using the following commands:
```bash
# to upload the container image to your registry
export REGISTRY='your.registry.company.com'
docker login $REGISTRY
make build
```
#### Running the test suite #### Running the test suite
**It is essential that you configure and run the test suite after creating the **It is essential that you configure and run the test suite after modifying the
DNS01 webhook.** DNS01 webhook.**
You can run the test suite with: You can run the test suite with:
@@ -76,8 +66,23 @@ You can run the test suite with:
$ TEST_ZONE_NAME=example.com. make test $ TEST_ZONE_NAME=example.com. make test
``` ```
The example file has a number of areas you must fill in and replace with your Setting the trailing "." on the zone name (for which you have the Variomedia API key
own options in order for tests to pass. and set up the files in the testdata/my-custom-solver/ subdirectory) is required, the
test run might otherwise fail.
### Pushing the Docker image
Once you have your registry up & running (which is not part of this README description),
you can build and upload your local copy of the software using the following commands:
```bash
# to upload the container image to your registry
export REGISTRY='your.registry.company.com/yourproject'
docker login $REGISTRY
# push the resulting image to your repository
# will invoke via dependencies test -> build -> push
TEST_ZONE_NAME=example.com. make push
```
## Installation via Helm chart ## Installation via Helm chart
@@ -119,7 +124,7 @@ kubectl apply -f - << EOF
- dns01: - dns01:
webhook: webhook:
groupName: acme.cert-manager-webhook-variomedia.local groupName: acme.cert-manager-webhook-variomedia.local
solverName: variomedia solverName: variomedia-APIv2019
config: config:
example.com: variomedia-credentials-01 example.com: variomedia-credentials-01
someotherdomain.com: variomedia-credentials-01 someotherdomain.com: variomedia-credentials-01

2
go.mod
View File

@@ -1,4 +1,4 @@
module github.com/cert-manager/webhook-example module github.com/jmozd/cert-manager-webhook-variomedia
go 1.17 go 1.17

18
main.go
View File

@@ -124,14 +124,14 @@ func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error {
cfg, err := c.loadApiKeys(ch.Config, ch.ResourceNamespace) cfg, err := c.loadApiKeys(ch.Config, ch.ResourceNamespace)
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "Present() finished with error while loading API keys") klog.ErrorS( err, "Present() finished with error while loading API keys")
return err return err
} }
klog.V(6).Infof("decoded configuration %v", cfg) klog.V(6).Infof("decoded configuration %v", cfg)
entry, domain, apiKey, err := c.getDomainAndEntryAndApiKey( ch, &cfg) entry, domain, apiKey, err := c.getDomainAndEntryAndApiKey( ch, &cfg)
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "Present() finished with error while determining domain and entry name") klog.ErrorS( err, "Present() finished with error while determining domain and entry name")
return fmt.Errorf("unable to get domain key for zone %s: %v", ch.ResolvedZone, err) return fmt.Errorf("unable to get domain key for zone %s: %v", ch.ResolvedZone, err)
} }
klog.V(4).InfoS( "present", "entry", entry, "domain", domain, "entry", entry, "API key", apiKey) klog.V(4).InfoS( "present", "entry", entry, "domain", domain, "entry", entry, "API key", apiKey)
@@ -140,7 +140,7 @@ func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error {
url, err := variomediaClient.UpdateTxtRecord(&domain, &entry, &ch.Key, variomediaMinTtl) url, err := variomediaClient.UpdateTxtRecord(&domain, &entry, &ch.Key, variomediaMinTtl)
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "Present() finished with error while trying to update the DNS record") klog.ErrorS( err, "Present() finished with error while trying to update the DNS record")
return fmt.Errorf("unable to change TXT record: %v", err) return fmt.Errorf("unable to change TXT record: %v", err)
} }
@@ -170,14 +170,14 @@ func (c *customDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
cfg, err := c.loadApiKeys(ch.Config, ch.ResourceNamespace) cfg, err := c.loadApiKeys(ch.Config, ch.ResourceNamespace)
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "CleanUp() finished with error while loading API keys") klog.ErrorS( err, "CleanUp() finished with error while loading API keys")
return err return err
} }
klog.V(6).Infof("decoded configuration %v", cfg) klog.V(6).Infof("decoded configuration %v", cfg)
entry, domain, apiKey, err := c.getDomainAndEntryAndApiKey( ch, &cfg) entry, domain, apiKey, err := c.getDomainAndEntryAndApiKey( ch, &cfg)
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "CleanUp() finished with error while determining domain and entry name") klog.ErrorS( err, "CleanUp() finished with error while determining domain and entry name")
return fmt.Errorf("unable to get domain key for zone %s: %v", ch.ResolvedZone, err) return fmt.Errorf("unable to get domain key for zone %s: %v", ch.ResolvedZone, err)
} }
klog.V(4).InfoS( "clean up", "entry", entry, "domain", domain, "entry", entry, "API key", apiKey) klog.V(4).InfoS( "clean up", "entry", entry, "domain", domain, "entry", entry, "API key", apiKey)
@@ -188,7 +188,7 @@ func (c *customDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
err = variomediaClient.DeleteTxtRecord( url, variomediaMinTtl) err = variomediaClient.DeleteTxtRecord( url, variomediaMinTtl)
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "CleanUp() finished with error while trying to delete the DNS record") klog.ErrorS( err, "CleanUp() finished with error while trying to delete the DNS record")
return fmt.Errorf("unable to delete TXT record: %v", err) return fmt.Errorf("unable to delete TXT record: %v", err)
} }
@@ -238,13 +238,13 @@ func (c *customDNSProviderSolver) loadApiKeys(cfgJSON *extapi.JSON, namespace st
klog.V(6).Infof("try to load secret `%s` with key `%s`", secretName, "api-token") klog.V(6).Infof("try to load secret `%s` with key `%s`", secretName, "api-token")
sec, err := c.client.CoreV1().Secrets(namespace).Get(context.Background(), secretName, metav1.GetOptions{}) sec, err := c.client.CoreV1().Secrets(namespace).Get(context.Background(), secretName, metav1.GetOptions{})
if err != nil { if err != nil {
klog.V(2).ErrorS( err, "loadApiKeys() finished with error") klog.ErrorS( err, "loadApiKeys() finished with error")
return nil, fmt.Errorf("unable to get secret `%s`; %v", secretName, err) return nil, fmt.Errorf("unable to get secret `%s`; %v", secretName, err)
} }
secBytes, ok := sec.Data["api-token"] secBytes, ok := sec.Data["api-token"]
if !ok { if !ok {
klog.V(2).ErrorS( err, "loadApiKeys() finished with error") klog.ErrorS( err, "loadApiKeys() finished with error")
return nil, fmt.Errorf("key %q not found in secret \"%s/%s\"", "api-token", return nil, fmt.Errorf("key %q not found in secret \"%s/%s\"", "api-token",
secretName, namespace) secretName, namespace)
} }
@@ -268,7 +268,7 @@ func (c *customDNSProviderSolver) getDomainAndEntryAndApiKey(ch *v1alpha1.Challe
domain := strings.TrimSuffix(ch.ResolvedZone, ".") domain := strings.TrimSuffix(ch.ResolvedZone, ".")
apiKey, ok := (*cfg)[domain] apiKey, ok := (*cfg)[domain]
if !ok { if !ok {
klog.V(2).ErrorS( fmt.Errorf("domain '%s' not found in config.", domain), "getDomainAndEntryAndApiKey() finished with error") klog.ErrorS( fmt.Errorf("domain '%s' not found in config.", domain), "getDomainAndEntryAndApiKey() finished with error")
return entry, domain, apiKey, fmt.Errorf("domain '%s' not found in config.", domain) return entry, domain, apiKey, fmt.Errorf("domain '%s' not found in config.", domain)
} }

View File

@@ -124,32 +124,32 @@ func (c *variomediaClient) UpdateTxtRecord(domain *string, name *string, value *
// the actual request is encoded in JSON // the actual request is encoded in JSON
body, err := json.Marshal( reqData) body, err := json.Marshal( reqData)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", fmt.Errorf("cannot marshall to json: %v", err) return "", fmt.Errorf("cannot marshall to json: %v", err)
} }
req, err := http.NewRequest("POST", variomediaLiveDnsBaseUrl, bytes.NewReader(body)) req, err := http.NewRequest("POST", variomediaLiveDnsBaseUrl, bytes.NewReader(body))
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", err return "", err
} }
// contact Variomedia and check the results // contact Variomedia and check the results
status, respData, err := c.doRequest(req, true) status, respData, err := c.doRequest(req, true)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", err return "", err
} }
// have we hit the rate limit? // have we hit the rate limit?
if status == http.StatusTooManyRequests { if status == http.StatusTooManyRequests {
klog.V(2).ErrorS( fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests), "UpdateTxtRecord() finished with error") klog.ErrorS( nil, "UpdateTxtRecord() finished with errori 'too many requests' reported by Variomedia")
return "", fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests) return "", fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests)
} }
if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted { if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(nil, "UpdateTxtRecord() finished with error reported by server", "status code", status)
return "", fmt.Errorf("failed creating TXT record: %v", err) return "", fmt.Errorf("failed creating TXT record: server reported status code %d", status)
} }
// the request has succeeded - but is the job already finished? // the request has succeeded - but is the job already finished?
@@ -157,7 +157,7 @@ func (c *variomediaClient) UpdateTxtRecord(domain *string, name *string, value *
var reply variomediaResponse var reply variomediaResponse
err = json.Unmarshal( respData, &reply) err = json.Unmarshal( respData, &reply)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", fmt.Errorf("cannot unmarshall response to json: %v", err) return "", fmt.Errorf("cannot unmarshall response to json: %v", err)
} }
klog.V(5).InfoS( "HTTP finished", "JSON reply", reply) klog.V(5).InfoS( "HTTP finished", "JSON reply", reply)
@@ -174,33 +174,33 @@ func (c *variomediaClient) UpdateTxtRecord(domain *string, name *string, value *
// re-fetch the job status // re-fetch the job status
req, err := http.NewRequest("GET", reply.Data.Links[ "queue-job"], nil) req, err := http.NewRequest("GET", reply.Data.Links[ "queue-job"], nil)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", err return "", err
} }
// contact Variomedia and check the results // contact Variomedia and check the results
status, respData, err := c.doRequest(req, true) status, respData, err := c.doRequest(req, true)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", err return "", err
} }
// have we hit the rate limit? // have we hit the rate limit?
if status == http.StatusTooManyRequests { if status == http.StatusTooManyRequests {
klog.V(2).ErrorS(fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests), "UpdateTxtRecord() finished with error") klog.ErrorS( nil, "UpdateTxtRecord() finished with errori 'too many requests' reported by Variomedia")
return "", fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests) return "", fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests)
} }
if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted { if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(nil, "UpdateTxtRecord() finished with error reported by server", "status code", status)
return "", fmt.Errorf("failed creating TXT record: %v", err) return "", fmt.Errorf("failed creating TXT record: server reported status code %d", status)
} }
// the request has succeeded - but is the job already finished? // the request has succeeded - but is the job already finished?
// check the response for an according '' element // check the response for an according '' element
err = json.Unmarshal( respData, &reply) err = json.Unmarshal( respData, &reply)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "UpdateTxtRecord() finished with error") klog.ErrorS(err, "UpdateTxtRecord() finished with error")
return "", fmt.Errorf("cannot unmarshall response to json: %v", err) return "", fmt.Errorf("cannot unmarshall response to json: %v", err)
} }
klog.V(5).InfoS( "HTTP finished", "JSON reply", reply) klog.V(5).InfoS( "HTTP finished", "JSON reply", reply)
@@ -213,7 +213,7 @@ func (c *variomediaClient) UpdateTxtRecord(domain *string, name *string, value *
break; break;
} }
if (loopcount == 0) { if (loopcount == 0) {
klog.V(2).ErrorS(fmt.Errorf("DNS update job timed out with most recent status '%s'", reply.Data.Attributes[ "status"]), "UpdateTxtRecord() finished with error") klog.ErrorS(nil, "UpdateTxtRecord() finished with error: job timed out", "most recent status", reply.Data.Attributes[ "status"])
return "", fmt.Errorf("DNS update job timed out with most recent status '%s'", reply.Data.Attributes[ "status"]) return "", fmt.Errorf("DNS update job timed out with most recent status '%s'", reply.Data.Attributes[ "status"])
} }
} // emulated do until } // emulated do until
@@ -237,25 +237,25 @@ func (c *variomediaClient) DeleteTxtRecord(url string, ttl int) error {
// deleting a record happens by sending a HTTP "DELETE" request to the DNS entry's URL // deleting a record happens by sending a HTTP "DELETE" request to the DNS entry's URL
req, err := http.NewRequest("DELETE", url, nil) req, err := http.NewRequest("DELETE", url, nil)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(err, "DeleteTxtRecord() finished with error")
return err return err
} }
// contact Variomedia and check the results // contact Variomedia and check the results
status, respData, err := c.doRequest(req, true) status, respData, err := c.doRequest(req, true)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(err, "DeleteTxtRecord() finished with error")
return err return err
} }
// have we hit the rate limit? // have we hit the rate limit?
if status == http.StatusTooManyRequests { if status == http.StatusTooManyRequests {
klog.V(2).ErrorS(fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests), "DeleteTxtRecord() finished with error") klog.ErrorS( nil, "DeleteTxtRecord() finished with errori 'too many requests' reported by Variomedia")
return fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests) return fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests)
} }
if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted { if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(nil, "DeleteTxtRecord() finished with error reported by server", "status code", status)
return fmt.Errorf("failed deleting TXT record: %v", err) return fmt.Errorf("failed deleting TXT record: %v", err)
} }
@@ -264,7 +264,7 @@ func (c *variomediaClient) DeleteTxtRecord(url string, ttl int) error {
var reply variomediaResponse var reply variomediaResponse
err = json.Unmarshal( respData, &reply) err = json.Unmarshal( respData, &reply)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(err, "DeleteTxtRecord() finished with error")
return fmt.Errorf("cannot unmarshall response to json: %v", err) return fmt.Errorf("cannot unmarshall response to json: %v", err)
} }
klog.V(5).InfoS( "HTTP finished", "JSON reply", reply) klog.V(5).InfoS( "HTTP finished", "JSON reply", reply)
@@ -281,25 +281,25 @@ func (c *variomediaClient) DeleteTxtRecord(url string, ttl int) error {
// re-fetch the job status // re-fetch the job status
req, err := http.NewRequest("GET", reply.Data.Links[ "queue-job"], nil) req, err := http.NewRequest("GET", reply.Data.Links[ "queue-job"], nil)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(err, "DeleteTxtRecord() finished with error")
return err return err
} }
// contact Variomedia and check the results // contact Variomedia and check the results
status, respData, err := c.doRequest(req, true) status, respData, err := c.doRequest(req, true)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(err, "DeleteTxtRecord() finished with error")
return err return err
} }
// have we hit the rate limit? // have we hit the rate limit?
if status == http.StatusTooManyRequests { if status == http.StatusTooManyRequests {
klog.V(2).ErrorS(fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests), "DeleteTxtRecord() finished with error") klog.ErrorS( nil, "DeleteTxtRecord() finished with errori 'too many requests' reported by Variomedia")
return fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests) return fmt.Errorf("Variomedia rate limit reached (HTTP code %d)", http.StatusTooManyRequests)
} }
if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted && status != http.StatusNotFound { if status != http.StatusCreated && status != http.StatusOK && status != http.StatusAccepted && status != http.StatusNotFound {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(nil, "DeleteTxtRecord() finished with error reported by server", "status code", status)
return fmt.Errorf("failed creating TXT record: %v", err) return fmt.Errorf("failed creating TXT record: %v", err)
} }
@@ -307,7 +307,7 @@ func (c *variomediaClient) DeleteTxtRecord(url string, ttl int) error {
// check the response for an according '' element // check the response for an according '' element
err = json.Unmarshal( respData, &reply) err = json.Unmarshal( respData, &reply)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "DeleteTxtRecord() finished with error") klog.ErrorS(err, "DeleteTxtRecord() finished with error")
return fmt.Errorf("cannot unmarshall response to json: %v", err) return fmt.Errorf("cannot unmarshall response to json: %v", err)
} }
klog.V(5).InfoS( "HTTP finished", "JSON reply", reply) klog.V(5).InfoS( "HTTP finished", "JSON reply", reply)
@@ -327,7 +327,7 @@ func (c *variomediaClient) DeleteTxtRecord(url string, ttl int) error {
break; break;
} }
if (loopcount == 0) { if (loopcount == 0) {
klog.V(2).ErrorS(fmt.Errorf("DNS update job timed out with most recent status '%s'", reply.Data.Attributes[ "status"]), "DeleteTxtRecord() finished with error") klog.ErrorS(nil, "DeleteTxtRecord() finished with error: job timed out", "most recent status", reply.Data.Attributes[ "status"])
return fmt.Errorf("DNS update job timed out with most recent status '%s'", reply.Data.Attributes[ "status"]) return fmt.Errorf("DNS update job timed out with most recent status '%s'", reply.Data.Attributes[ "status"])
} }
} // emulated do until } // emulated do until
@@ -363,7 +363,7 @@ func (c *variomediaClient) doRequest(req *http.Request, readResponseBody bool) (
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "doRequest() finished with error") klog.ErrorS(err, "doRequest() finished with error")
return 0, nil, err return 0, nil, err
} }
@@ -373,7 +373,7 @@ func (c *variomediaClient) doRequest(req *http.Request, readResponseBody bool) (
if (res.StatusCode == http.StatusOK || res.StatusCode == http.StatusAccepted) && readResponseBody { if (res.StatusCode == http.StatusOK || res.StatusCode == http.StatusAccepted) && readResponseBody {
data, err := ioutil.ReadAll(res.Body) data, err := ioutil.ReadAll(res.Body)
if err != nil { if err != nil {
klog.V(2).ErrorS(err, "HTTP request finished with error") klog.ErrorS(err, "HTTP request finished with error")
return 0, nil, err return 0, nil, err
} }
klog.V(4).InfoS( "HTTP request succeeded", "status code", res.StatusCode) klog.V(4).InfoS( "HTTP request succeeded", "status code", res.StatusCode)