Skip to content

Commit eeaf1a2

Browse files
author
Paweł Bojanowski
authored
istio config validation + helm chart fix (#2722)
* disallowing vcluster.yaml combination with istio integration that can lead to undefined behavior * create cluster role when istio integration is enabled --------- Signed-off-by: Paweł Bojanowski <pawel.bojanowski@loft.sh>
1 parent a4aea35 commit eeaf1a2

4 files changed

Lines changed: 180 additions & 19 deletions

File tree

‎chart/templates/_rbac.tpl‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
(and .Values.integrations.metricsServer.enabled .Values.integrations.metricsServer.nodes)
4444
.Values.experimental.multiNamespaceMode.enabled
4545
.Values.sync.fromHost.configMaps.enabled
46-
.Values.sync.fromHost.secrets.enabled -}}
46+
.Values.sync.fromHost.secrets.enabled
47+
.Values.integrations.istio.enabled
48+
-}}
4749
{{- true -}}
4850
{{- end -}}
4951
{{- end -}}

‎chart/tests/clusterrole_test.yaml‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,3 +683,23 @@ tests:
683683
resourceNames: [ "my-secret", "my-secret-2" ]
684684
resources: [ "secrets" ]
685685
verbs: [ "get" ]
686+
- it: istio enabled
687+
set:
688+
integrations:
689+
istio:
690+
enabled: true
691+
release:
692+
name: my-release
693+
namespace: my-namespace
694+
asserts:
695+
- hasDocuments:
696+
count: 1
697+
- lengthEqual:
698+
path: rules
699+
count: 1
700+
- contains:
701+
path: rules
702+
content:
703+
apiGroups: [ "apiextensions.k8s.io" ]
704+
resources: [ "customresourcedefinitions" ]
705+
verbs: [ "get", "list", "watch" ]

‎pkg/config/validation.go‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ func ValidateConfigAndSetDefaults(vConfig *VirtualClusterConfig) error {
6565
return fmt.Errorf("embedded database is not supported with multiple replicas")
6666
}
6767

