From d63a4674317497fd6700c52c705649ce85ac3725 Mon Sep 17 00:00:00 2001 From: Tomasz Wrobel Date: Tue, 13 Jul 2021 16:47:08 +0200 Subject: [OOM-K8S-CERT-EXTERNAL-PROVIDER] Add send update request functionality Issue-ID: OOM-2753 Signed-off-by: Tomasz Wrobel Change-Id: I0637ded5c870cc66c7dc27dff269dab0f7d9015b --- .../src/certserviceclient/cert_service_client.go | 31 ++++++++++-- .../cert_service_client_factory.go | 15 +++--- .../cert_service_client_factory_test.go | 53 +++++++++++--------- .../certserviceclient/cert_service_client_mock.go | 11 ++++- .../certserviceclient/cert_service_client_test.go | 56 +++++++++++++++++++++- 5 files changed, 131 insertions(+), 35 deletions(-) (limited to 'certServiceK8sExternalProvider/src/certserviceclient') diff --git a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client.go b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client.go index 4806c4a1..f4cc9991 100644 --- a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client.go +++ b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client.go @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * oom-certservice-k8s-external-provider * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,21 +25,27 @@ import ( "encoding/json" "fmt" "net/http" + + "onap.org/oom-certservice/k8s-external-provider/src/model" ) const ( - CsrHeaderName = "CSR" - PkHeaderName = "PK" + CsrHeaderName = "CSR" + PkHeaderName = "PK" + OldPkHeaderName = "OLD_PK" + OldCertificateHeaderName = "OLD_CERT" ) type CertServiceClient interface { GetCertificates(csr []byte, key []byte) (*CertificatesResponse, error) CheckHealth() error + UpdateCertificate(csr []byte, key []byte, signCertificateModel model.SignCertificateModel) (*CertificatesResponse, error) } type CertServiceClientImpl struct { healthUrl string certificationUrl string + updateUrl string httpClient HTTPClient } @@ -83,6 +89,25 @@ func (client *CertServiceClientImpl) GetCertificates(csr []byte, key []byte) (*C request.Header.Add(CsrHeaderName, base64.StdEncoding.EncodeToString(csr)) request.Header.Add(PkHeaderName, base64.StdEncoding.EncodeToString(key)) + + return client.executeRequest(request) +} + +func (client *CertServiceClientImpl) UpdateCertificate(csr []byte, key []byte, signCertificateModel model.SignCertificateModel) (*CertificatesResponse, error) { + request, err := http.NewRequest("GET", client.updateUrl, nil) + if err != nil { + return nil, err + } + + request.Header.Add(CsrHeaderName, base64.StdEncoding.EncodeToString(csr)) + request.Header.Add(PkHeaderName, base64.StdEncoding.EncodeToString(key)) + request.Header.Add(OldPkHeaderName, signCertificateModel.OldPrivateKey) + request.Header.Add(OldCertificateHeaderName, signCertificateModel.OldCertificate) + + return client.executeRequest(request) +} + +func (client *CertServiceClientImpl) executeRequest(request *http.Request) (*CertificatesResponse, error) { response, err := client.httpClient.Do(request) if err != nil { return nil, err diff --git a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory.go b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory.go index 0fa1d165..380cbcf9 100644 --- a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory.go +++ b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory.go @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * oom-certservice-k8s-external-provider * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import ( "path" ) -func CreateCertServiceClient(baseUrl string, healthEndpoint string, certEndpoint string, caName string, +func CreateCertServiceClient(baseUrl string, healthEndpoint string, certEndpoint string, updateEndpoint string, caName string, keyPemBase64 []byte, certPemBase64 []byte, cacertPemBase64 []byte) (*CertServiceClientImpl, error) { cert, err := tls.X509KeyPair(certPemBase64, keyPemBase64) if err != nil { @@ -49,31 +49,34 @@ func CreateCertServiceClient(baseUrl string, healthEndpoint string, certEndpoint }, }, } - healthUrl, certificationUrl, err := validateAndParseUrls(baseUrl, healthEndpoint, certEndpoint, caName) + healthUrl, certificationUrl, updateUrl, err := validateAndParseUrls(baseUrl, healthEndpoint, certEndpoint, updateEndpoint, caName) if err != nil { return nil, err } client := CertServiceClientImpl{ healthUrl: healthUrl, certificationUrl: certificationUrl, + updateUrl: updateUrl, httpClient: httpClient, } return &client, nil } -func validateAndParseUrls(baseUrl string, healthEndpoint string, certEndpoint string, caName string) (string, string, error) { +func validateAndParseUrls(baseUrl string, healthEndpoint string, certEndpoint string, updateEndpoint string, caName string) (string, string, string, error) { if err := validateUrls(baseUrl, healthEndpoint, certEndpoint, caName); err != nil { - return "", "", err + return "", "", "", err } certUrl, _ := url.Parse(baseUrl) healthUrl, _ := url.Parse(baseUrl) + updateUrl, _ := url.Parse(baseUrl) certUrl.Path = path.Join(certEndpoint, caName) healthUrl.Path = path.Join(healthEndpoint) + updateUrl.Path = path.Join(updateEndpoint, caName) - return healthUrl.String(), certUrl.String(), nil + return healthUrl.String(), certUrl.String(), updateUrl.String(), nil } func validateUrls(baseUrl string, healthEndpoint string, certEndpoint string, caName string) error { diff --git a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory_test.go b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory_test.go index 5d255a62..a844e53c 100644 --- a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory_test.go +++ b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_factory_test.go @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * oom-certservice-k8s-external-provider * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,17 +29,19 @@ import ( ) const ( - validUrl = "https://oom-cert-service:8443/" - validUrl2 = "https://oom-cert-service:8443" - invalidUrl = "https://oom-cert service:8443/" - healthEndpoint = "actuator/health" - healthEndpointInvalid = ":/actuator/health" - certEndpoint = "v1/certificate" - certEndpointInvalid = ":/v1/certificate" - caName = "RA" - caNameInvalid = ":/RA" - expectedCertificationUrl = "https://oom-cert-service:8443/v1/certificate/RA" - expectedHealthCheckUrl = "https://oom-cert-service:8443/actuator/health" + validUrl = "https://oom-cert-service:8443/" + validUrl2 = "https://oom-cert-service:8443" + invalidUrl = "https://oom-cert service:8443/" + healthEndpoint = "actuator/health" + healthEndpointInvalid = ":/actuator/health" + certEndpoint = "v1/certificate" + updateEndpoint = "v1/certificate-update" + certEndpointInvalid = ":/v1/certificate" + certUpdateEndpointInvalid = ":/v1/certificate-update" + caName = "RA" + caNameInvalid = ":/RA" + expectedCertificationUrl = "https://oom-cert-service:8443/v1/certificate/RA" + expectedHealthCheckUrl = "https://oom-cert-service:8443/actuator/health" ) func Test_shouldCreateCertServiceClient(t *testing.T) { @@ -48,7 +50,7 @@ func Test_shouldCreateCertServiceClient(t *testing.T) { } func shouldCreateCertServiceClientWithExpectedUrl(t *testing.T, baseUrl string) { - client, err := CreateCertServiceClient(baseUrl, healthEndpoint, certEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(baseUrl, healthEndpoint, certEndpoint, updateEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) assert.NotNil(t, client) assert.Nil(t, err) @@ -57,42 +59,49 @@ func shouldCreateCertServiceClientWithExpectedUrl(t *testing.T, baseUrl string) } func Test_shouldReturnError_whenCaNameInvalid(t *testing.T) { - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, caNameInvalid, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, updateEndpoint, caNameInvalid, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) } func Test_shouldReturnError_whenHealthEndpointInvalid(t *testing.T) { - client, err := CreateCertServiceClient(validUrl, healthEndpointInvalid, certEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpointInvalid, certEndpoint, updateEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) } func Test_shouldReturnError_whenCertEndpointInvalid(t *testing.T) { - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpointInvalid, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpointInvalid, updateEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + + assert.Nil(t, client) + assert.Error(t, err) +} + +func Test_shouldReturnError_whenUpdateCertificateEndpointInvalid(t *testing.T) { + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, certUpdateEndpointInvalid, caName, testdata.KeyBytes, testdata.CertBytes, testdata.KeyBytes) assert.Nil(t, client) assert.Error(t, err) } func Test_shouldReturnError_whenUrlInvalid(t *testing.T) { - client, err := CreateCertServiceClient(invalidUrl, healthEndpoint, certEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(invalidUrl, healthEndpoint, certEndpoint, updateEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) } func Test_shouldReturnError_whenCanameEmpty(t *testing.T) { - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, "", testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, updateEndpoint, "", testdata.KeyBytes, testdata.CertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) } func Test_shouldReturnError_whenKeyNotMatchingCert(t *testing.T) { - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, caName, testdata.NotMatchingKeyBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, updateEndpoint, caName, testdata.NotMatchingKeyBytes, testdata.CertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) @@ -100,7 +109,7 @@ func Test_shouldReturnError_whenKeyNotMatchingCert(t *testing.T) { func Test_shouldReturnError_whenKeyInvalid(t *testing.T) { //Cert used as key - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, caName, testdata.CertBytes, testdata.CertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, updateEndpoint, caName, testdata.CertBytes, testdata.CertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) @@ -108,7 +117,7 @@ func Test_shouldReturnError_whenKeyInvalid(t *testing.T) { func Test_shouldReturnError_whenCertInvalid(t *testing.T) { //Cacert used as cert - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, caName, testdata.KeyBytes, testdata.CacertBytes, testdata.CacertBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, updateEndpoint, caName, testdata.KeyBytes, testdata.CacertBytes, testdata.CacertBytes) assert.Nil(t, client) assert.Error(t, err) @@ -116,7 +125,7 @@ func Test_shouldReturnError_whenCertInvalid(t *testing.T) { func Test_shouldReturnError_whenCacertInvalid(t *testing.T) { //Key used as cacert - client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.KeyBytes) + client, err := CreateCertServiceClient(validUrl, healthEndpoint, certEndpoint, updateEndpoint, caName, testdata.KeyBytes, testdata.CertBytes, testdata.KeyBytes) assert.Nil(t, client) assert.Error(t, err) diff --git a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go index d060a980..a6fec1fd 100644 --- a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go +++ b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * oom-certservice-k8s-external-provider * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,15 @@ package certserviceclient +import "onap.org/oom-certservice/k8s-external-provider/src/model" + type CertServiceClientMock struct { - GetCertificatesFunc func(csr []byte, key []byte) (*CertificatesResponse, error) + GetCertificatesFunc func(csr []byte, key []byte) (*CertificatesResponse, error) + UpdateCertificateFunc func(csr []byte, key []byte, signCertificateModel model.SignCertificateModel) (*CertificatesResponse, error) +} + +func (client *CertServiceClientMock) UpdateCertificate(csr []byte, key []byte, signCertificateModel model.SignCertificateModel) (*CertificatesResponse, error) { + return client.UpdateCertificateFunc(csr, key, signCertificateModel) } func (client *CertServiceClientMock) GetCertificates(csr []byte, key []byte) (*CertificatesResponse, error) { diff --git a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_test.go b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_test.go index 5e80f7f7..e1c6bb91 100644 --- a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_test.go +++ b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_test.go @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * oom-certservice-k8s-external-provider * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,11 +30,13 @@ import ( "github.com/stretchr/testify/assert" + "onap.org/oom-certservice/k8s-external-provider/src/model" "onap.org/oom-certservice/k8s-external-provider/src/testdata" ) const ( - certificationUrl = "https://oom-cert-service:8443/v1/certificate/RA" + certificationUrl = "https://oom-cert-service:8443/v1/certificate/RA" + certificateUpdateUrl = "https://oom-cert-service:8443/v1/certificate-update/RA" ) func Test_GetCertificates_shouldParseCertificateResponseCorrectly(t *testing.T) { @@ -97,6 +99,48 @@ func Test_GetCertificates_shouldReturnError_whenResponseOtherThan200(t *testing. assert.Error(t, err) } +func Test_UpdateCertificates_shouldParseCertificateResponseCorrectly(t *testing.T) { + responseJson := `{"certificateChain": ["cert-0", "cert-1"], "trustedCertificates": ["trusted-cert-0", "trusted-cert-1"]}` + responseJsonReader := ioutil.NopCloser(bytes.NewReader([]byte(responseJson))) + client := CertServiceClientImpl{ + updateUrl: certificateUpdateUrl, + httpClient: getMockedClient(responseJsonReader, http.StatusOK), + } + + response, _ := client.UpdateCertificate(testdata.CsrBytes, testdata.PkBytes, getTestSignCertificateModel()) + assert.ElementsMatch(t, []string{"cert-0", "cert-1"}, response.CertificateChain) + assert.ElementsMatch(t, []string{"trusted-cert-0", "trusted-cert-1"}, response.TrustedCertificates) +} + + +func Test_UpdateCertificates_shouldReturnError_whenHttpClientReturnsError(t *testing.T) { + client := CertServiceClientImpl{ + updateUrl: certificateUpdateUrl, + httpClient: &httpClientMock{ + DoFunc: func(req *http.Request) (response *http.Response, err error) { + return nil, fmt.Errorf("mock error") + }, + }, + } + response, err := client.UpdateCertificate(testdata.CsrBytes, testdata.PkBytes, getTestSignCertificateModel()) + + assert.Nil(t, response) + assert.Error(t, err) +} + +func Test_UpdateCertificates_shouldReturnError_whenResponseOtherThan200(t *testing.T) { + responseJson := `{"errorMessage": "CertService API error"}` + responseJsonReader := ioutil.NopCloser(bytes.NewReader([]byte(responseJson))) + client := CertServiceClientImpl{ + updateUrl: updateEndpoint, + httpClient: getMockedClient(responseJsonReader, http.StatusNotFound), + } + response, err := client.UpdateCertificate(testdata.CsrBytes, testdata.PkBytes, getTestSignCertificateModel()) + + assert.Nil(t, response) + assert.Error(t, err) +} + func Test_CheckHealth_shouldReturnNil_whenHttpClientReturnsStatusCode200(t *testing.T) { client := CertServiceClientImpl{ certificationUrl: certificationUrl, @@ -168,3 +212,11 @@ type httpClientMock struct { func (client httpClientMock) Do(req *http.Request) (*http.Response, error) { return client.DoFunc(req) } + +func getTestSignCertificateModel() model.SignCertificateModel { + testSignCertificateModel := model.SignCertificateModel{ + OldCertificate: testdata.OldCertificateEncoded, + OldPrivateKey: testdata.OldPrivateKeyEncoded, + } + return testSignCertificateModel +} -- cgit 1.2.3-korg