Skip to content

Commit 1f2c5b8

Browse files
authored
Merge 5d3d916 into f73a0f8
2 parents f73a0f8 + 5d3d916 commit 1f2c5b8

25 files changed

Lines changed: 642 additions & 440 deletions

.github/workflows/test.yml

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
name: Build and Test
1+
name: Build Test and Lint
22
on:
3+
workflow_dispatch:
34
pull_request:
45
push:
56
branches:
67
- 'main'
78
- 'release-*.*'
89
jobs:
910
build:
10-
name: Build and Lint
11+
name: Build and Test
1112
runs-on: ubuntu-latest
12-
timeout-minutes: 8
13+
timeout-minutes: 10
1314
steps:
1415
# Checkout code
1516
# https://github.com/actions/checkout
@@ -30,19 +31,13 @@ jobs:
3031
# Build Go binary
3132
- run: go build -v cmd/main.go
3233

33-
- name: Regenerate CRDs
34-
run: make generate manifests
35-
36-
- name: Check for CRD drift
37-
run: |
38-
git diff --compact-summary --exit-code || \
39-
(echo; echo "Unexpected difference in directories after code generation. Run 'make generate manifests' and commit."; exit 1)
34+
- run: go test ./...
4035

41-
test:
42-
name: Go Test
36+
lint:
37+
name: Lint
4338
needs: build
4439
runs-on: ubuntu-latest
45-
timeout-minutes: 15
40+
timeout-minutes: 10
4641
steps:
4742
# Checkout code
4843
# https://github.com/actions/checkout
@@ -57,6 +52,23 @@ jobs:
5752
go-version-file: 'go.mod'
5853
cache: true
5954

60-
# Run Go tests
61-
- name: Run go test
62-
run: go test -v ./...
55+
- name: Install Helm
56+
uses: azure/setup-helm@v3.5
57+
58+
# Run Go linters
59+
# https://github.com/golangci/golangci-lint-action
60+
- name: Run linters
61+
uses: golangci/golangci-lint-action@v7
62+
with:
63+
version: v2.4.0
64+
65+
- name: Regenerate CRDs
66+
run: make generate manifests
67+
68+
- name: Check for CRD drift
69+
run: |
70+
git diff --compact-summary --exit-code -- config/crd deploy/charts || \
71+
(echo; echo "Unexpected difference in directories after code generation. Run 'make generate manifests' and commit."; exit 1)
72+
73+
- name: Lint Helm manifests
74+
run: make lint-manifests

.golangci.yml

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,46 @@
1-
run:
2-
# timeout for analysis, e.g. 30s, 5m, default is 1m
3-
timeout: 12m
4-
5-
skip-dirs:
6-
- testdata$
7-
- test/mock
8-
- go/pkg/mod
9-
10-
skip-files:
11-
- ".*\\.pb\\.go"
12-
1+
version: "2"
132
linters:
143
enable:
154
- bodyclose
165
- durationcheck
176
- errorlint
18-
- goimports
19-
- revive
7+
- gocritic
208
- gosec
219
- misspell
2210
- nakedret
11+
- nolintlint
12+
- revive
2313
- unconvert
2414
- unparam
25-
- whitespace
26-
- gocritic
27-
- nolintlint
28-
29-
linters-settings:
30-
revive:
31-
# minimal confidence for issues, default is 0.8
32-
confidence: 0.0
15+
settings:
16+
revive:
17+
confidence: 0
18+
rules:
19+
- name: var-naming
20+
disabled: true
21+
exclusions:
22+
generated: lax
23+
presets:
24+
- comments
25+
- common-false-positives
26+
- legacy
27+
- std-error-handling
28+
paths:
29+
- .*\.pb\.go
30+
- testdata$
31+
- test/mock
32+
- third_party$
33+
- builtin$
34+
- examples$
35+
formatters:
36+
enable:
37+
- goimports
38+
exclusions:
39+
generated: lax
40+
paths:
41+
- .*\.pb\.go
42+
- testdata$
43+
- test/mock
44+
- third_party$
45+
- builtin$
46+
- examples$

.kube-linter.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
checks:
2+
addAllBuiltIn: true
3+
# Add project-specific exclusions below as needed, e.g.:
4+
# exclude:
5+
# - "unset-cpu-requirements"
6+
# - "unset-memory-requirements"

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# v2.5.2
2+
## Fixes
3+
- 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.
4+
- Fixes an issue where the error message from a failed Enrollment API call is not logged.
5+
## Chores
6+
- Update GitHub Actions workflow to check for policy enforcement on Helm chart rendered manifests in addition to checking for drift in generated CRDs.
7+
- Fixes various linting issues in the codebase.
8+
19
# v2.5.1
210
## Fixes
311
- Fixes an issue where OAuth 2.0 client credentials were being regenerated on every API call.

