diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 23611fd..a843b9d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -72,3 +72,16 @@ jobs: - name: Lint Helm manifests run: make lint-manifests + + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Dependency Review + uses: actions/dependency-review-action@v5 + with: + fail-on-severity: critical diff --git a/CHANGELOG.md b/CHANGELOG.md index 71e444c..fb8ab7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v2.5.3 +## Security +- Updated dependencies to address various security vulnerabilities: + - google.golang.org/grpc -> v1.79.3 (CVE-2026-33186) + - github.com/Azure/go-ntlmssp -> v0.1.1 (CVE-2026-32952) + - golang.org/x/crypto -> v0.46.0 (CVE-2025-58181 & CVE-2025-47914) + # v2.5.2 ## Fixes - Fixes an issue where a namespace may not be properly applied if applying the Helm template without a namespace specified / using `kubectl apply -f` directly with the rendered template. diff --git a/Makefile b/Makefile index 5a3b40d..caf2534 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,10 @@ lint: golangci-lint ## Run golangci-lint linter & yamllint lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes $(GOLANGCI_LINT) run --fix +.PHONY: fix +fix: + go fix ./... + .PHONY: helm-template helm-template: ## Render Helm chart templates to stdout (includes CRDs). helm template $(HELM_RELEASE_NAME) $(HELM_CHART_DIR) --include-crds diff --git a/go.mod b/go.mod index d2f1d31..0dcacbc 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ require ( github.com/Keyfactor/keyfactor-auth-client-go v1.3.1 github.com/Keyfactor/keyfactor-go-client-sdk/v25 v25.0.2 github.com/cert-manager/cert-manager v1.16.2 - github.com/go-logr/logr v1.4.2 - github.com/stretchr/testify v1.10.0 - golang.org/x/oauth2 v0.30.0 + github.com/go-logr/logr v1.4.3 + github.com/stretchr/testify v1.11.1 + golang.org/x/oauth2 v0.34.0 k8s.io/api v0.31.1 k8s.io/apimachinery v0.31.1 k8s.io/client-go v0.31.1 @@ -24,23 +24,23 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.1 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 // indirect - google.golang.org/grpc v1.70.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect ) require ( - cloud.google.com/go/compute/metadata v0.6.0 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.3.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 // indirect - github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect + github.com/Azure/go-ntlmssp v0.1.1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -86,16 +86,16 @@ require ( github.com/x448/float16 v0.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.39.0 // indirect + golang.org/x/crypto v0.46.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.41.0 - golang.org/x/sys v0.33.0 // indirect - golang.org/x/term v0.32.0 // indirect - golang.org/x/text v0.26.0 // indirect + golang.org/x/net v0.48.0 + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.10.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/api v0.223.0 - google.golang.org/protobuf v1.36.5 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 907e229..bf30c03 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= @@ -16,8 +16,9 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.3.1 h1:mrkD github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.3.1/go.mod h1:hPv41DbqMmnxcGralanA/kVlfdH5jv3T4LxGku2E1BY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww= -github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw= +github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= @@ -61,8 +62,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.6/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ= github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -168,8 +169,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI= github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -183,29 +184,29 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -219,8 +220,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -239,17 +240,17 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -262,24 +263,24 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -288,22 +289,24 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= 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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.223.0 h1:JUTaWEriXmEy5AhvdMgksGGPEFsYfUKaPEYXd4c3Wvc= google.golang.org/api v0.223.0/go.mod h1:C+RS7Z+dDwds2b+zoAk5hN/eSfsiCn0UDrYof/M4d2M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 h1:DMTIbak9GhdaSxEjvVzAeNZvyc03I61duqNbnm3SU0M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/internal/command/client.go b/internal/command/client.go index 416ebb7..28fe7e9 100644 --- a/internal/command/client.go +++ b/internal/command/client.go @@ -23,13 +23,14 @@ import ( "strings" "time" + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" v1 "github.com/Keyfactor/keyfactor-go-client-sdk/v25/api/keyfactor/v1" "github.com/go-logr/logr" "github.com/golang-jwt/jwt/v5" - "golang.org/x/net/context" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/idtoken" diff --git a/internal/controller/issuer_controller_test.go b/internal/controller/issuer_controller_test.go index 4a2c4ce..54fda8b 100644 --- a/internal/controller/issuer_controller_test.go +++ b/internal/controller/issuer_controller_test.go @@ -1621,669 +1621,3 @@ func TestCommandConfigFromIssuer(t *testing.T) { }) } } - -func TestCommandConfigFromIssuer(t *testing.T) { - type testCase struct { - name string - issuerSpec commandissuerv1alpha1.IssuerSpec - secretNamespace string - objects []client.Object - expectedConfig *command.Config - expectedError error - expectedErrorMsg string - } - - tests := []testCase{ - { - name: "success-basic-auth", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "auth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-basic-auth-with-ca-cert-secret", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "auth-secret", - CaSecretName: "ca-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - "tls.crt": []byte("-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----"), - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - CaCertsBytes: []byte("-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----"), - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-basic-auth-with-ca-cert-secret-with-key", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "auth-secret", - CaSecretName: "ca-secret", - CaBundleKey: "ca.crt", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - "tls.crt": []byte("-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----"), - "ca.crt": []byte("-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----"), - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - CaCertsBytes: []byte("-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----"), - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-basic-auth-with-ca-cert-configmap", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "auth-secret", - CaBundleConfigMapName: "ca-configmap", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-configmap", - Namespace: "ns1", - }, - Data: map[string]string{ - "tls.crt": "-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----", - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - CaCertsBytes: []byte("-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----"), - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-basic-auth-with-ca-cert-configmap-with-key", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "auth-secret", - CaBundleConfigMapName: "ca-configmap", - CaBundleKey: "ca.crt", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-configmap", - Namespace: "ns1", - }, - Data: map[string]string{ - "ca.crt": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----", - "tls.crt": "-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----", - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - CaCertsBytes: []byte("-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----"), - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-basic-auth-with-ca-cert-configmap-overwrites-secret", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "auth-secret", - CaSecretName: "ca-secret", - CaBundleConfigMapName: "ca-configmap", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - "ca.crt": []byte("-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----"), - }, - }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-configmap", - Namespace: "ns1", - }, - Data: map[string]string{ - "ca.crt": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----", - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - CaCertsBytes: []byte("-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----"), - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-oauth-minimal", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "oauth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "oauth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - commandissuer.OAuthTokenURLKey: []byte("https://oauth.example.com/token"), - commandissuer.OAuthClientIDKey: []byte("client-id"), - commandissuer.OAuthClientSecretKey: []byte("client-secret"), - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - OAuth: &command.OAuth{ - TokenURL: "https://oauth.example.com/token", - ClientID: "client-id", - ClientSecret: "client-secret", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-oauth-with-scopes-and-audience", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - SecretName: "oauth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "oauth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - commandissuer.OAuthTokenURLKey: []byte("https://oauth.example.com/token"), - commandissuer.OAuthClientIDKey: []byte("client-id"), - commandissuer.OAuthClientSecretKey: []byte("client-secret"), - commandissuer.OAuthScopesKey: []byte("scope1,scope2,scope3"), - commandissuer.OAuthAudienceKey: []byte("https://api.example.com"), - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - OAuth: &command.OAuth{ - TokenURL: "https://oauth.example.com/token", - ClientID: "client-id", - ClientSecret: "client-secret", - Scopes: []string{"scope1", "scope2", "scope3"}, - Audience: "https://api.example.com", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "success-ambient-credentials-with-scopes", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - Scopes: "scope1,scope2", - Audience: "https://api.example.com", - }, - secretNamespace: "ns1", - objects: []client.Object{}, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - AmbientCredentialScopes: []string{"scope1", "scope2"}, - AmbientCredentialAudience: "https://api.example.com", - }, - }, - { - name: "success-no-auth-secret", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - }, - secretNamespace: "ns1", - objects: []client.Object{}, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - APIPath: "/api/v1", - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - { - name: "error-auth-secret-not-found", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "missing-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{}, - expectedError: errGetAuthSecret, - }, - { - name: "error-ca-secret-not-found", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - CaSecretName: "missing-ca-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{}, - expectedError: errGetCaSecret, - }, - { - name: "error-ca-secret-key-not-found", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - CaSecretName: "ca-secret", - CaBundleKey: "ca.crt", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - "tls.crt": []byte("-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----"), - }, - }, - }, - expectedError: errGetCaBundleKey, - }, - { - name: "error-ca-configmap-not-found", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - CaBundleConfigMapName: "missing-ca-bundle", - }, - secretNamespace: "ns1", - objects: []client.Object{}, - expectedError: errGetCaConfigMap, - }, - { - name: "error-ca-configmap-key-not-found", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - CaBundleConfigMapName: "ca-configmap", - CaBundleKey: "ca.crt", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ca-configmap", - Namespace: "ns1", - }, - Data: map[string]string{ - "tls.crt": "-----BEGIN CERTIFICATE-----\nABCD...\n-----END CERTIFICATE-----", - }, - }, - }, - expectedError: errGetCaBundleKey, - }, - { - name: "error-basic-auth-no-username", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "auth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - }, - expectedError: errGetAuthSecret, - expectedErrorMsg: "found basic auth secret with no username", - }, - { - name: "error-basic-auth-no-password", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "auth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - }, - }, - }, - expectedError: errGetAuthSecret, - expectedErrorMsg: "found basic auth secret with no password", - }, - { - name: "error-oauth-no-token-url", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "oauth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "oauth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - commandissuer.OAuthClientIDKey: []byte("client-id"), - commandissuer.OAuthClientSecretKey: []byte("client-secret"), - }, - }, - }, - expectedError: errGetAuthSecret, - expectedErrorMsg: "found secret with no tokenUrl", - }, - { - name: "error-oauth-no-client-id", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "oauth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "oauth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - commandissuer.OAuthTokenURLKey: []byte("https://oauth.example.com/token"), - commandissuer.OAuthClientSecretKey: []byte("client-secret"), - }, - }, - }, - expectedError: errGetAuthSecret, - expectedErrorMsg: "found secret with no clientId", - }, - { - name: "error-oauth-no-client-secret", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "oauth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeOpaque, - ObjectMeta: metav1.ObjectMeta{ - Name: "oauth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - commandissuer.OAuthTokenURLKey: []byte("https://oauth.example.com/token"), - commandissuer.OAuthClientIDKey: []byte("client-id"), - }, - }, - }, - expectedError: errGetAuthSecret, - expectedErrorMsg: "found secret with no clientSecret", - }, - { - name: "error-unsupported-secret-type", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "auth-secret", - }, - secretNamespace: "ns1", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeTLS, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "ns1", - }, - Data: map[string][]byte{ - "tls.crt": []byte("cert"), - "tls.key": []byte("key"), - }, - }, - }, - expectedError: errGetAuthSecret, - expectedErrorMsg: "found secret with unsupported type", - }, - { - name: "success-cluster-scoped-secret-namespace", - issuerSpec: commandissuerv1alpha1.IssuerSpec{ - Hostname: "https://ca.example.com", - SecretName: "auth-secret", - }, - secretNamespace: "kube-system", - objects: []client.Object{ - &corev1.Secret{ - Type: corev1.SecretTypeBasicAuth, - ObjectMeta: metav1.ObjectMeta{ - Name: "auth-secret", - Namespace: "kube-system", - }, - Data: map[string][]byte{ - corev1.BasicAuthUsernameKey: []byte("username"), - corev1.BasicAuthPasswordKey: []byte("password"), - }, - }, - }, - expectedConfig: &command.Config{ - Hostname: "https://ca.example.com", - BasicAuth: &command.BasicAuth{ - Username: "username", - Password: "password", - }, - AmbientCredentialScopes: []string{""}, - AmbientCredentialAudience: "", - }, - }, - } - - scheme := runtime.NewScheme() - require.NoError(t, commandissuerv1alpha1.AddToScheme(scheme)) - require.NoError(t, corev1.AddToScheme(scheme)) - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - fakeClient := fake.NewClientBuilder(). - WithScheme(scheme). - WithObjects(tc.objects...). - Build() - - // Create a minimal issuer with the test spec - issuer := &commandissuerv1alpha1.Issuer{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-issuer", - Namespace: tc.secretNamespace, - }, - Spec: tc.issuerSpec, - } - - ctx := context.Background() - config, err := commandConfigFromIssuer(ctx, fakeClient, issuer, tc.secretNamespace) - - if tc.expectedError != nil { - require.Error(t, err) - assert.ErrorIs(t, err, tc.expectedError) - if tc.expectedErrorMsg != "" { - assert.Contains(t, err.Error(), tc.expectedErrorMsg) - } - assert.Nil(t, config) - } else { - require.NoError(t, err) - require.NotNil(t, config) - assert.Equal(t, tc.expectedConfig.Hostname, config.Hostname) - assert.Equal(t, tc.expectedConfig.APIPath, config.APIPath) - assert.Equal(t, tc.expectedConfig.CaCertsBytes, config.CaCertsBytes) - assert.Equal(t, tc.expectedConfig.BasicAuth, config.BasicAuth) - assert.Equal(t, tc.expectedConfig.OAuth, config.OAuth) - assert.Equal(t, tc.expectedConfig.AmbientCredentialScopes, config.AmbientCredentialScopes) - assert.Equal(t, tc.expectedConfig.AmbientCredentialAudience, config.AmbientCredentialAudience) - } - }) - } -}