From c860a1e8ea07d9749fa87d44647970cce35f5024 Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:31:20 +0200 Subject: [PATCH] add VenafiConnection support for NGTS Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- .../charts/venafi-kubernetes-agent/README.md | 5 +- .../jetstack.io_venaficonnections.yaml | 2 +- .../templates/deployment.yaml | 2 +- .../tests/deployment_test.yaml | 68 +++++++++++++++++++ .../values.schema.json | 2 +- .../venafi-kubernetes-agent/values.yaml | 8 ++- go.mod | 10 +-- go.sum | 20 +++--- pkg/agent/config_test.go | 13 ++++ pkg/client/client_oauth.go | 2 +- pkg/client/client_venconn.go | 52 ++++++++++---- pkg/client/client_venconn_test.go | 4 +- 12 files changed, 149 insertions(+), 39 deletions(-) diff --git a/deploy/charts/venafi-kubernetes-agent/README.md b/deploy/charts/venafi-kubernetes-agent/README.md index 232b8d77..f4ff5db5 100644 --- a/deploy/charts/venafi-kubernetes-agent/README.md +++ b/deploy/charts/venafi-kubernetes-agent/README.md @@ -390,7 +390,10 @@ Configure VenafiConnection authentication > false > ``` -When set to true, the Discovery Agent will authenticate to CyberArk Certificate Manager using the configuration in a VenafiConnection resource. Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the +When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for. CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or +`url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and +`spec.vcp.apiKey` are rejected by the agent. +Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the Discovery Agent Pod. #### **authentication.venafiConnection.name** ~ `string` > Default value: diff --git a/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml b/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml index 90cdcb70..9389601d 100644 --- a/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml +++ b/deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.20.1 + controller-gen.kubebuilder.io/version: v0.21.0 name: venaficonnections.jetstack.io spec: group: jetstack.io diff --git a/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml b/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml index 24eb99a9..c582d504 100644 --- a/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml +++ b/deploy/charts/venafi-kubernetes-agent/templates/deployment.yaml @@ -81,8 +81,8 @@ spec: - {{ .Values.config.clientId | quote }} - "--private-key-path" - "/etc/venafi/agent/key/{{ .Values.authentication.secretKey }}" - {{- end }} - --venafi-cloud + {{- end }} {{- if .Values.metrics.enabled }} - --enable-metrics {{- end }} diff --git a/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml b/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml index f1e27510..9f770ff1 100644 --- a/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml +++ b/deploy/charts/venafi-kubernetes-agent/tests/deployment_test.yaml @@ -133,3 +133,71 @@ tests: - lengthEqual : path: spec.template.spec.containers[0].env count: 4 + + # VenafiConnection mode (used for both VCP and NGTS backends) wires the + # connection name/namespace through as flags and skips mounting the keypair + # Secret. The Secret-based --client-id / --private-key-path flags must not be + # present in this mode. + - it: VenafiConnection mode passes the connection flags and omits the credentials Secret + set: + authentication.venafiConnection.enabled: true + authentication.venafiConnection.name: my-venconn + authentication.venafiConnection.namespace: my-ns + template: deployment.yaml + asserts: + - isKind: + of: Deployment + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-connection + - contains: + path: spec.template.spec.containers[0].args + content: my-venconn + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-connection-namespace + - contains: + path: spec.template.spec.containers[0].args + content: my-ns + - notContains: + path: spec.template.spec.containers[0].args + content: --client-id + - notContains: + path: spec.template.spec.containers[0].args + content: --private-key-path + - notContains: + path: spec.template.spec.containers[0].args + content: --venafi-cloud + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: credentials + mountPath: /etc/venafi/agent/key + readOnly: true + - notContains: + path: spec.template.spec.volumes + content: + name: credentials + secret: + secretName: agent-credentials + optional: false + + # Keypair mode (the default, used when authentication.venafiConnection.enabled + # is false) still renders --venafi-cloud since the agent's mode-resolution + # treats keypair as a Venafi Cloud backend. + - it: Keypair mode still passes --venafi-cloud + set: + config.clientId: "00000000-0000-0000-0000-000000000000" + template: deployment.yaml + asserts: + - isKind: + of: Deployment + - contains: + path: spec.template.spec.containers[0].args + content: --venafi-cloud + - contains: + path: spec.template.spec.containers[0].args + content: --client-id + - contains: + path: spec.template.spec.containers[0].args + content: --private-key-path diff --git a/deploy/charts/venafi-kubernetes-agent/values.schema.json b/deploy/charts/venafi-kubernetes-agent/values.schema.json index 48a04b63..b7fe9506 100644 --- a/deploy/charts/venafi-kubernetes-agent/values.schema.json +++ b/deploy/charts/venafi-kubernetes-agent/values.schema.json @@ -137,7 +137,7 @@ }, "helm-values.authentication.venafiConnection.enabled": { "default": false, - "description": "When set to true, the Discovery Agent will authenticate to CyberArk Certificate Manager using the configuration in a VenafiConnection resource. Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the\nDiscovery Agent Pod.", + "description": "When set to true, the Discovery Agent will authenticate to its upload backend using the configuration in a VenafiConnection resource. The backend is determined by the VenafiConnection's spec: use `spec.vcp` for. CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or\n`url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and\n`spec.vcp.apiKey` are rejected by the agent.\nUse `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). When set to true, the `authentication.secret` values will be ignored and the. Secret with `authentication.secretName` will _not_ be mounted into the\nDiscovery Agent Pod.", "type": "boolean" }, "helm-values.authentication.venafiConnection.name": { diff --git a/deploy/charts/venafi-kubernetes-agent/values.yaml b/deploy/charts/venafi-kubernetes-agent/values.yaml index 92829937..c40c9d4b 100644 --- a/deploy/charts/venafi-kubernetes-agent/values.yaml +++ b/deploy/charts/venafi-kubernetes-agent/values.yaml @@ -238,8 +238,12 @@ authentication: # +docs:section=Venafi Connection # Configure VenafiConnection authentication venafiConnection: - # When set to true, the Discovery Agent will authenticate to CyberArk Certificate Manager - # using the configuration in a VenafiConnection resource. + # When set to true, the Discovery Agent will authenticate to its upload + # backend using the configuration in a VenafiConnection resource. The + # backend is determined by the VenafiConnection's spec: use `spec.vcp` for + # CyberArk Certificate Manager (CMSaaS), or `spec.ngts` (with `tsgID` or + # `url`, and a `jwt` source) for NGTS / Palo Alto Networks. `spec.tpp` and + # `spec.vcp.apiKey` are rejected by the agent. # Use `venafiConnection.enabled=true` for [secretless authentication](https://docs.cyberark.com/mis-saas/vaas/k8s-components/t-install-tlspk-agent/). # When set to true, the `authentication.secret` values will be ignored and the # Secret with `authentication.secretName` will _not_ be mounted into the diff --git a/go.mod b/go.mod index ca88f6a0..ccbbd358 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/fatih/color v1.19.0 github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/jetstack/venafi-connection-lib v0.6.0 + github.com/jetstack/venafi-connection-lib v0.6.1-0.20260528121802-f90d3d05ddd5 github.com/lestrrat-go/jwx/v3 v3.1.1 github.com/microcosm-cc/bluemonday v1.0.27 github.com/pmylund/go-cache v2.1.0+incompatible @@ -63,7 +63,7 @@ require ( go.opentelemetry.io/otel v1.41.0 // indirect go.opentelemetry.io/otel/trace v1.41.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.1 // indirect + go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.50.0 // indirect @@ -74,8 +74,8 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/ini.v1 v1.67.1 // indirect - k8s.io/apiextensions-apiserver v0.36.0 // indirect - k8s.io/apiserver v0.36.0 // indirect + k8s.io/apiextensions-apiserver v0.36.1 // indirect + k8s.io/apiserver v0.36.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect ) @@ -112,6 +112,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 k8s.io/klog/v2 v2.140.0 k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect - k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect + k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect ) diff --git a/go.sum b/go.sum index 92d9f01c..a13e4c26 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jetstack/venafi-connection-lib v0.6.0 h1:ZVR06xfJdWTKfIjVK3v4oPgc68TZNd9cYZmsi+9prFg= -github.com/jetstack/venafi-connection-lib v0.6.0/go.mod h1:XEjTVju/2ROnUEDQAyAm0Rj7Mk7HJF0/bwmS67KbwQA= +github.com/jetstack/venafi-connection-lib v0.6.1-0.20260528121802-f90d3d05ddd5 h1:bF8CfskHNjfxm5dcIhMKBSa+hWvSR0rQEzFxXcj3dBw= +github.com/jetstack/venafi-connection-lib v0.6.1-0.20260528121802-f90d3d05ddd5/go.mod h1:KPndhwwPHPkBqv7cocVTtEDPHV/CBrwapLqzUnwbCUs= 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/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -238,8 +238,8 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -293,12 +293,12 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo= -k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= -k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= +k8s.io/apiextensions-apiserver v0.36.1 h1:6JfYmPUsuUIHuN+3QxutXYWj492RqF5fBSx67GYK5Ks= +k8s.io/apiextensions-apiserver v0.36.1/go.mod h1:pLzZin90riwisdzKwv/GoTwENooytoIx5zWJb4Hkby8= k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA= k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8= -k8s.io/apiserver v0.36.0 h1:Jg5OFAENUACByUCg15CmhZAYrr5ZyJ+jodyA1mHl3YE= -k8s.io/apiserver v0.36.0/go.mod h1:mHvwdHf+qKEm+1/hYm756SV+oREOKSPnsjagOpx6Vho= +k8s.io/apiserver v0.36.1 h1:iMS5V+rPUertv5P9RaqJgmHHTuh4quWpoxchvMUY+JY= +k8s.io/apiserver v0.36.1/go.mod h1:Cby1PbLWztu0GDOxoO6iFOyyqIsziHNEW+w9zVQ22Kw= k8s.io/client-go v0.36.1 h1:FN/K8QIT2CEDt+2WB2HnWrUANZ50AP5GII43/SP2JR0= k8s.io/client-go v0.36.1/go.mod h1:s6rAnCtTGYDQnpNjEhSaISV+2O8jwruZ6m3QOYBFbtU= k8s.io/component-base v0.36.1 h1:iG6GsELftXqTNG9HG6kiVjatSgAw1sf5pJ6R5a6N0kA= @@ -307,8 +307,8 @@ k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM= -k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= diff --git a/pkg/agent/config_test.go b/pkg/agent/config_test.go index c7137ca6..9d12ef21 100644 --- a/pkg/agent/config_test.go +++ b/pkg/agent/config_test.go @@ -645,6 +645,19 @@ func Test_ValidateAndCombineConfig(t *testing.T) { assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) }) + t.Run("venafi-cloud-workload-identity-auth: --venafi-cloud is tolerated alongside --venafi-connection for backwards compatibility with older rendered charts", func(t *testing.T) { + t.Setenv("POD_NAMESPACE", "venafi") + t.Setenv("KUBECONFIG", withFile(t, fakeKubeconfig)) + got, _, err := ValidateAndCombineConfig(discardLogs(), + withConfig(testutil.Undent(` + period: 1h + cluster_name: cluster-1 + `)), + withCmdLineFlags("--venafi-connection", "venafi-components", "--venafi-cloud")) + require.NoError(t, err) + assert.Equal(t, VenafiCloudVenafiConnection, got.OutputMode) + }) + const arkUsername = "cluster-1-region-1-cloud-1@cyberark.cloud.123456" t.Run("--machine-hub selects MachineHub mode", func(t *testing.T) { diff --git a/pkg/client/client_oauth.go b/pkg/client/client_oauth.go index 5cc1e64f..b7ad93ea 100644 --- a/pkg/client/client_oauth.go +++ b/pkg/client/client_oauth.go @@ -159,8 +159,8 @@ func (c *OAuthClient) post(ctx context.Context, path string, body io.Reader) (*h return nil, err } + req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") - version.SetUserAgent(req) if len(token.bearer) > 0 { diff --git a/pkg/client/client_venconn.go b/pkg/client/client_venconn.go index 9ce0c86b..25869411 100644 --- a/pkg/client/client_venconn.go +++ b/pkg/client/client_venconn.go @@ -13,8 +13,10 @@ import ( "time" venapi "github.com/jetstack/venafi-connection-lib/api/v1alpha1" - "github.com/jetstack/venafi-connection-lib/chain/sources/venafi" + "github.com/jetstack/venafi-connection-lib/connection_details" + "github.com/jetstack/venafi-connection-lib/sources/venafi" "github.com/jetstack/venafi-connection-lib/venafi_client" + "github.com/microcosm-cc/bluemonday" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -137,17 +139,25 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading if err != nil { return fmt.Errorf("while loading the VenafiConnection %s/%s: %w", c.venConnNS, c.venConnName, err) } - if details.TPP != nil { - return fmt.Errorf(`VenafiConnection %s/%s: the agent cannot be used with TPP`, c.venConnNS, c.venConnName) - } - if details.VCP != nil && details.VCP.APIKey != "" { + server := details.ServerDetails() + switch server.BackendAuth { + case connection_details.VCPAccessToken, connection_details.NGTSAccessToken: + // Supported. + case connection_details.TPPAccessToken: + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support the TPP backend`, c.venConnNS, c.venConnName) + case connection_details.DistributedIssuerAccessToken: + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support the Distributed Issuer backend`, c.venConnNS, c.venConnName) + case connection_details.VCPAPIKey: // Although it is technically possible to use an API key, we have // decided to not allow it as it isn't recommended and will eventually // be phased out. - return fmt.Errorf(`VenafiConnection %s/%s: the agent cannot be used with an API key`, c.venConnNS, c.venConnName) + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support API key authentication with the VCP backend`, c.venConnNS, c.venConnName) + default: + return fmt.Errorf(`VenafiConnection %s/%s: the agent does not support backend auth %q`, c.venConnNS, c.venConnName, server.BackendAuth) } - if details.VCP == nil || details.VCP.AccessToken == "" { - return fmt.Errorf(`programmer mistake: VenafiConnection %s/%s: TPPAccessToken is empty in the token returned by connHandler.Get: %v`, c.venConnNS, c.venConnName, details) + token := details.Credential() + if token == "" { + return fmt.Errorf(`programmer mistake: VenafiConnection %s/%s: access token is empty in the connection details returned by connHandler.Get`, c.venConnNS, c.venConnName) } payload := api.DataReadingsPost{ @@ -160,9 +170,10 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading return err } + uploadURL := fullURL(server.BaseURL, "/v1/tlspk/upload/clusterdata/no") klog.FromContext(ctx).V(2).Info( "uploading data readings", - "url", fullURL(details.VCP.URL, "/v1/tlspk/upload/clusterdata/no"), + "url", uploadURL, "cluster_name", opts.ClusterName, "data_readings_count", len(readings), "data_size_bytes", len(data), @@ -171,21 +182,32 @@ func (c *VenConnClient) PostDataReadingsWithOptions(ctx context.Context, reading // The path parameter "no" is a dummy parameter to make the Venafi Cloud // backend happy. This parameter, named `uploaderID` in the backend, is not // actually used by the backend. - req, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL(details.VCP.URL, "/v1/tlspk/upload/clusterdata/no"), bytes.NewReader(data)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, uploadURL, bytes.NewReader(data)) if err != nil { return err } + req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", details.VCP.AccessToken)) + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) version.SetUserAgent(req) - q := req.URL.Query() - q.Set("name", opts.ClusterName) + isNGTS := server.BackendAuth == connection_details.NGTSAccessToken + + query := req.URL.Query() + stripHTML := bluemonday.StrictPolicy() + if opts.ClusterName != "" { + query.Add("name", stripHTML.Sanitize(opts.ClusterName)) + } if opts.ClusterDescription != "" { - q.Set("description", base64.RawURLEncoding.EncodeToString([]byte(opts.ClusterDescription))) + query.Add("description", base64.RawURLEncoding.EncodeToString([]byte(stripHTML.Sanitize(opts.ClusterDescription)))) } - req.URL.RawQuery = q.Encode() + if isNGTS && opts.ClaimableCerts { + // The TLSPK backend reads "certOwnership=unassigned" — this is the backend contract. + query.Set("certOwnership", "unassigned") + } + + req.URL.RawQuery = query.Encode() res, err := c.Client.Do(req) if err != nil { diff --git a/pkg/client/client_venconn_test.go b/pkg/client/client_venconn_test.go index 6b9e14a4..93db9e5f 100644 --- a/pkg/client/client_venconn_test.go +++ b/pkg/client/client_venconn_test.go @@ -156,7 +156,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) { // PostDataReadingsWithOptions failed, but Get succeeded; that's why the // condition says the VenafiConnection is ready. expectReadyCondMsg: "Generated a new token", - expectErr: "VenafiConnection error-when-the-apikey-field-is-used/venafi-components: the agent cannot be used with an API key", + expectErr: "VenafiConnection error-when-the-apikey-field-is-used/venafi-components: the agent does not support API key authentication with the VCP backend", })) t.Run("error when the tpp field is used", run_TestVenConnClient_PostDataReadingsWithOptions(ctx, restconf, kclient, testcase{ // IMPORTANT: The user may think they can use 'tpp', spend time @@ -214,7 +214,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) { namespace: venafi `), expectReadyCondMsg: "Generated a new token", - expectErr: "VenafiConnection error-when-the-tpp-field-is-used/venafi-components: the agent cannot be used with TPP", + expectErr: "VenafiConnection error-when-the-tpp-field-is-used/venafi-components: the agent does not support the TPP backend", })) }