CONTRIBUTING.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Command Cert Manager Issuer Contribution Guide
2+
3+
## Requirements
4+
- Go (>= 1.24)
5+
- golangci-lint (>= 2.4.0) ([installation notes](https://github.com/golangci/golangci-lint?tab=readme-ov-file#install-golangci-lint))
6+
- helm (>= 3.x) — required to render chart templates for manifest linting ([installation notes](https://helm.sh/docs/intro/install/))
7+
- conftest — policy testing tool powered by Open Policy Agent; installed automatically by `make lint-manifests`
8+
9+
## Installing dependencies
10+
Project dependencies can be installed by running the following:
11+
12+
```bash
13+
go mod download
14+
```
15+
16+
The following command can be used to add missing requirements or remove unused modules:
17+
18+
```bash
19+
go mod tidy
20+
```
21+
22+
## Running unit tests
23+
The following command can be run to run the project unit tests:
24+
25+
```bash
26+
go test -v ./...
27+
```
28+
29+
## Running linters
30+
The project uses golangci-lint to lint the codebase. The following command can be run to run the linters:
31+
32+
```bash
33+
golangci-lint run
34+
```
35+
36+
or, alternatively:
37+
38+
```bash
39+
make lint
40+
```
41+
42+
## Updating generated manifests
43+
44+
This command will update the generated custom resource definitions under `config/crd/bases`:
45+
46+
```bash
47+
make generate manifests
48+
```
49+
50+
> [!IMPORTANT]
51+
> There is no automated process to automatically update the CRDs under `deploy/charts/command-cert-manager-issuer`. If any changes are made to the CRDs, the generated CRDs under `config/crd/bases` must be copied to `deploy/charts/command-cert-manager-issuer/crds` to ensure the Helm chart is up to date.
52+
53+
## Linting Helm manifests
54+
55+
The Helm chart under `deploy/charts/command-cert-manager-issuer` is linted with two tools on every PR:
56+
- **conftest** — runs custom Rego policies located in the [`policy/`](policy/) directory against the rendered manifests
57+
58+
To run both checks locally:
59+
60+
```bash
61+
make lint-manifests
62+
```
63+
64+
`conftest` is downloaded automatically into `bin/` on first use; no manual installation is required.
65+
66+
To inspect the rendered templates without linting:
67+
68+
```bash
69+
make helm-template
70+
```
71+
72+
### Adding or modifying policies
73+
74+
Rego policies live in [`policy/`](policy/). Each `.rego` file in that directory is evaluated by conftest against every resource in the rendered chart. Add a new `.rego` file to enforce additional rules. For example, `policy/roles.rego` enforces that all `Role` resources declare an explicit namespace.
75+
76+
kube-linter checks can be tuned in [.kube-linter.yaml](.kube-linter.yaml). To exclude a check, add its name under the `exclude` key.
77+
78+
## Running end-to-end tests
79+
A comprehensive end-to-end test suite is available to verify the issuer code works against cert-manager and a Keyfactor Command instance.
80+
81+
Instructions on how to run the end-to-end test suite can be found [here](./e2e/README.md).

Makefile

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ endif
1717
# tools. (i.e. podman)
1818
CONTAINER_TOOL ?= docker
1919

20+
# Helm chart and Conftest policy directory for manifest linting
21+
HELM_CHART_DIR ?= deploy/charts/command-cert-manager-issuer
22+
POLICY_DIR ?= policy
23+
2024
# Setting SHELL to bash allows bash commands to be executed by recipes.
2125
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
2226
SHELL = /usr/bin/env bash -o pipefail
@@ -78,6 +82,20 @@ lint: golangci-lint ## Run golangci-lint linter & yamllint
7882
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
7983
$(GOLANGCI_LINT) run --fix
8084

85+
.PHONY: helm-template
86+
helm-template: ## Render Helm chart templates to stdout (includes CRDs).
87+
helm template ejbca-cert-manager-issuer $(HELM_CHART_DIR) --include-crds
88+
89+
.PHONY: lint-manifests
90+
lint-manifests: conftest ## Run Conftest policy checks against every CI values file in $(HELM_CHART_DIR)/ci/.
91+
@failed=0; \
92+
for f in $(HELM_CHART_DIR)/ci/*-values.yaml; do \
93+
echo "==> $$(basename $$f)"; \
94+
helm template ejbca-cert-manager-issuer $(HELM_CHART_DIR) --include-crds -f "$$f" \
95+
| $(CONFTEST) test --policy $(POLICY_DIR) - || failed=1; \
96+
done; \
97+
exit $$failed
98+
8199
##@ Build
82100

83101
.PHONY: build
@@ -162,18 +180,32 @@ KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION)
162180
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION)
163181
ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION)
164182
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
183+
KUBE_LINTER = $(LOCALBIN)/kube-linter-$(KUBE_LINTER_VERSION)
184+
CONFTEST = $(LOCALBIN)/conftest-$(CONFTEST_VERSION)
165185

166186
## Tool Versions
167187
KUSTOMIZE_VERSION ?= v5.3.0
168188
CONTROLLER_TOOLS_VERSION ?= v0.14.0
169189
ENVTEST_VERSION ?= latest
170-
GOLANGCI_LINT_VERSION ?= v1.60.1
190+
GOLANGCI_LINT_VERSION ?= v2.4.0
191+
KUBE_LINTER_VERSION ?= v0.6.8
192+
CONFTEST_VERSION ?= v0.60.0
171193

172194
.PHONY: kustomize
173195
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
174196
$(KUSTOMIZE): $(LOCALBIN)
175197
$(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION))
176198

199+
.PHONY: kube-linter
200+
kube-linter: $(KUBE_LINTER) ## Download kube-linter locally if necessary.
201+
$(KUBE_LINTER): $(LOCALBIN)
202+
$(call go-install-tool,$(KUBE_LINTER),golang.stackrox.io/kube-linter/cmd/kube-linter,$(KUBE_LINTER_VERSION))
203+
204+
.PHONY: conftest
205+
conftest: $(CONFTEST) ## Download conftest locally if necessary.
206+
$(CONFTEST): $(LOCALBIN)
207+
$(call go-install-tool,$(CONFTEST),github.com/open-policy-agent/conftest,$(CONFTEST_VERSION))
208+
177209
.PHONY: controller-gen
178210
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
179211
$(CONTROLLER_GEN): $(LOCALBIN)
@@ -187,7 +219,12 @@ $(ENVTEST): $(LOCALBIN)
187219
.PHONY: golangci-lint
188220
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
189221
$(GOLANGCI_LINT): $(LOCALBIN)
190-
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION})
222+
@[ -f $(GOLANGCI_LINT) ] || { \
223+
set -e; \
224+
echo "Downloading golangci-lint $(GOLANGCI_LINT_VERSION)" ;\
225+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh | sh -s -- -b $(LOCALBIN) $(GOLANGCI_LINT_VERSION) ;\
226+
mv $(LOCALBIN)/golangci-lint $(GOLANGCI_LINT) ;\
227+
}
191228

192229
# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
193230
# $1 - target path with name of binary (ideally with version)

api/v1alpha1/issuer_types.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,9 @@ func (is *IssuerStatus) HasCondition(conditionType IssuerConditionType, state Co
201201
}
202202

203203
func (is *IssuerStatus) UnsetCondition(conditionType IssuerConditionType) {
204-
conditions := is.Conditions
205-
for i, c := range conditions {
204+
for i, c := range is.Conditions {
206205
if c.Type == conditionType {
207-
is.Conditions = append(conditions[:i], conditions[i+1:]...)
206+
is.Conditions = append(is.Conditions[:i], is.Conditions[i+1:]...)
208207
return
209208
}
210209
}

api/v1alpha1/issuer_types_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func TestIssuerStatus_SetCondition_UpdateConditionStatus(t *testing.T) {
6868
assert.Equal(t, "NewMessage", cond.Message)
6969

7070
// LastTransitionTime should be updated because status changed from ConditionFalse -> ConditionTrue
71-
assert.True(t, cond.LastTransitionTime.Time.After(now.Time), "LastTransitionTime should be more recent if the status changed.")
71+
assert.True(t, cond.LastTransitionTime.After(now.Time), "LastTransitionTime should be more recent if the status changed.")
7272
}
7373

7474
func TestIssuerStatus_SetCondition_NoStatusChange(t *testing.T) {

cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func main() {
197197
}
198198

199199
if defaultHealthCheckInterval < time.Duration(30)*time.Second {
200-
setupLog.Error(errors.New(fmt.Sprintf("interval %s is invalid, must be greater than or equal to '30s'", healthCheckInterval)), "invalid health check interval")
200+
setupLog.Error(fmt.Errorf("interval %s is invalid, must be greater than or equal to '30s'", healthCheckInterval), "invalid health check interval")
201201
os.Exit(1)
202202
}
203203

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Cluster-wide access configuration — exercises ClusterRole/ClusterRoleBinding
2+
# paths for secret and configmap access, and enables secure metrics.
3+
secretConfig:
4+
useClusterRoleForSecretAccess: true
5+
useClusterRoleForConfigMapAccess: true
6+
metrics:
7+
secure: true

0 commit comments

Comments
 (0)