68+
// disallow listing istio CRDs in sync.toHost.customResources if istio integration is enabled
69+
if err := validateIstioEnabled(vConfig.Sync.ToHost.CustomResources, vConfig.Integrations.Istio); err != nil {
70+
return err
71+
}
72+
6873
// check if custom resources have correct scope
6974
for key, customResource := range vConfig.Sync.ToHost.CustomResources {
7075
if customResource.Scope != "" && customResource.Scope != config.ScopeNamespaced {
@@ -723,6 +728,33 @@ func validateExportKubeConfig(exportKubeConfig config.ExportKubeConfig) error {
723728
return nil
724729
}
725730

731+
func validateIstioEnabled(toHostCustomResources map[string]config.SyncToHostCustomResource, istioIntegration config.Istio) error {
732+
if !istioIntegration.Enabled {
733+
return nil
734+
}
735+
for crdName, crdConfig := range toHostCustomResources {
736+
if crdName == "destinationrules.networking.istio.io" && crdConfig.Enabled && istioIntegration.Sync.ToHost.DestinationRules.Enabled {
737+
return errors.New("" +
738+
"istio integration is enabled but istio custom resource (destinationrules.networking.istio.io) is also set in the sync.toHost.customResources. " +
739+
"This is not supported, please remove the entry from sync.toHost.customResources",
740+
)
741+
}
742+
if crdName == "gateways.networking.istio.io" && crdConfig.Enabled && istioIntegration.Sync.ToHost.Gateways.Enabled {
743+
return errors.New("" +
744+
"istio integration is enabled but istio custom resource (gateways.networking.istio.io) is also set in the sync.toHost.customResources. " +
745+
"This is not supported, please remove the entry from sync.toHost.customResources",
746+
)
747+
}
748+
if crdName == "virtualservices.networking.istio.io" && crdConfig.Enabled && istioIntegration.Sync.ToHost.VirtualServices.Enabled {
749+
return errors.New("" +
750+
"istio integration is enabled but istio custom resource (virtualservices.networking.istio.io) is also set in the sync.toHost.customResources. " +
751+
"This is not supported, please remove the entry from sync.toHost.customResources",
752+
)
753+
}
754+
}
755+
return nil
756+
}
757+
726758
var ProValidateConfig = func(_ *VirtualClusterConfig) error {
727759
return nil
728760
}

‎pkg/config/validation_test.go‎

Lines changed: 125 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -411,24 +411,6 @@ func TestValidateFromHostSyncMappings(t *testing.T) {
411411
}
412412

413413
func TestValidateFromHostSyncCustomResources(t *testing.T) {
414-
noErrExpected := func(t *testing.T, err error) {
415-
t.Helper()
416-
if err != nil {
417-
t.Fatalf("unexpected error: %v", err)
418-
}
419-
}
420-
expectErr := func(errMsg string) func(t *testing.T, err error) {
421-
return func(t *testing.T, err error) {
422-
t.Helper()
423-
if err == nil {
424-
t.Fatal("expected error, got nil")
425-
}
426-
if err.Error() != errMsg {
427-
t.Fatalf("unexpected error: %v", err)
428-
}
429-
}
430-
}
431-
432414
cases := []struct {
433415
name string
434416
customResourcesFromHostSync map[string]config.SyncFromHostCustomResource
@@ -757,3 +739,128 @@ func TestValidateAllSyncPatches(t *testing.T) {
757739
})
758740
}
759741
}
742+
743+
func TestValidateToHostSyncAndIstioIntegration(t *testing.T) {
744+
istioEnabled := config.Istio{
745+
EnableSwitch: config.EnableSwitch{Enabled: true},
746+
Sync: config.IstioSync{ToHost: config.IstioSyncToHost{
747+
DestinationRules: config.EnableSwitch{Enabled: true},
748+
Gateways: config.EnableSwitch{Enabled: true},
749+
VirtualServices: config.EnableSwitch{Enabled: true},
750+
}},
751+
}
752+
istioDisabled := config.Istio{
753+
EnableSwitch: config.EnableSwitch{Enabled: false},
754+
}
755+
756+
cases := []struct {
757+
name string
758+
customResourcesToHostSync map[string]config.SyncToHostCustomResource
759+
istioIntegration config.Istio
760+
checkErr func(t *testing.T, err error)
761+
}{
762+
{
763+
name: "valid config",
764+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
765+
"clusterissuers.cert-manager.io": {
766+
Enabled: true,
767+
Scope: config.ScopeCluster,
768+
},
769+
},
770+
istioIntegration: istioEnabled,
771+
checkErr: noErrExpected,
772+
},
773+
{
774+
name: "destination rule listed in sync.toHost.customResources",
775+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
776+
"destinationrules.networking.istio.io": {
777+
Enabled: true,
778+
Scope: config.ScopeNamespaced,
779+
},
780+
},
781+
istioIntegration: istioEnabled,
782+
checkErr: expectErr("istio integration is enabled but istio custom resource (destinationrules.networking.istio.io) is also set in the sync.toHost.customResources. This is not supported, please remove the entry from sync.toHost.customResources"),
783+
},
784+
{
785+
name: "destination rule listed in sync.toHost.customResources but istio disabled",
786+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
787+
"destinationrules.networking.istio.io": {
788+
Enabled: true,
789+
Scope: config.ScopeNamespaced,
790+
},
791+
},
792+
istioIntegration: istioDisabled,
793+
checkErr: noErrExpected,
794+
},
795+
{
796+
name: "gateways listed in sync.toHost.customResources",
797+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
798+
"gateways.networking.istio.io": {
799+
Enabled: true,
800+
Scope: config.ScopeNamespaced,
801+
},
802+
},
803+
istioIntegration: istioEnabled,
804+
checkErr: expectErr("istio integration is enabled but istio custom resource (gateways.networking.istio.io) is also set in the sync.toHost.customResources. This is not supported, please remove the entry from sync.toHost.customResources"),
805+
},
806+
{
807+
name: "gateways listed in sync.toHost.customResources but istio disabled",
808+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
809+
"gateways.networking.istio.io": {
810+
Enabled: true,
811+
Scope: config.ScopeNamespaced,
812+
},
813+
},
814+
istioIntegration: istioDisabled,
815+
checkErr: noErrExpected,
816+
},
817+
{
818+
name: "virtual services listed in sync.toHost.customResources",
819+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
820+
"virtualservices.networking.istio.io": {
821+
Enabled: true,
822+
Scope: config.ScopeNamespaced,
823+
},
824+
},
825+
istioIntegration: istioEnabled,
826+
checkErr: expectErr("istio integration is enabled but istio custom resource (virtualservices.networking.istio.io) is also set in the sync.toHost.customResources. This is not supported, please remove the entry from sync.toHost.customResources"),
827+
},
828+
{
829+
name: "virtual services listed in sync.toHost.customResources but istio disabled",
830+
customResourcesToHostSync: map[string]config.SyncToHostCustomResource{
831+
"virtualservices.networking.istio.io": {
832+
Enabled: true,
833+
Scope: config.ScopeNamespaced,
834+
},
835+
},
836+
istioIntegration: istioDisabled,
837+
checkErr: noErrExpected,
838+
},
839+
}
840+
841+
for _, tc := range cases {
842+
t.Run(tc.name, func(t *testing.T) {
843+
err := validateIstioEnabled(tc.customResourcesToHostSync, tc.istioIntegration)
844+
tc.checkErr(t, err)
845+
})
846+
}
847+
}
848+
849+
func expectErr(errMsg string) func(t *testing.T, err error) {
850+
return func(t *testing.T, err error) {
851+
t.Helper()
852+
if err == nil {
853+
t.Fatal("expected error, got nil")
854+
}
855+
if err.Error() != errMsg {
856+
t.Fatalf("unexpected error: %v", err)
857+
}
858+
}
859+
}
860+
861+
func noErrExpected(t *testing.T, err error) {
862+
t.Helper()
863+
if err != nil {
864+
t.Fatalf("unexpected error: %v", err)
865+
}
866+
}

0 commit comments

Comments
 (0)