Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation for OS when using registry mirror InsecureSkipVerify #5314

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions config/crd/bases/anywhere.eks.amazonaws.com_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,7 @@ spec:
insecureSkipVerify:
description: InsecureSkipVerify skips the registry certificate
verification. Only use this solution for isolated testing or
in a tightly controlled, air-gapped environment. Currently only
supported for snow provider
in a tightly controlled, air-gapped environment.
type: boolean
ociNamespaces:
description: OCINamespaces defines the mapping from an upstream
Expand Down
3 changes: 1 addition & 2 deletions config/manifest/eksa-components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3917,8 +3917,7 @@ spec:
insecureSkipVerify:
description: InsecureSkipVerify skips the registry certificate
verification. Only use this solution for isolated testing or
in a tightly controlled, air-gapped environment. Currently only
supported for snow provider
in a tightly controlled, air-gapped environment.
type: boolean
ociNamespaces:
description: OCINamespaces defines the mapping from an upstream
Expand Down
9 changes: 0 additions & 9 deletions pkg/api/v1alpha1/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,15 +723,6 @@ func validateMirrorConfig(clusterConfig *Cluster) error {
return fmt.Errorf("registry mirror port %s is invalid, please provide a valid port", clusterConfig.Spec.RegistryMirrorConfiguration.Port)
}

if clusterConfig.Spec.RegistryMirrorConfiguration.InsecureSkipVerify {
switch clusterConfig.Spec.DatacenterRef.Kind {
case DockerDatacenterKind, NutanixDatacenterKind, VSphereDatacenterKind, TinkerbellDatacenterKind, CloudStackDatacenterKind, SnowDatacenterKind:
break
default:
return fmt.Errorf("insecureSkipVerify is only supported for docker, nutanix, snow, tinkerbell, cloudstack and vsphere providers")
}
}

