Skip to content

Commit

Permalink
[istio] Updating registerIstioExternalAuthorizer
Browse files Browse the repository at this point in the history
* Reconciles also the Istio ConfigMap with the external authorizers
* If the IstioOperator CR returns an error, it continues reconciling CM
  • Loading branch information
didierofrivia committed May 24, 2023
1 parent 29fbaa9 commit d355268
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 46 deletions.
116 changes: 94 additions & 22 deletions controllers/kuadrant_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import (
"encoding/json"
"fmt"

"istio.io/istio/pkg/config/mesh"
"istio.io/istio/pkg/util/protomarshal"

corev1 "k8s.io/api/core/v1"

"github.com/go-logr/logr"
authorinov1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1"
maistrav1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1"
Expand Down Expand Up @@ -326,37 +331,43 @@ func (r *KuadrantReconciler) registerExternalAuthorizer(ctx context.Context, kOb

func (r *KuadrantReconciler) registerExternalAuthorizerIstio(ctx context.Context, kObj *kuadrantv1beta1.Kuadrant) error {
logger, _ := logr.FromContext(ctx)
iop := &iopv1alpha1.IstioOperator{}
var configsToUpdate []client.Object

iop := &iopv1alpha1.IstioOperator{}
iopKey := client.ObjectKey{Name: controlPlaneProviderName(), Namespace: controlPlaneProviderNamespace()}
if err := r.Client().Get(ctx, iopKey, iop); err != nil {
logger.V(1).Info("failed to get istiooperator object", "key", iopKey, "err", err)
return err
}

if iop.Spec == nil {
iop.Spec = &istioapiv1alpha1.IstioOperatorSpec{}
if apimeta.IsNoMatchError(err) {
// if it's a no match error (CRD not installed), return the error
// otherwise continue with the fetching of the configmap
return err
}
} else {
// if there is no error, add the iop to the list of configs to update
configsToUpdate = append(configsToUpdate, iop)
}

meshConfig, err := meshConfigFromStruct(iop.Spec.MeshConfig)
if err != nil {
istioConfigMap := &corev1.ConfigMap{}
if err := r.Client().Get(ctx, client.ObjectKey{Name: "istio", Namespace: controlPlaneProviderNamespace()}, istioConfigMap); err != nil {
logger.V(1).Info("failed to get istio configMap", "key", iopKey, "err", err)
return err
}
extensionProviders := extensionProvidersFromMeshConfig(meshConfig)
configsToUpdate = append(configsToUpdate, istioConfigMap)

if hasKuadrantAuthorizer(extensionProviders) {
return nil
}

meshConfig.ExtensionProviders = append(meshConfig.ExtensionProviders, createKuadrantAuthorizer(kObj.Namespace))
meshConfigStruct, err := meshConfigToStruct(meshConfig)
if err != nil {
return err
}
iop.Spec.MeshConfig = meshConfigStruct
logger.Info("adding external authorizer to meshconfig")
if err := r.Client().Update(ctx, iop); err != nil {
return err
for _, config := range configsToUpdate {
meshConfig, err := getMeshConfig(config)
if err != nil {
logger.V(1).Info("failed to get mesh config", "err", err)
return err
}
if needsUpdate, err := updateMeshConfig(config, meshConfig, kObj.Namespace); err != nil {
return err
} else if needsUpdate {
logger.Info("adding external authorizer to meshconfig")
if err := r.Client().Update(ctx, config); err != nil {
return err
}
}
}

return nil
Expand Down Expand Up @@ -639,6 +650,25 @@ func meshConfigFromStruct(structure *structpb.Struct) (*istiomeshv1alpha1.MeshCo
return meshConfig, nil
}

// meshConfigFromString returns the Istio MeshConfig from a ConfigMap
func meshConfigFromString(config string) (*istiomeshv1alpha1.MeshConfig, error) {
meshConfig := mesh.DefaultMeshConfig()
err := protomarshal.ApplyYAML(config, meshConfig)
if err != nil {
return nil, err
}
return meshConfig, nil
}

// meshConfigToString returns the Istio MeshConfig as a string
func meshConfigToString(config *istiomeshv1alpha1.MeshConfig) (string, error) {
configString, err := protomarshal.ToYAML(config)
if err != nil {
return "", err
}
return configString, nil
}

func meshConfigToStruct(config *istiomeshv1alpha1.MeshConfig) (*structpb.Struct, error) {
configJSON, err := protojson.Marshal(config)
if err != nil {
Expand All @@ -660,6 +690,48 @@ func extensionProvidersFromMeshConfig(config *istiomeshv1alpha1.MeshConfig) (ext
return
}

func updateMeshConfig(configObject client.Object, meshConfig *istiomeshv1alpha1.MeshConfig, kObjNamespace string) (bool, error) {
extProviders := extensionProvidersFromMeshConfig(meshConfig)
if !hasKuadrantAuthorizer(extProviders) {
meshConfig.ExtensionProviders = append(meshConfig.ExtensionProviders, createKuadrantAuthorizer(kObjNamespace))

switch config := configObject.(type) {
case *iopv1alpha1.IstioOperator:
meshConfigStruct, err := meshConfigToStruct(meshConfig)
if err != nil {
return false, err
}
config.Spec.MeshConfig = meshConfigStruct
return true, nil
case *corev1.ConfigMap:
var err error
config.Data["mesh"], err = meshConfigToString(meshConfig)
if err != nil {
return false, err
}
return true, nil
default:
return false, fmt.Errorf("unsupported configObject type: %T", config)
}
}

return false, nil
}

func getMeshConfig(configObject client.Object) (*istiomeshv1alpha1.MeshConfig, error) {
switch config := configObject.(type) {
case *iopv1alpha1.IstioOperator:
if config.Spec == nil {
config.Spec = &istioapiv1alpha1.IstioOperatorSpec{}
}
return meshConfigFromStruct(config.Spec.MeshConfig)
case *corev1.ConfigMap:
return meshConfigFromString(config.Data["mesh"])
default:
return nil, fmt.Errorf("unsupported configObject type: %T", config)
}
}

// SetupWithManager sets up the controller with the Manager.
func (r *KuadrantReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
Expand Down
28 changes: 28 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,38 +31,64 @@ require (
require (
cloud.google.com/go v0.102.1 // indirect
cloud.google.com/go/compute v1.10.0 // indirect
cloud.google.com/go/logging v1.4.2 // indirect
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cncf/xds/go v0.0.0-20220520190051-1e77728a1eaa // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/envoyproxy/go-control-plane v0.10.3-0.20220719090109-b024c36d9935 // indirect
github.com/envoyproxy/protoc-gen-validate v0.6.7 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-logr/zapr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/swag v0.21.1 // indirect
github.com/goccy/go-json v0.9.7 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/cel-go v0.12.6 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
github.com/googleapis/gax-go/v2 v2.4.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.0 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/iter v1.0.1 // indirect
github.com/lestrrat-go/jwx v1.2.25 // indirect
github.com/lestrrat-go/option v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/spf13/cobra v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect
golang.org/x/sys v0.3.0 // indirect
Expand All @@ -73,11 +99,13 @@ require (
google.golang.org/api v0.96.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006 // indirect
google.golang.org/grpc v1.49.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
istio.io/pkg v0.0.0-20220907025138-198870de7239 // indirect
k8s.io/component-base v0.26.1 // indirect
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect
Expand Down
Loading

0 comments on commit d355268

Please sign in to comment.