Skip to content

Commit

Permalink
k8s: bump golangci-lint to latest version
Browse files Browse the repository at this point in the history
There was a change for nolint directives:
golangci/golangci-lint#3109 (comment)

And we are adding confidence of 0.8 in revive to
avoid false positives.

(cherry picked from commit bf5401e)
  • Loading branch information
r-vasquez authored and joejulian committed Apr 12, 2023
1 parent ff86e39 commit 5c01043
Show file tree
Hide file tree
Showing 40 changed files with 484 additions and 105 deletions.
3 changes: 2 additions & 1 deletion src/go/k8s/.golangci.yml
Expand Up @@ -26,10 +26,11 @@ linters-settings:
misspell:
locale: US
nolintlint:
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
revive:
confidence: 0.8

linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
Expand Down
32 changes: 26 additions & 6 deletions src/go/k8s/apis/redpanda/v1alpha1/cluster_types.go
Expand Up @@ -50,11 +50,12 @@ type RedpandaResourceRequirements struct {
// * Is limited by 2Gi per core if requests.memory is set.
//
// Example:
// in: minimum requirement per core, 2GB
// in: Requests.Memory, 16GB
// => maxAllowedCores = 8
// if requestedCores == 8, set smp = 8 (with 2GB per core)
// if requestedCores == 4, set smp = 4 (with 4GB per core)
//
// in: minimum requirement per core, 2GB
// in: Requests.Memory, 16GB
// => maxAllowedCores = 8
// if requestedCores == 8, set smp = 8 (with 2GB per core)
// if requestedCores == 4, set smp = 4 (with 4GB per core)
func (r *RedpandaResourceRequirements) RedpandaCPU() *resource.Quantity {
q := r.Redpanda.Cpu()
if q == nil || q.IsZero() {
Expand Down Expand Up @@ -257,17 +258,33 @@ type StorageSpec struct {
// used as a external listener. This port is tight to the autogenerated
// host port. The collision between Kafka external, Kafka internal,
// Admin, Pandaproxy, Schema Registry and RPC port is checked in the webhook.
// An optional endpointTemplate can be used to configure advertised addresses
// for Kafka API and Pandaproxy, while it is disallowed for other listeners.
type ExternalConnectivityConfig struct {
// Enabled enables the external connectivity feature
Enabled bool `json:"enabled,omitempty"`
// Subdomain can be used to change the behavior of an advertised
// KafkaAPI. Each broker advertises Kafka API as follows
// BROKER_ID.SUBDOMAIN:EXTERNAL_KAFKA_API_PORT.
// ENDPOINT.SUBDOMAIN:EXTERNAL_KAFKA_API_PORT.
// If Subdomain is empty then each broker advertises Kafka
// API as PUBLIC_NODE_IP:EXTERNAL_KAFKA_API_PORT.
// If TLS is enabled then this subdomain will be requested
// as a subject alternative name.
Subdomain string `json:"subdomain,omitempty"`
// EndpointTemplate is a Golang template string that allows customizing each
// broker advertised address.
// Redpanda uses the format BROKER_ID.SUBDOMAIN:EXTERNAL_KAFKA_API_PORT by
// default for advertised addresses. When an EndpointTemplate is
// provided, then the BROKER_ID part is replaced with the endpoint
// computed from the template.
// The following variables are available to the template:
// - Index: the Redpanda broker progressive number
// - HostIP: the ip address of the Node, as reported in pod status
//
// Common template functions from Sprig (http://masterminds.github.io/sprig/)
// are also available. The set of available functions is limited to hermetic
// functions because template application needs to be deterministic.
EndpointTemplate string `json:"endpointTemplate,omitempty"`
// The preferred address type to be assigned to the external
// advertised addresses. The valid types are ExternalDNS,
// ExternalIP, InternalDNS, InternalIP, and Hostname.
Expand Down Expand Up @@ -908,12 +925,14 @@ type TLSConfig struct {
// Kafka API

// GetPort returns API port
//
//nolint:gocritic // TODO KafkaAPI is now 81 bytes, consider a pointer
func (k KafkaAPI) GetPort() int {
return k.Port
}

// GetTLS returns API TLSConfig
//
//nolint:gocritic // TODO KafkaAPI is now 81 bytes, consider a pointer
func (k KafkaAPI) GetTLS() *TLSConfig {
return &TLSConfig{
Expand All @@ -925,6 +944,7 @@ func (k KafkaAPI) GetTLS() *TLSConfig {
}

// GetExternal returns API's ExternalConnectivityConfig
//
//nolint:gocritic // TODO KafkaAPI is now 81 bytes, consider a pointer
func (k KafkaAPI) GetExternal() *ExternalConnectivityConfig {
return &k.External
Expand Down
2 changes: 1 addition & 1 deletion src/go/k8s/apis/redpanda/v1alpha1/cluster_types_test.go
Expand Up @@ -21,7 +21,7 @@ import (
"k8s.io/utils/pointer"
)

// nolint:funlen // this is ok for a test
//nolint:funlen // this is ok for a test
func TestRedpandaResourceRequirements(t *testing.T) {
type test struct {
name string
Expand Down
61 changes: 61 additions & 0 deletions src/go/k8s/apis/redpanda/v1alpha1/cluster_webhook.go
Expand Up @@ -15,6 +15,7 @@ import (
"strconv"

cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
"github.com/redpanda-data/redpanda/src/go/k8s/pkg/utils"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -277,6 +278,12 @@ func (r *Cluster) validateAdminListeners() field.ErrorList {
r.Spec.Configuration.AdminAPI,
"bootstrap loadbalancer not available for http admin api"))
}
if externalAdmin != nil && externalAdmin.External.EndpointTemplate != "" {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec").Child("configuration").Child("adminApi"),
r.Spec.Configuration.AdminAPI,
"cannot provide an endpoint template for admin listener"))
}

// for now only one listener can have TLS to be backward compatible with v1alpha1 API
foundListenerWithTLS := false
Expand Down Expand Up @@ -306,6 +313,7 @@ func (r *Cluster) validateKafkaListeners() field.ErrorList {
}

var external *KafkaAPI
var externalIdx int
for i, p := range r.Spec.Configuration.KafkaAPI {
if p.External.Enabled {
if external != nil {
Expand All @@ -315,6 +323,7 @@ func (r *Cluster) validateKafkaListeners() field.ErrorList {
"only one kafka api listener can be marked as external"))
}
external = &r.Spec.Configuration.KafkaAPI[i]
externalIdx = i
}
}

Expand Down Expand Up @@ -357,10 +366,36 @@ func (r *Cluster) validateKafkaListeners() field.ErrorList {
r.Spec.Configuration.KafkaAPI,
"bootstrap port cannot be empty"))
}
//nolint:dupl // not identical
if external != nil && external.External.EndpointTemplate != "" {
if external.External.Subdomain == "" {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec").Child("configuration").Child("kafkaApi").Index(externalIdx).Child("external"),
external.External,
"endpointTemplate can only be used in combination with subdomain"))
}

err := checkValidEndpointTemplate(external.External.EndpointTemplate)
if err != nil {
log.Error(err, "Invalid endpoint template received", "template", external.External.EndpointTemplate)
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec").Child("configuration").Child("kafkaApi").Index(externalIdx).Child("external").Child("endpointTemplate"),
external.External.EndpointTemplate,
fmt.Sprintf("template is invalid: %v", err)))
}
}

return allErrs
}

