Skip to content
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
81 changes: 45 additions & 36 deletions cmd/deploy_flux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,79 @@ package cmd
import (
"fmt"

"github.com/openmcp-project/controller-utils/pkg/clusters"
"github.com/spf13/cobra"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"

cfg "github.com/openmcp-project/bootstrapper/internal/config"
"github.com/openmcp-project/bootstrapper/internal/flux_deployer"
logging "github.com/openmcp-project/bootstrapper/internal/log"
)

const (
flagOCMConfig = "ocm-config"
flagGitCredentials = "git-credentials"
flagKubeconfig = "kubeconfig"
flagFluxCDNamespace = "fluxcd-namespace"
"github.com/openmcp-project/bootstrapper/internal/util"
)

// deployFluxCmd represents the "deploy flux" command
var deployFluxCmd = &cobra.Command{
Use: "deploy-flux source target",
Short: "Transfer an OCM component from a source to a target location",
Long: `Transfers the specified OCM component version from the source location to the target location.`,
Args: cobra.ExactArgs(5),
Use: "deploy-flux",
Short: "Deploys Flux controllers on the platform cluster, and establishes synchronization with a Git repository",
Long: `Deploys Flux controllers on the platform cluster, and establishes synchronization with a Git repository.`,
Args: cobra.ExactArgs(1),
ArgAliases: []string{
"component-location",
"deployment-templates",
"deployment-repository",
"deployment-repository-branch",
"deployment-repository-path",
"configFile",
},
RunE: func(cmd *cobra.Command, args []string) error {
configFilePath := args[0]

log := logging.GetLogger()
log.Infof("Starting flux deployment with component-location: %s, deployment-templates: %s, "+
"deployment-repository: %s, deployment-repository-branch: %s, deployment-repository-path: %s",
args[0], args[1], args[2], args[3], args[4])
log.Infof("Starting deployment of Flux controllers with config file: %s.", configFilePath)

platformKubeconfig := cmd.Flag(flagKubeconfig).Value.String()
platformCluster := clusters.New("platform").WithConfigPath(platformKubeconfig)
// Configuration
config := &cfg.BootstrapperConfig{}
err := config.ReadFromFile(configFilePath)
if err != nil {
return fmt.Errorf("failed to read config file: %w", err)
}
config.SetDefaults()
err = config.Validate()
if err != nil {
return fmt.Errorf("invalid config file: %w", err)
}

// Platform cluster
scheme := runtime.NewScheme()
if err := v1.AddToScheme(scheme); err != nil {
return fmt.Errorf("error adding corev1 to scheme: %w", err)
}

platformCluster, err := util.GetCluster(cmd.Flag(FlagKubeConfig).Value.String(), "platform", scheme)
if err != nil {
return fmt.Errorf("failed to get platform cluster: %w", err)
}
if err := platformCluster.InitializeRESTConfig(); err != nil {
return fmt.Errorf("error initializing REST config for platform cluster: %w", err)
}
if err := platformCluster.InitializeClient(nil); err != nil {
return fmt.Errorf("error initializing client for platform cluster: %w", err)
}

d := flux_deployer.NewFluxDeployer(args[0], args[1], args[2], args[3], args[4],
cmd.Flag(flagOCMConfig).Value.String(),
cmd.Flag(flagGitCredentials).Value.String(),
cmd.Flag(flagFluxCDNamespace).Value.String(),
platformKubeconfig,
platformCluster, log)
err := d.Deploy(cmd.Context())
if err != nil {
log.Errorf("Flux deployment failed: %v", err)
d := flux_deployer.NewFluxDeployer(config, cmd.Flag(FlagGitConfig).Value.String(), cmd.Flag(FlagOcmConfig).Value.String(), platformCluster, log)
if err = d.Deploy(cmd.Context()); err != nil {
log.Errorf("Deployment of flux controllers failed: %v", err)
return err
}

log.Info("Flux deployment completed")
log.Info("Deployment of flux controllers completed")
return nil
},
}

func init() {
RootCmd.AddCommand(deployFluxCmd)
deployFluxCmd.Flags().SortFlags = false
deployFluxCmd.Flags().String(FlagOcmConfig, "", "OCM configuration file")
deployFluxCmd.Flags().String(FlagGitConfig, "", "Git credentials configuration file that configures basic auth or ssh private key. This will be used in the fluxcd GitSource for spec.secretRef to authenticate against the deploymentRepository. If not set, no authentication will be configured.")
deployFluxCmd.Flags().String(FlagKubeConfig, "", "Kubernetes configuration file")

deployFluxCmd.Flags().StringP(flagOCMConfig, "c", "", "ocm configuration file")
deployFluxCmd.Flags().StringP(flagGitCredentials, "g", "", "git credentials configuration file that configures basic auth, personal access token, ssh private key. This will be used in the fluxcd GitSource for spec.secretRef to authenticate against the deploymentRepository. If not set, no authentication will be configured.")
deployFluxCmd.Flags().StringP(flagKubeconfig, "k", "", "kubeconfig of the Kubernetes cluster on which the flux deployment will be created/updated. If not set, the current context will be used.")
deployFluxCmd.Flags().StringP(flagFluxCDNamespace, "n", "", "namespace on the Kubernetes cluster in which the namespaced fluxcd resources will be deployed. Default 'flux-system'.")
if err := deployFluxCmd.MarkFlagRequired(FlagGitConfig); err != nil {
panic(err)
}
}
50 changes: 50 additions & 0 deletions docs/technical/flux-deployer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Flux Deployer

The flux deployer creates a temporary working directory with subdirectories `download`, `templates`, and `repo`.

The final directory structure looks like this:

```shell
WORKDIR
├── download
│ ├── Chart.yaml
│ ├── templates
│ │ ├── overlays
│ │ │ ├── flux-kustomization.yaml
│ │ │ ├── gitrepo.yaml
│ │ │ └── kustomization.yaml
│ │ └── resources
│ │ ├── components.yaml
│ │ ├── flux-kustomization.yaml
│ │ ├── gitrepo.yaml
│ │ └── kustomization.yaml
│ └── values.yaml
├── templates
│ ├── envs
│ │ └── dev
│ │ └── fluxcd
│ │ ├── flux-kustomization.yaml
│ │ ├── gitrepo.yaml
│ │ └── kustomization.yaml
│ └── resources
│ └── fluxcd
│ ├── components.yaml
│ ├── flux-kustomization.yaml
│ ├── gitrepo.yaml
│ └── kustomization.yaml
└── repo # same structure as in WORKDIR/templates
├── envs
│ └── dev
│ └── fluxcd # entry point for the kustomization
│ ├── flux-kustomization.yaml
│ ├── gitrepo.yaml
│ └── kustomization.yaml
└── resources
└── fluxcd
├── components.yaml
├── flux-kustomization.yaml
├── gitrepo.yaml
└── kustomization.yaml
```
22 changes: 18 additions & 4 deletions internal/flux_deployer/constants.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
package flux_deployer

const (
// Names of ocm resources of the root component
// FluxSystemNamespace is the namespace on the platform cluster in which the flux controllers are deployed.
FluxSystemNamespace = "flux-system"

FluxcdHelmController = "fluxcd-helm-controller"
FluxcdKustomizeController = "fluxcd-kustomize-controller"
FluxcdSourceController = "fluxcd-source-controller"
// GitSecretName is the name of the secret in the flux system namespace that contains the git credentials for accessing the deployment repository.
// The secret is references in the GitRepository resource which establishes the synchronization with the deployment git repository.
GitSecretName = "git"

// Directory names
EnvsDirectoryName = "envs"
FluxCDDirectoryName = "fluxcd"
OpenMCPDirectoryName = "openmcp"
ResourcesDirectoryName = "resources"
TemplatesDirectoryName = "templates"
OverlaysDirectoryName = "overlays"

// Resource names
FluxCDSourceControllerResourceName = "fluxcd-source-controller"
FluxCDKustomizationControllerResourceName = "fluxcd-kustomize-controller"
FluxCDHelmControllerResourceName = "fluxcd-helm-controller"
)
Loading