mirrorCount := 0
ociNamespaces := clusterConfig.Spec.RegistryMirrorConfiguration.OCINamespaces
for _, ociNamespace := range ociNamespaces {
Expand Down
16 changes: 0 additions & 16 deletions pkg/api/v1alpha1/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2571,22 +2571,6 @@ func TestValidateMirrorConfig(t *testing.T) {
},
},
},
{
name: "insecureSkipVerify on an unsupported provider",
wantErr: "insecureSkipVerify is only supported for docker, nutanix, snow, tinkerbell, cloudstack and vsphere providers",
cluster: &Cluster{
Spec: ClusterSpec{
RegistryMirrorConfiguration: &RegistryMirrorConfiguration{
Endpoint: "1.2.3.4",
Port: "443",
InsecureSkipVerify: true,
},
DatacenterRef: Ref{
Kind: "nonsnow",
},
},
},
},
{
name: "insecureSkipVerify on snow provider",
wantErr: "",
Expand Down
1 change: 0 additions & 1 deletion pkg/api/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ type RegistryMirrorConfiguration struct {

// InsecureSkipVerify skips the registry certificate verification.
// Only use this solution for isolated testing or in a tightly controlled, air-gapped environment.
// Currently only supported for snow provider
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
}

Expand Down
1 change: 0 additions & 1 deletion pkg/registrymirror/registrymirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ type RegistryMirror struct {
CACertContent string
// InsecureSkipVerify skips the registry certificate verification.
// Only use this solution for isolated testing or in a tightly controlled, air-gapped environment.
// Currently only supported for snow provider
InsecureSkipVerify bool
}

Expand Down
22 changes: 22 additions & 0 deletions pkg/validations/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,38 @@ package validations

import (
"context"
"errors"
"fmt"

"github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/cluster"
"github.com/aws/eks-anywhere/pkg/config"
"github.com/aws/eks-anywhere/pkg/features"
"github.com/aws/eks-anywhere/pkg/logger"
"github.com/aws/eks-anywhere/pkg/providers"
"github.com/aws/eks-anywhere/pkg/types"
)

// ValidateOSForRegistryMirror checks if the OS is valid for the provided registry mirror configuration.
func ValidateOSForRegistryMirror(clusterSpec *cluster.Spec, provider providers.Provider) error {
cluster := clusterSpec.Cluster
if cluster.Spec.RegistryMirrorConfiguration == nil {
return nil
}

machineConfigs := provider.MachineConfigs(clusterSpec)
if !cluster.Spec.RegistryMirrorConfiguration.InsecureSkipVerify || machineConfigs == nil {
return nil
}

for _, mc := range machineConfigs {
if mc.OSFamily() == v1alpha1.Bottlerocket {
return errors.New("InsecureSkipVerify is not supported for bottlerocket")
}
}
return nil
}

func ValidateCertForRegistryMirror(clusterSpec *cluster.Spec, tlsValidator TlsValidator) error {
cluster := clusterSpec.Cluster
if cluster.Spec.RegistryMirrorConfiguration == nil {
Expand Down
93 changes: 93 additions & 0 deletions pkg/validations/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/aws/eks-anywhere/pkg/cluster"
"github.com/aws/eks-anywhere/pkg/constants"
"github.com/aws/eks-anywhere/pkg/features"
"github.com/aws/eks-anywhere/pkg/providers"
providermocks "github.com/aws/eks-anywhere/pkg/providers/mocks"
"github.com/aws/eks-anywhere/pkg/types"
"github.com/aws/eks-anywhere/pkg/validations"
"github.com/aws/eks-anywhere/pkg/validations/mocks"
Expand All @@ -25,6 +27,7 @@ type clusterTest struct {
*WithT
tlsValidator *mocks.MockTlsValidator
kubectl *mocks.MockKubectlClient
provider *providermocks.MockProvider
clusterSpec *cluster.Spec
certContent string
host, port string
Expand All @@ -33,9 +36,11 @@ type clusterTest struct {
type clusterTestOpt func(t *testing.T, ct *clusterTest)

func newTest(t *testing.T, opts ...clusterTestOpt) *clusterTest {
ctrl := gomock.NewController(t)
cTest := &clusterTest{
WithT: NewWithT(t),
clusterSpec: test.NewClusterSpec(),
provider: providermocks.NewMockProvider(ctrl),
}
for _, opt := range opts {
opt(t, cTest)
Expand Down Expand Up @@ -153,6 +158,94 @@ func TestValidateAuthenticationForRegistryMirrorAuthValid(t *testing.T) {
tt.Expect(validations.ValidateAuthenticationForRegistryMirror(tt.clusterSpec)).To(Succeed())
}

func TestValidateOSForRegistryMirrorNoRegistryMirror(t *testing.T) {
tt := newTest(t, withTLS())
tt.clusterSpec.Cluster.Spec.RegistryMirrorConfiguration = nil
tt.Expect(validations.ValidateOSForRegistryMirror(tt.clusterSpec, tt.provider)).To(Succeed())
}

func TestValidateOSForRegistryMirrorInsecureSkipVerifyDisabled(t *testing.T) {
tt := newTest(t, withTLS())
tt.clusterSpec.Cluster.Spec.RegistryMirrorConfiguration.InsecureSkipVerify = false
tt.provider.EXPECT().MachineConfigs(tt.clusterSpec).Return([]providers.MachineConfig{})
tt.Expect(validations.ValidateOSForRegistryMirror(tt.clusterSpec, tt.provider)).To(Succeed())
}

func TestValidateOSForRegistryMirrorInsecureSkipVerifyEnabled(t *testing.T) {
tests := []struct {
name string
mirrorConfig *anywherev1.RegistryMirrorConfiguration
machineConfigs func() []providers.MachineConfig
wantErr string
}{
{
name: "insecureSkipVerify no machine configs",
machineConfigs: func() []providers.MachineConfig {
return nil
},
wantErr: "",
},
{
name: "insecureSkipVerify on provider with ubuntu",
machineConfigs: func() []providers.MachineConfig {
configs := make([]providers.MachineConfig, 0, 1)
configs = append(configs, &anywherev1.VSphereMachineConfig{
Spec: anywherev1.VSphereMachineConfigSpec{
OSFamily: anywherev1.Ubuntu,
},
})
return configs
},
wantErr: "",
},
{
name: "insecureSkipVerify on provider with bottlerocket",
machineConfigs: func() []providers.MachineConfig {
configs := make([]providers.MachineConfig, 0, 1)
configs = append(configs, &anywherev1.SnowMachineConfig{
Spec: anywherev1.SnowMachineConfigSpec{
OSFamily: anywherev1.Bottlerocket,
},
})
return configs
},
wantErr: "InsecureSkipVerify is not supported for bottlerocket",
},
{
name: "insecureSkipVerify on provider with redhat",
machineConfigs: func() []providers.MachineConfig {
configs := make([]providers.MachineConfig, 0, 1)
configs = append(configs, &anywherev1.VSphereMachineConfig{
Spec: anywherev1.VSphereMachineConfigSpec{
OSFamily: anywherev1.RedHat,
},
})
return configs
},
wantErr: "",
},
}

validationTest := newTest(t, func(t *testing.T, ct *clusterTest) {
ct.clusterSpec = test.NewClusterSpec(func(s *cluster.Spec) {
s.Cluster.Spec.RegistryMirrorConfiguration = &anywherev1.RegistryMirrorConfiguration{
InsecureSkipVerify: true,
}
})
})
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
validationTest.provider.EXPECT().MachineConfigs(validationTest.clusterSpec).Return(test.machineConfigs())
err := validations.ValidateOSForRegistryMirror(validationTest.clusterSpec, validationTest.provider)
if test.wantErr != "" {
validationTest.Expect(err).To(MatchError(test.wantErr))
} else {
validationTest.Expect(err).To(BeNil())
}
})
}
}

func TestValidateManagementClusterNameValid(t *testing.T) {
mgmtName := "test"
tt := newTest(t, withKubectl())
Expand Down
7 changes: 7 additions & 0 deletions pkg/validations/createvalidations/preflightvalidations.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ func (v *CreateValidations) PreflightValidations(ctx context.Context) []validati
}

createValidations := []validations.Validation{
func() *validations.ValidationResult {
return &validations.ValidationResult{
Name: "validate OS is compatible with registry mirror configuration",
Remediation: "please use a valid OS for your registry mirror configuration",
Err: validations.ValidateOSForRegistryMirror(v.Opts.Spec, v.Opts.Provider),
}
},
func() *validations.ValidationResult {
return &validations.ValidationResult{
Name: "validate certificate for registry mirror",
Expand Down
7 changes: 7 additions & 0 deletions pkg/validations/upgradevalidations/preflightvalidations.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ func (u *UpgradeValidations) PreflightValidations(ctx context.Context) []validat
KubeconfigFile: u.Opts.ManagementCluster.KubeconfigFile,
}
upgradeValidations := []validations.Validation{
func() *validations.ValidationResult {
return &validations.ValidationResult{
Name: "validate OS is compatible with registry mirror configuration",
Remediation: "please use a valid OS for your registry mirror configuration",
Err: validations.ValidateOSForRegistryMirror(u.Opts.Spec, u.Opts.Provider),
}
},
func() *validations.ValidationResult {
return &validations.ValidationResult{
Name: "validate certificate for registry mirror",
Expand Down