func checkValidEndpointTemplate(tmpl string) error {
// Using an example input to ensure that the template expression is allowed
data := utils.NewEndpointTemplateData(0, "1.2.3.4")
_, err := utils.ComputeEndpoint(tmpl, data)
return err
}

//nolint:funlen,gocyclo // it's a sequence of checks
func (r *Cluster) validatePandaproxyListeners() field.ErrorList {
var allErrs field.ErrorList
var proxyExternal *PandaproxyAPI
Expand Down Expand Up @@ -412,6 +447,25 @@ func (r *Cluster) validatePandaproxyListeners() field.ErrorList {
r.Spec.Configuration.PandaproxyAPI[i],
"sudomain of external pandaproxy must be the same as kafka's"))
}
//nolint:dupl // not identical
if kafkaExternal != nil && proxyExternal.External.EndpointTemplate != "" {
if proxyExternal.External.Subdomain == "" {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec").Child("configuration").Child("pandaproxyApi").Index(i).Child("external"),
proxyExternal.External,
"endpointTemplate can only be used in combination with subdomain"))
}

err := checkValidEndpointTemplate(proxyExternal.External.EndpointTemplate)
if err != nil {
log.Error(err, "Invalid endpoint template received", "template", proxyExternal.External.EndpointTemplate)
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec").Child("configuration").Child("pandaproxyApi").Index(i).
Child("external").Child("endpointTemplate"),
proxyExternal.External.EndpointTemplate,
fmt.Sprintf("template is invalid: %v", err)))
}
}
}

// for now only one listener can have TLS to be backward compatible with v1alpha1 API
Expand Down Expand Up @@ -510,6 +564,13 @@ func (r *Cluster) validateSchemaRegistryListener() field.ErrorList {
r.Spec.Configuration.SchemaRegistry.External,
"bootstrap loadbalancer not available for schema reigstry"))
}
if schemaRegistry.External.EndpointTemplate != "" {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec").Child("configuration").Child("schemaRegistry").Child("external").Child("endpointTemplate"),
r.Spec.Configuration.SchemaRegistry.External.EndpointTemplate,
"cannot provide an endpoint template for schema registry"))
}

return allErrs
}

Expand Down

0 comments on commit 5c01043

Please sign in to comment.