Skip to content
62 changes: 62 additions & 0 deletions api/v1alpha1/apiexportpolicy_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package v1alpha1

import (
lifecycleapi "github.com/platform-mesh/golang-commons/controller/lifecycle/api"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type APIExportRef struct {
Name string `json:"name"`
ClusterPath string `json:"clusterPath"`
}

type APIExportPolicySpec struct {
APIExportRef APIExportRef `json:"apiExportRef"`

// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
AllowPathExpressions []string `json:"allowPathExpressions"`
}

type APIExportPolicyStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty"`
ManagedAllowExpressions []string `json:"managedAllowExpressions,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster

type APIExportPolicy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec APIExportPolicySpec `json:"spec,omitempty"`
Status APIExportPolicyStatus `json:"status,omitempty"`
}

// GetConditions implements lifecycle.RuntimeObjectConditions.
func (in *APIExportPolicy) GetConditions() []metav1.Condition {
return in.Status.Conditions
}

// SetConditions implements lifecycle.RuntimeObjectConditions.
func (in *APIExportPolicy) SetConditions(conditions []metav1.Condition) {
in.Status.Conditions = conditions
}

var _ lifecycleapi.RuntimeObjectConditions = &APIExportPolicy{}

// +kubebuilder:object:root=true

// APIExportPolicyList contains a list of APIExportPolicy.
type APIExportPolicyList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []APIExportPolicy `json:"items"`
}

func init() {
SchemeBuilder.Register(&APIExportPolicy{}, &APIExportPolicyList{})
}
122 changes: 122 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 103 additions & 0 deletions cmd/authorization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package cmd

import (
"context"
"crypto/tls"

openfgav1 "github.com/openfga/api/proto/openfga/v1"
platformeshcontext "github.com/platform-mesh/golang-commons/context"
"github.com/platform-mesh/security-operator/internal/controller"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"

"k8s.io/client-go/rest"

"github.com/kcp-dev/multicluster-provider/apiexport"
)

var apiExportPolicyCmd = &cobra.Command{
Use: "authorization",
Short: "Controllers for authorization.platform-mesh.io APIExport",
RunE: func(cmd *cobra.Command, args []string) error {
ctrl.SetLogger(log.ComponentLogger("controller-runtime").Logr())

ctx, _, shutdown := platformeshcontext.StartContext(log, defaultCfg, defaultCfg.ShutdownTimeout)
defer shutdown()

restCfg, err := getKubeconfigFromPath(authorizationCfg.KCP.Kubeconfig)
if err != nil {
log.Error().Err(err).Msg("unable to get KCP kubeconfig")
return err
}

opts := ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{
BindAddress: defaultCfg.Metrics.BindAddress,
TLSOpts: []func(*tls.Config){
func(c *tls.Config) {
c.NextProtos = []string{"http/1.1"}
},
},
},
HealthProbeBindAddress: defaultCfg.HealthProbeBindAddress,
LeaderElection: defaultCfg.LeaderElectionEnabled,
LeaderElectionID: "security-operator-authorization.platform-mesh.io",
BaseContext: func() context.Context { return ctx },
}

if defaultCfg.LeaderElectionEnabled {
inClusterCfg, err := rest.InClusterConfig()
if err != nil {
setupLog.Error(err, "unable to get in-cluster config for leader election")
return err
}
opts.LeaderElectionConfig = inClusterCfg
}

provider, err := apiexport.New(restCfg, authorizationCfg.AuthorizationAPIExportEndpointSliceName, apiexport.Options{
Scheme: scheme,
})
if err != nil {
setupLog.Error(err, "unable to create path-aware provider")
return err
}

mgr, err := mcmanager.New(restCfg, provider, opts)
if err != nil {
setupLog.Error(err, "unable to create apiexportpolicy manager")
return err
}

conn, err := grpc.NewClient(authorizationCfg.FGA.Target, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Error().Err(err).Msg("unable to create grpc client")
return err
}

fga := openfgav1.NewOpenFGAServiceClient(conn)

if err = controller.NewAPIExportPolicyReconciler(log, fga, mgr).SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "apiexportpolicy").Msg("unable to create controller")
return err
}

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
log.Error().Err(err).Msg("unable to set up health check")
return err
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
log.Error().Err(err).Msg("unable to set up ready check")
return err
}

setupLog.Info("starting authorization manager")

return mgr.Start(ctx)
},
}
2 changes: 1 addition & 1 deletion cmd/model_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ var modelGeneratorCmd = &cobra.Command{
return fmt.Errorf("scheme should not be nil")
}

provider, err := apiexport.New(restCfg, operatorCfg.APIExportEndpointSliceName, apiexport.Options{
provider, err := apiexport.New(restCfg, operatorCfg.CoreAPIExportEndpointSliceName, apiexport.Options{
Scheme: mgrOpts.Scheme,
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ var operatorCmd = &cobra.Command{
return fmt.Errorf("scheme should not be nil")
}

provider, err := apiexport.New(restCfg, operatorCfg.APIExportEndpointSliceName, apiexport.Options{
provider, err := apiexport.New(restCfg, operatorCfg.CoreAPIExportEndpointSliceName, apiexport.Options{
Scheme: mgrOpts.Scheme,
})
if err != nil {
Expand Down
18 changes: 11 additions & 7 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import (
)

var (
defaultCfg *platformeshconfig.CommonServiceConfig
initializerCfg config.Config
terminatorCfg config.Config
operatorCfg config.Config
generatorCfg config.Config
log *logger.Logger
setupLog logr.Logger
defaultCfg *platformeshconfig.CommonServiceConfig
initializerCfg config.Config
terminatorCfg config.Config
operatorCfg config.Config
generatorCfg config.Config
authorizationCfg config.Config
log *logger.Logger
setupLog logr.Logger
)

var rootCmd = &cobra.Command{
Expand All @@ -34,19 +35,22 @@ func init() {
rootCmd.AddCommand(operatorCmd)
rootCmd.AddCommand(modelGeneratorCmd)
rootCmd.AddCommand(initContainerCmd)
rootCmd.AddCommand(apiExportPolicyCmd)

defaultCfg = platformeshconfig.NewDefaultConfig()
operatorCfg = config.NewConfig()
generatorCfg = config.NewConfig()
initializerCfg = config.NewConfig()
terminatorCfg = config.NewConfig()
authorizationCfg = config.NewConfig()
initContainerCfg = config.NewInitContainerConfig()

defaultCfg.AddFlags(rootCmd.PersistentFlags())
operatorCfg.AddFlags(operatorCmd.Flags())
generatorCfg.AddFlags(modelGeneratorCmd.Flags())
initializerCfg.AddFlags(initializerCmd.Flags())
terminatorCfg.AddFlags(terminatorCmd.Flags())
authorizationCfg.AddFlags(apiExportPolicyCmd.Flags())
initContainerCfg.AddFlags(initContainerCmd.Flags())

cobra.OnInitialize(initLog)
Expand Down
Loading
Loading