Skip to content

Commit b252e1b

Browse files
committed
fixup! build: Integrate with vscode
1 parent bed7a0c commit b252e1b

File tree

9 files changed

+125
-117
lines changed

9 files changed

+125
-117
lines changed

.golangci-kal.yml

Lines changed: 0 additions & 88 deletions
This file was deleted.

.golangci.yml

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ linters:
2323
- govet
2424
- importas
2525
- ineffassign
26+
- kubeapilinter
2627
- lll
2728
- misspell
2829
- nolintlint
@@ -74,8 +75,55 @@ linters:
7475
- github.com/onsi/gomega
7576
testifylint:
7677
enable-all: true
78+
custom:
79+
kubeapilinter:
80+
type: module
81+
description: KAL is the Kube-API-Linter and lints Kube like APIs based on API conventions and best practices.
82+
settings:
83+
linters:
84+
enable:
85+
# - "commentstart" # Ensure comments start with the serialized version of the field name.
86+
# - "conditions" # Ensure conditions have the correct json tags and markers.
87+
- "duplicatemarkers" # Ensure there are no exact duplicate markers. for types and fields.
88+
- "integers" # Ensure only int32 and int64 are used for integers.
89+
- "jsontags" # Ensure every field has a json tag.
90+
- "maxlength" # Ensure all strings and arrays have maximum lengths/maximum items.
91+
- "nobools" # Bools do not evolve over time, should use enums instead.
92+
- "nofloats" # Ensure floats are not used.
93+
# - "nomaps" # Ensure maps are not used.
94+
# - "nophase" # Ensure phases are not used, as they are not extensible.
95+
- "optionalfields" # Ensure that all fields marked as optional adhere to being pointers and
96+
# having the `omitempty` value in their `json` tag where appropriate.
97+
- "optionalorrequired" # Every field should be marked as `+optional` or `+required`.
98+
- "requiredfields" # Required fields should not be pointers, and should not have `omitempty`.
99+
# - "ssatags" # Ensure array fields have the appropriate listType markers
100+
# - "statusoptional" # Ensure all first children within status should be optional.
101+
# - "statussubresource" # All root objects that have a `status` field should have a status subresource.
102+
- "uniquemarkers" # Ensure that types and fields do not contain more than a single definition of a marker that should only be present once.
103+
104+
# Linters below this line are disabled, pending conversation on how and when to enable them.
105+
disable:
106+
- "*" # We will manually enable new linters after understanding the impact. Disable all by default.
107+
lintersConfig:
108+
optionalfields:
109+
pointers:
110+
preference: WhenRequired # Always | WhenRequired # Whether to always require pointers, or only when required. Defaults to `Always`.
111+
jsontags:
112+
jsonTagRegex: "^[a-z][a-z0-9-]*(?:[A-Z][a-z0-9]*)*$" # The default regex is appropriate for our use case.
113+
optionalorrequired:
114+
preferredOptionalMarker: kubebuilder:validation:Optional # The preferred optional marker to use, fixes will suggest to use this marker. Defaults to `optional`.
115+
preferredRequiredMarker: kubebuilder:validation:Required # The preferred required marker to use, fixes will suggest to use this marker. Defaults to `required`.
77116
exclusions:
78-
generated: lax
117+
generated: strict
118+
paths:
119+
# Ignore generated files.
120+
- zz_generated.*\.go$
121+
# Ignore external API packages.
122+
- external/
123+
# Ignore test files.
124+
- '.+_test\.go$'
125+
# Ignore aggregate types.
126+
- 'aggregate_types\.go$'
79127
presets:
80128
- comments
81129
- common-false-positives
@@ -103,11 +151,36 @@ linters:
103151
- gocritic
104152
path: internal/test/envtest
105153
text: 'hugeParam: input is heavy'
106-
paths:
107-
- external
108-
- third_party$
109-
- builtin$
110-
- examples$
154+
155+
# START kube-api-linter rules
156+
- path: ".*"
157+
text: "optionalorrequired: embedded field must be marked as kubebuilder:validation:Optional or kubebuilder:validation:Required"
158+
linters:
159+
- kubeapilinter
160+
161+
# kube-api-linter does not handle formats correctly yet.
162+
- path: '/addon_types\.go$'
163+
text: "maxlength: field (Start|End) must have a maximum length, add kubebuilder:validation:MaxLength marker"
164+
linters:
165+
- kubeapilinter
166+
- path: '/common_types\.go$'
167+
text: "maxlength: field Address must have a maximum length, add kubebuilder:validation:MaxLength marker"
168+
linters:
169+
- kubeapilinter
170+
171+
# kube-api-linter does not handle patterns correctly yet.
172+
- path: '/aws_(clusterconfig|node)_types\.go$'
173+
text: "maxlength: field (ID|IAMInstanceProfile|InstanceType|Org) must have a maximum length, add kubebuilder:validation:MaxLength marker"
174+
linters:
175+
- kubeapilinter
176+
- path: '/(nutanix_)?(clusterconfig)_types\.go$'
177+
text: "maxlength: field (URL|Tag) must have a maximum length, add kubebuilder:validation:MaxLength marker"
178+
linters:
179+
- kubeapilinter
180+
- path-except: "^/api/"
181+
linters:
182+
- kubeapilinter
183+
# END kube-api-linter rules
111184
formatters:
112185
enable:
113186
- gci

