...

Source file src/edge-infra.dev/pkg/edge/kustomization/kustomization.go

Documentation: edge-infra.dev/pkg/edge/kustomization

     1  package kustomization
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/thoas/go-funk"
     7  	"sigs.k8s.io/controller-runtime/pkg/client"
     8  
     9  	clusterApi "edge-infra.dev/pkg/edge/apis/cluster/v1alpha1"
    10  	"edge-infra.dev/pkg/edge/constants"
    11  	"edge-infra.dev/pkg/edge/constants/api/cluster"
    12  	"edge-infra.dev/pkg/edge/constants/api/fleet"
    13  	"edge-infra.dev/pkg/edge/flux/bootstrap"
    14  )
    15  
    16  const (
    17  	// ForemanBucketName default foreman bucket name.
    18  	ForemanBucketName = "bucket"
    19  	// BannerInfraBucketName default banner-infra bucket name.
    20  	BannerInfraBucketName = "banner-infra-sync"
    21  )
    22  
    23  var (
    24  	warehouseKustomizations = []*Kustomizations{
    25  		{
    26  			Name:               "shipments",
    27  			Namespace:          constants.FluxEdgeNamespace,
    28  			Path:               constants.ShipmentKustomizationDir,
    29  			Prune:              false,
    30  			Force:              false,
    31  			SupportedFleet:     fleet.Types,
    32  			SupportedCluster:   cluster.Types,
    33  			OverrideSyncSuffix: false,
    34  		},
    35  		{
    36  			Name:               "chariot",
    37  			Namespace:          constants.FluxEdgeNamespace,
    38  			Path:               "chariot",
    39  			Prune:              true,
    40  			Force:              true,
    41  			SupportedFleet:     fleet.Types,
    42  			SupportedCluster:   cluster.Types,
    43  			OverrideSyncSuffix: false,
    44  		},
    45  	}
    46  	defaultKustomizations = []*Kustomizations{
    47  		{
    48  			Name:               "chariot",
    49  			Namespace:          constants.FluxEdgeNamespace,
    50  			Path:               "chariot",
    51  			Prune:              true,
    52  			Force:              true,
    53  			SupportedFleet:     fleet.Types,
    54  			SupportedCluster:   cluster.Types,
    55  			OverrideSyncSuffix: false,
    56  		},
    57  		{
    58  			Name:               "cluster",
    59  			Namespace:          constants.FluxEdgeNamespace,
    60  			Path:               "hydrated/cluster",
    61  			Prune:              false,
    62  			Force:              true,
    63  			SupportedFleet:     fleet.Types,
    64  			SupportedCluster:   cluster.Types,
    65  			OverrideSyncSuffix: false,
    66  		},
    67  		{
    68  			Name:               "namespaces",
    69  			Namespace:          constants.FluxEdgeNamespace,
    70  			Path:               "hydrated/namespaces",
    71  			Prune:              false,
    72  			Force:              true,
    73  			SupportedFleet:     fleet.Types,
    74  			SupportedCluster:   cluster.Types,
    75  			OverrideSyncSuffix: false,
    76  		},
    77  		{
    78  			Name:               "cert-manager",
    79  			Namespace:          constants.FluxEdgeNamespace,
    80  			Path:               "hydrated/cert-manager",
    81  			Prune:              false,
    82  			Force:              true,
    83  			SupportedFleet:     fleet.Types,
    84  			SupportedCluster:   cluster.Types,
    85  			OverrideSyncSuffix: false,
    86  		},
    87  		{
    88  			Name:               "external-secrets",
    89  			Namespace:          constants.FluxEdgeNamespace,
    90  			Path:               "hydrated/external-secrets",
    91  			Prune:              false,
    92  			Force:              true,
    93  			SupportedFleet:     fleet.Types,
    94  			SupportedCluster:   cluster.Types,
    95  			OverrideSyncSuffix: false,
    96  		},
    97  		{
    98  			Name:               "gatekeeper-constraints",
    99  			Namespace:          constants.FluxEdgeNamespace,
   100  			Path:               "hydrated/gatekeeper-policies/constraints",
   101  			Prune:              false,
   102  			Force:              true,
   103  			SupportedFleet:     []fleet.Type{fleet.Store, fleet.BasicStore, fleet.CouchDB, fleet.Cluster},
   104  			SupportedCluster:   []cluster.Type{cluster.GKE},
   105  			OverrideSyncSuffix: false,
   106  		},
   107  		{
   108  			Name:               "gatekeeper-constraint-templates",
   109  			Namespace:          constants.FluxEdgeNamespace,
   110  			Path:               "hydrated/gatekeeper-policies/constraint-templates",
   111  			Prune:              false,
   112  			Force:              true,
   113  			SupportedFleet:     []fleet.Type{fleet.Store, fleet.BasicStore, fleet.CouchDB, fleet.Cluster},
   114  			SupportedCluster:   []cluster.Type{cluster.GKE},
   115  			OverrideSyncSuffix: false,
   116  		},
   117  		{
   118  			Name:               "gatekeeper-system",
   119  			Namespace:          constants.FluxEdgeNamespace,
   120  			Path:               "hydrated/gatekeeper-system",
   121  			Prune:              false,
   122  			Force:              true,
   123  			SupportedFleet:     []fleet.Type{fleet.Store, fleet.BasicStore, fleet.CouchDB, fleet.Cluster},
   124  			SupportedCluster:   []cluster.Type{cluster.GKE},
   125  			OverrideSyncSuffix: false,
   126  		},
   127  		{
   128  			Name:               "flux-system",
   129  			Namespace:          constants.FluxEdgeNamespace,
   130  			Path:               "hydrated/flux-system",
   131  			Prune:              false,
   132  			Force:              true,
   133  			SupportedFleet:     fleet.Types,
   134  			SupportedCluster:   cluster.Types,
   135  			OverrideSyncSuffix: false,
   136  		},
   137  		{
   138  			Name:               "redpanda",
   139  			Namespace:          constants.FluxEdgeNamespace,
   140  			Path:               "hydrated/redpanda",
   141  			Prune:              false,
   142  			Force:              true,
   143  			SupportedFleet:     []fleet.Type{fleet.Store},
   144  			SupportedCluster:   cluster.Types,
   145  			OverrideSyncSuffix: false,
   146  		},
   147  		{
   148  			Name:               "k8s-config-connector",
   149  			Namespace:          constants.FluxEdgeNamespace,
   150  			Path:               "hydrated/k8s-config-connector",
   151  			Prune:              false,
   152  			Force:              true,
   153  			SupportedFleet:     []fleet.Type{fleet.Cluster, fleet.Banner},
   154  			SupportedCluster:   cluster.Types,
   155  			OverrideSyncSuffix: false,
   156  		},
   157  		{
   158  			Name:               "banner-infra",
   159  			Namespace:          constants.FluxEdgeNamespace,
   160  			Path:               "hydrated/fluxcfg",
   161  			Prune:              false,
   162  			Force:              true,
   163  			SupportedFleet:     []fleet.Type{fleet.Banner},
   164  			SupportedCluster:   cluster.Types,
   165  			OverrideSyncSuffix: false,
   166  			OverridePath:       true,
   167  		},
   168  		{
   169  			Name:               "sds",
   170  			Namespace:          constants.FluxEdgeNamespace,
   171  			Path:               "hydrated/sds",
   172  			Prune:              true,
   173  			Force:              true,
   174  			SupportedFleet:     []fleet.Type{fleet.Store},
   175  			SupportedCluster:   []cluster.Type{cluster.DSDS},
   176  			OverrideSyncSuffix: false,
   177  		},
   178  	}
   179  )
   180  
   181  // EdgeKustomizations represents a group of kustomizations for a cluster from which kustomization manifests can be built.
   182  type EdgeKustomizations struct {
   183  	// Cluster the cluster for which the kustomizations are being generated for.
   184  	Cluster *clusterApi.Cluster
   185  	// BucketName the name of the bucket to which the kustomization will point to.
   186  	BucketName      string
   187  	BucketNamespace string
   188  	// Rules list of kustomization rules used to generate each kustomization.
   189  	Rules        []*Kustomizations
   190  	Annotations  map[string]string
   191  	StoreVersion string
   192  }
   193  
   194  // Kustomizations represents a singular kustomization from which a kustomization manifest can be built.
   195  type Kustomizations struct {
   196  	Name               string
   197  	Namespace          string
   198  	Path               string
   199  	Prune              bool
   200  	Force              bool
   201  	SupportedFleet     []fleet.Type
   202  	SupportedCluster   []cluster.Type
   203  	OverrideSyncSuffix bool
   204  	OverridePath       bool
   205  }
   206  
   207  // New returns new Edge Kustomizations.
   208  func New() *EdgeKustomizations {
   209  	return &EdgeKustomizations{
   210  		Annotations: make(map[string]string),
   211  	}
   212  }
   213  
   214  // SetCluster sets the cluster for the edge kustomizations.
   215  func (k *EdgeKustomizations) SetCluster(cluster *clusterApi.Cluster) *EdgeKustomizations {
   216  	k.Cluster = cluster
   217  	return k
   218  }
   219  
   220  // SetBucketName sets the bucket name for the edge kustomization.
   221  func (k *EdgeKustomizations) SetBucketName(name string) *EdgeKustomizations {
   222  	k.BucketName = name
   223  	return k
   224  }
   225  
   226  func (k *EdgeKustomizations) SetBucketNamespace(ns string) *EdgeKustomizations {
   227  	k.BucketNamespace = ns
   228  	return k
   229  }
   230  
   231  func (k *EdgeKustomizations) SetStoreVersion(version string) *EdgeKustomizations {
   232  	k.StoreVersion = version
   233  	return k
   234  }
   235  
   236  func (k *EdgeKustomizations) SetAnnotations(annotations map[string]string) *EdgeKustomizations {
   237  	k.Annotations = annotations
   238  	return k
   239  }
   240  
   241  // UseDefaultRules returns all the default kustomization rules.
   242  func (k *EdgeKustomizations) UseDefaultRules() *EdgeKustomizations {
   243  	k.Rules = defaultKustomizations
   244  	return k
   245  }
   246  
   247  // UseDefaultRules returns all the default kustomization rules.
   248  func (k *EdgeKustomizations) UseWarehouseRules() *EdgeKustomizations {
   249  	k.Rules = warehouseKustomizations
   250  	return k
   251  }
   252  
   253  // UseDefaultForemanRules filters the default kustomizations and returns kustomization rules for foreman clusters.
   254  func (k *EdgeKustomizations) UseDefaultForemanRules() *EdgeKustomizations {
   255  	foremanRules := funk.Filter(defaultKustomizations, isForemanRule)
   256  	k.Rules = foremanRules.([]*Kustomizations)
   257  	return k
   258  }
   259  
   260  // UseDefaultStoreRules filters the default kustomizations and returns kustomization rules for store clusters.
   261  func (k *EdgeKustomizations) UseDefaultStoreRules() *EdgeKustomizations {
   262  	storeRules := funk.Filter(defaultKustomizations, isStoreRule)
   263  	k.Rules = storeRules.([]*Kustomizations)
   264  	return k
   265  }
   266  
   267  // UseDefaultBannerInfraRules filters the default kustomizations and returns kustomization rules for banner-infra clusters.
   268  func (k *EdgeKustomizations) UseDefaultBannerInfraRules() *EdgeKustomizations {
   269  	storeRules := funk.Filter(defaultKustomizations, isBannerInfraRule)
   270  	k.Rules = storeRules.([]*Kustomizations)
   271  	return k
   272  }
   273  
   274  // RegisterNewRule registers a new kustomization rule that is different from the provided defaults.
   275  func (k *EdgeKustomizations) RegisterNewRule(name, namespace, path string, prune, force bool, supportedFleets []fleet.Type, supportedClusters []cluster.Type, overrideSuffix bool) *EdgeKustomizations {
   276  	k.Rules = append(k.Rules, &Kustomizations{
   277  		Name:               name,
   278  		Namespace:          namespace,
   279  		Path:               path,
   280  		Prune:              prune,
   281  		Force:              force,
   282  		SupportedFleet:     supportedFleets,
   283  		SupportedCluster:   supportedClusters,
   284  		OverrideSyncSuffix: overrideSuffix,
   285  	})
   286  	return k
   287  }
   288  
   289  // CreateBannerKustomization creates the customization for the banner
   290  func (k *EdgeKustomizations) CreateBannerKustomization() client.Object {
   291  	return bootstrap.KustomizeFluxConfig().
   292  		Name("banner-sync").
   293  		Namespace(k.BucketNamespace).
   294  		BucketName(k.BucketName).
   295  		Path("./chariot").
   296  		Force(true).
   297  		Prune(true).
   298  		ForStoreVersion(k.StoreVersion).
   299  		Annotations(k.Annotations).
   300  		BucketNamespace(k.BucketNamespace).
   301  		Build()
   302  }
   303  
   304  // CreateClusterKustomizations creates the kustomization manifests for the cluster.
   305  func (k *EdgeKustomizations) CreateClusterKustomizations() []client.Object {
   306  	kustomizations := make([]client.Object, 0)
   307  	clusterEdgeID := k.Cluster.Name
   308  	if k.BucketName == "" {
   309  		k.BucketName = fmt.Sprintf("%s-cluster-sync", clusterEdgeID)
   310  	}
   311  	for _, kusto := range k.Rules {
   312  		name := fmt.Sprintf("%s-sync", kusto.Name)
   313  		path := fmt.Sprintf("./%s/%s", clusterEdgeID, kusto.Path)
   314  		if kusto.OverrideSyncSuffix {
   315  			name = kusto.Name
   316  		}
   317  		if kusto.OverridePath {
   318  			path = fmt.Sprintf("./%s/%s/%s", clusterEdgeID, kusto.Path, clusterEdgeID)
   319  		}
   320  		if funk.Contains(kusto.SupportedFleet, k.Cluster.Spec.Fleet) && funk.Contains(kusto.SupportedCluster, k.Cluster.Spec.Type) {
   321  			k := bootstrap.KustomizeFluxConfig().
   322  				Name(name).
   323  				Namespace(kusto.Namespace).
   324  				BucketName(k.BucketName).
   325  				Path(path).
   326  				Force(kusto.Force).
   327  				Prune(kusto.Prune).
   328  				Annotations(k.Annotations).
   329  				ForStoreVersion(k.StoreVersion).
   330  				BucketNamespace(k.BucketNamespace).
   331  				Build()
   332  			kustomizations = append(kustomizations, k)
   333  		}
   334  	}
   335  	return kustomizations
   336  }
   337  
   338  // isForemanRule returns true if the cluster is a foreman cluster.
   339  func isForemanRule(k *Kustomizations) bool {
   340  	for _, fleetType := range k.SupportedFleet {
   341  		if fleetType == fleet.TopLevel {
   342  			return true
   343  		}
   344  	}
   345  	return false
   346  }
   347  
   348  // isBannerInfraRule returns true if the cluster is a banner-infra cluster.
   349  func isBannerInfraRule(k *Kustomizations) bool {
   350  	for _, fleetType := range k.SupportedFleet {
   351  		if fleetType == fleet.Banner {
   352  			return true
   353  		}
   354  	}
   355  	return false
   356  }
   357  
   358  // isStoreRule returns true if the cluster is a basic-store or store cluster.
   359  func isStoreRule(k *Kustomizations) bool {
   360  	for _, fleetType := range k.SupportedFleet {
   361  		if fleetType == fleet.BasicStore || fleetType == fleet.Store {
   362  			return true
   363  		}
   364  	}
   365  	return false
   366  }
   367  

View as plain text