.pre-commit-config.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,6 @@ repos:
2626
language: system
2727
files: "(.*\\.go|go.mod|go.sum|go.mk)$"
2828
pass_filenames: false
29-
- id: kube-api-linter
30-
name: kube-api-linter
31-
entry: make lint-kube-api
32-
language: system
33-
files: "((^api/(.*\\.go|go.mod|go.sum))|go.mk)$"
34-
pass_filenames: false
3529
- id: chart-docs
3630
name: chart-docs
3731
entry: make chart-docs

api/v1alpha1/addon_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ type StorageClassConfig struct {
284284

285285
// If the storage class should allow volume expanding
286286
// +kubebuilder:validation:Optional
287-
AllowExpansion bool `json:"allowExpansion,omitempty"` //nolint:kubeapilinter,lll // Leave as bool for backward compatibility and this comment makes it a long line.
287+
AllowExpansion bool `json:"allowExpansion,omitempty"`
288288
}
289289

290290
type CSICredentials struct {

api/v1alpha1/nutanix_clusterconfig_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type NutanixPrismCentralEndpointSpec struct {
3535

3636
// use insecure connection to Prism Central endpoint
3737
// +kubebuilder:validation:Optional
38-
Insecure bool `json:"insecure,omitempty"` //nolint:kubeapilinter // Leave as bool for backward compatibility.
38+
Insecure bool `json:"insecure,omitempty"`
3939

4040
// A base64 PEM encoded x509 cert for the RootCA that was used to create
4141
// the certificate for a Prism Central that uses certificates that were issued by a non-publicly trusted RootCA.

docs/content/contributing/linting.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
+++
2+
title = "Linting"
3+
icon = "fa-solid fa-magnifying-glass"
4+
+++
5+
6+
This project uses [`golangci-lint`][golangci-lint] to both lint and format the CAREN sourcecode. `golangci-lint` is
7+
installed via devbox, just as every other development tool that this project uses. The `golangci-lint` configuration
8+
includes a custom linter, [`kube-api-linter`][kube-api-linter], integrated as a `golangci-lint` [module plugin].
9+
10+
## Installing `golangci-lint` with KAL
11+
12+
To install the customized linter binary into `hack/tools/golangci-lint-kube-api-linter`, run:
13+
14+
```bash
15+
make hack/tools/golangci-lint-kube-api-linter
16+
```
17+
18+
## Integrating with vscode
19+
20+
One the customized linter has been installed above, `vscode` can be configured to run this linter. Add the followin
21+
configuration to `.vscode/settings.json`:
22+
23+
```json
24+
"go.lintTool": "golangci-lint",
25+
"go.lintFlags": ["--path-mode=abs"],
26+
"go.formatTool": "custom",
27+
"go.alternateTools": {
28+
"customFormatter": "golangci-lint",
29+
"golangci-lint": "${workspaceFolder}/hack/tools/golangci-lint-kube-api-linter"
30+
},
31+
"go.formatFlags": ["fmt", "--stdin"]
32+
```
33+
34+
[golangci-lint]: https://golangci-lint.run/
35+
[kube-api-linter]: https://github.com/kubernetes-sigs/kube-api-linter/
36+
[module plugin]: https://golangci-lint.run/plugins/module-plugins/

hack/tools/.custom-gcl.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright 2025 Nutanix. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
version: v2.2.1
4+
version: v2.2.2
55
name: golangci-lint-kube-api-linter
66
plugins:
77
- module: 'sigs.k8s.io/kube-api-linter'

make/go.mk

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,8 @@ endif
153153

154154
.PHONY: lint.%
155155
lint.%: ## Runs golangci-lint run for a specific module
156-
lint.%: fmt.% ; $(info $(M) linting $* module)
157-
$(if $(filter-out root,$*),cd $* && )golangci-lint run --fix --config=$(GOLANGCI_CONFIG_FILE)
158-
159-
.PHONY: lint-kube-api
160-
lint-kube-api: ## Runs kube-api-linter via custom golangci-lint configuration
161-
lint-kube-api: go-generate hack/tools/golangci-lint-kube-api-linter
162-
lint-kube-api: ; $(info $(M) running kube-api-linter)
163-
cd api && $(PWD)/hack/tools/golangci-lint-kube-api-linter run --config=$(PWD)/.golangci-kal.yml
156+
lint.%: hack/tools/golangci-lint-kube-api-linter fmt.% ; $(info $(M) linting $* module)
157+
$(if $(filter-out root,$*),cd $* && )$(PWD)/hack/tools/golangci-lint-kube-api-linter run --fix --config=$(GOLANGCI_CONFIG_FILE)
164158

165159
hack/tools/golangci-lint-kube-api-linter: hack/tools/.custom-gcl.yml
166160
hack/tools/golangci-lint-kube-api-linter: ; $(info $(M) installing golangci-lint-kube-api-linter tool)

pkg/handlers/generic/mutation/externalcloudprovider/inject.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99

10+
"github.com/blang/semver/v4"
1011
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1112
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1213
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
@@ -15,16 +16,13 @@ import (
1516
ctrl "sigs.k8s.io/controller-runtime"
1617
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
1718

18-
"github.com/blang/semver/v4"
1919
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation"
2020
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/patches"
2121
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/patches/selectors"
2222
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables"
2323
)
2424

25-
var (
26-
versionGreaterOrEqualTo133Range = semver.MustParseRange(">=1.33.0-0")
27-
)
25+
var versionGreaterOrEqualTo133Range = semver.MustParseRange(">=1.33.0-0")
2826

2927
type externalCloudProviderPatchHandler struct{}
3028

@@ -58,7 +56,8 @@ func (h *externalCloudProviderPatchHandler) Mutate(
5856
}
5957

6058
// This is a fatal error, we can't proceed without the control plane version.
61-
log.WithValues("variables", vars).Error(err, "failed to get control plane Kubernetes version from builtin variable")
59+
log.WithValues("variables", vars).
60+
Error(err, "failed to get control plane Kubernetes version from builtin variable")
6261
return fmt.Errorf("failed to get control plane Kubernetes version from builtin variable: %w", err)
6362
}
6463

@@ -87,7 +86,7 @@ func (h *externalCloudProviderPatchHandler) Mutate(
8786
if obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.APIServer.ExtraArgs == nil {
8887
obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.APIServer.ExtraArgs = make(map[string]string, 1)
8988
}
90-
if _, ok := obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.APIServer.ExtraArgs["cloud-provider"]; !ok {
89+
if _, ok := obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.APIServer.ExtraArgs["cloud-provider"]; !ok { //nolint:lll // Easier to read this way.
9190
obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration.APIServer.ExtraArgs["cloud-provider"] = "external"
9291
}
9392

0 commit comments

Comments
 (0)