Skip to content

Commit

Permalink
error out when configurations do not match (#418)
Browse files Browse the repository at this point in the history
Signed-off-by: Manabu McCloskey <[email protected]>
  • Loading branch information
nabuskey authored Oct 17, 2024
1 parent d966372 commit edaa249
Show file tree
Hide file tree
Showing 24 changed files with 206 additions and 53 deletions.
13 changes: 12 additions & 1 deletion api/v1alpha1/localbuild_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,19 @@ type PackageConfigsSpec struct {
CorePackageCustomization map[string]PackageCustomization `json:"packageCustomization,omitempty"`
}

// BuildCustomizationSpec fields cannot change once a cluster is created
type BuildCustomizationSpec struct {
Protocol string `json:"protocol,omitempty"`
Host string `json:"host,omitempty"`
IngressHost string `json:"ingressHost,omitempty"`
Port string `json:"port,omitempty"`
UsePathRouting bool `json:"usePathRouting,omitempty"`
SelfSignedCert string `json:"selfSignedCert,omitempty"`
}

type LocalbuildSpec struct {
PackageConfigs PackageConfigsSpec `json:"packageConfigs,omitempty"`
PackageConfigs PackageConfigsSpec `json:"packageConfigs,omitempty"`
BuildCustomization BuildCustomizationSpec `json:"buildCustomization,omitempty"`
}

// PackageCustomization defines how packages are customized
Expand Down
16 changes: 16 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.

57 changes: 54 additions & 3 deletions pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/cnoe-io/idpbuilder/globals"
"github.com/cnoe-io/idpbuilder/pkg/controllers"
"github.com/cnoe-io/idpbuilder/pkg/kind"
"github.com/cnoe-io/idpbuilder/pkg/util"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
Expand All @@ -28,7 +28,7 @@ var (

type Build struct {
name string
cfg util.CorePackageTemplateConfig
cfg v1alpha1.BuildCustomizationSpec
kindConfigPath string
kubeConfigPath string
kubeVersion string
Expand All @@ -43,7 +43,7 @@ type Build struct {

type NewBuildOptions struct {
Name string
TemplateData util.CorePackageTemplateConfig
TemplateData v1alpha1.BuildCustomizationSpec
KindConfigPath string
KubeConfigPath string
KubeVersion string
Expand Down Expand Up @@ -126,6 +126,36 @@ func (b *Build) RunControllers(ctx context.Context, mgr manager.Manager, exitCh
return controllers.RunControllers(ctx, mgr, exitCh, b.CancelFunc, b.exitOnSync, b.cfg, tmpDir)
}

func (b *Build) isCompatible(ctx context.Context, kubeClient client.Client) (bool, error) {
localBuild := v1alpha1.Localbuild{
ObjectMeta: metav1.ObjectMeta{
Name: b.name,
},
}

err := kubeClient.Get(ctx, client.ObjectKeyFromObject(&localBuild), &localBuild)
if err != nil {
if k8serrors.IsNotFound(err) {
return true, nil
}
return false, err
}

ok := isBuildCustomizationSpecEqual(b.cfg, localBuild.Spec.BuildCustomization)

if ok {
return ok, nil
}

existing, given := localBuild.Spec.BuildCustomization, b.cfg
existing.SelfSignedCert = ""
given.SelfSignedCert = ""

return false, fmt.Errorf("provided command flags and existing configurations are incompatible. please recreate the cluster. "+
"existing: %+v, given: %+v",
existing, given)
}

func (b *Build) Run(ctx context.Context, recreateCluster bool) error {
managerExit := make(chan error)

Expand Down Expand Up @@ -185,6 +215,16 @@ func (b *Build) Run(ctx context.Context, recreateCluster bool) error {
}
b.cfg.SelfSignedCert = string(cert)

setupLog.V(1).Info("Checking for incompatible options from a previous run")
ok, err := b.isCompatible(ctx, kubeClient)
if err != nil {
setupLog.Error(err, "Error while checking incompatible flags")
return err
}
if !ok {
return err
}

setupLog.V(1).Info("Running controllers")
if err := b.RunControllers(ctx, mgr, managerExit, dir); err != nil {
setupLog.Error(err, "Error running controllers")
Expand All @@ -206,6 +246,7 @@ func (b *Build) Run(ctx context.Context, recreateCluster bool) error {
}
localBuild.ObjectMeta.Annotations[v1alpha1.CliStartTimeAnnotation] = cliStartTime
localBuild.Spec = v1alpha1.LocalbuildSpec{
BuildCustomization: b.cfg,
PackageConfigs: v1alpha1.PackageConfigsSpec{
Argo: v1alpha1.ArgoPackageConfigSpec{
Enabled: true,
Expand All @@ -229,3 +270,13 @@ func (b *Build) Run(ctx context.Context, recreateCluster bool) error {
close(managerExit)
return err
}

func isBuildCustomizationSpecEqual(s1, s2 v1alpha1.BuildCustomizationSpec) bool {
// probably ok to use cmp.Equal but keeping it simple for now
return s1.Protocol == s2.Protocol &&
s1.Host == s2.Host &&
s1.IngressHost == s2.IngressHost &&
s1.Port == s2.Port &&
s1.UsePathRouting == s2.UsePathRouting &&
s1.SelfSignedCert == s2.SelfSignedCert
}
67 changes: 67 additions & 0 deletions pkg/build/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package build

import (
"context"
"testing"

"github.com/cnoe-io/idpbuilder/api/v1alpha1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func TestIsCompatible(t *testing.T) {
cfg := v1alpha1.BuildCustomizationSpec{
Protocol: "http",
Host: "cnoe.localtest.me",
IngressHost: "string",
Port: "8443",
UsePathRouting: false,
SelfSignedCert: "some-cert",
}

b := Build{
name: "test",
cfg: cfg,
}

ctx := context.Background()
fClient := new(fakeKubeClient)
fClient.On("Get", ctx, client.ObjectKey{Name: "test"}, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
arg := args.Get(2).(*v1alpha1.Localbuild)
arg.Spec.BuildCustomization = cfg
}).Return(nil)

ok, err := b.isCompatible(ctx, fClient)

assert.NoError(t, err)
fClient.AssertExpectations(t)
require.True(t, ok)

fClient = new(fakeKubeClient)
fClient.On("Get", ctx, client.ObjectKey{Name: "test"}, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
arg := args.Get(2).(*v1alpha1.Localbuild)
c := cfg
c.Host = "not-right"
arg.Spec.BuildCustomization = c
}).Return(nil)

ok, err = b.isCompatible(ctx, fClient)

assert.Error(t, err)
fClient.AssertExpectations(t)
require.False(t, ok)

fClient = new(fakeKubeClient)
fClient.On("Get", ctx, client.ObjectKey{Name: "test"}, mock.Anything, mock.Anything).
Return(k8serrors.NewNotFound(schema.GroupResource{}, "name"))

ok, err = b.isCompatible(ctx, fClient)

assert.NoError(t, err)
fClient.AssertExpectations(t)
require.True(t, ok)
}
4 changes: 2 additions & 2 deletions pkg/build/coredns.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"embed"
"fmt"

"github.com/cnoe-io/idpbuilder/api/v1alpha1"
"github.com/cnoe-io/idpbuilder/pkg/k8s"
"github.com/cnoe-io/idpbuilder/pkg/util"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -22,7 +22,7 @@ const (
//go:embed templates
var templates embed.FS

func setupCoreDNS(ctx context.Context, kubeClient client.Client, scheme *runtime.Scheme, templateData util.CorePackageTemplateConfig) error {
func setupCoreDNS(ctx context.Context, kubeClient client.Client, scheme *runtime.Scheme, templateData v1alpha1.BuildCustomizationSpec) error {
checkCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "coredns-conf-default",
Expand Down
4 changes: 2 additions & 2 deletions pkg/build/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (
"math/big"
"time"

"github.com/cnoe-io/idpbuilder/api/v1alpha1"
"github.com/cnoe-io/idpbuilder/globals"
"github.com/cnoe-io/idpbuilder/pkg/k8s"
"github.com/cnoe-io/idpbuilder/pkg/util"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -182,7 +182,7 @@ func createSelfSignedCertificate(sans []string) ([]byte, []byte, error) {
return certOut, privateKeyOut, nil
}

func setupSelfSignedCertificate(ctx context.Context, logger logr.Logger, kubeclient client.Client, config util.CorePackageTemplateConfig) ([]byte, error) {
func setupSelfSignedCertificate(ctx context.Context, logger logr.Logger, kubeclient client.Client, config v1alpha1.BuildCustomizationSpec) ([]byte, error) {
if err := k8s.EnsureNamespace(ctx, kubeclient, globals.NginxNamespace); err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/cmd/create/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/cnoe-io/idpbuilder/pkg/build"
"github.com/cnoe-io/idpbuilder/pkg/cmd/helpers"
"github.com/cnoe-io/idpbuilder/pkg/k8s"
"github.com/cnoe-io/idpbuilder/pkg/util"
"github.com/spf13/cobra"
"k8s.io/client-go/util/homedir"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -117,7 +116,7 @@ func create(cmd *cobra.Command, args []string) error {
KindConfigPath: kindConfigPath,
ExtraPortsMapping: extraPortsMapping,

TemplateData: util.CorePackageTemplateConfig{
TemplateData: v1alpha1.BuildCustomizationSpec{
Protocol: protocol,
Host: host,
IngressHost: ingressHost,
Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/custompackage/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Reconciler struct {
client.Client
Recorder record.EventRecorder
Scheme *runtime.Scheme
Config util.CorePackageTemplateConfig
Config v1alpha1.BuildCustomizationSpec
TempDir string
RepoMap *util.RepoMap
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/controllers/gitrepository/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ type RepositoryReconciler struct {
client.Client
Recorder record.EventRecorder
Scheme *runtime.Scheme
Config util.CorePackageTemplateConfig
Config v1alpha1.BuildCustomizationSpec
GitProviderFunc gitProviderFunc
TempDir string
RepoMap *util.RepoMap
}

type gitProviderFunc func(context.Context, *v1alpha1.GitRepository, client.Client, *runtime.Scheme, util.CorePackageTemplateConfig) (gitProvider, error)
type gitProviderFunc func(context.Context, *v1alpha1.GitRepository, client.Client, *runtime.Scheme, v1alpha1.BuildCustomizationSpec) (gitProvider, error)

type notFoundError struct{}

Expand All @@ -69,7 +69,7 @@ func getFallbackRepositoryURL(repo *v1alpha1.GitRepository, info repoInfo) strin
return fmt.Sprintf("%s/%s.git", repo.Spec.Provider.GitURL, info.fullName)
}

func GetGitProvider(ctx context.Context, repo *v1alpha1.GitRepository, kubeClient client.Client, scheme *runtime.Scheme, tmplConfig util.CorePackageTemplateConfig) (gitProvider, error) {
func GetGitProvider(ctx context.Context, repo *v1alpha1.GitRepository, kubeClient client.Client, scheme *runtime.Scheme, tmplConfig v1alpha1.BuildCustomizationSpec) (gitProvider, error) {
switch repo.Spec.Provider.Name {
case v1alpha1.GitProviderGitea:
giteaClient, err := NewGiteaClient(repo.Spec.Provider.GitURL, gitea.SetHTTPClient(util.GetHttpClient()))
Expand Down Expand Up @@ -227,7 +227,7 @@ func pushToRemote(ctx context.Context, remoteRepo *git.Repository, creds gitProv
}

// add files from local fs to target repository (gitea for now)
func reconcileLocalRepoContent(ctx context.Context, repo *v1alpha1.GitRepository, tgtRepo repoInfo, creds gitProviderCredentials, scheme *runtime.Scheme, tmplConfig util.CorePackageTemplateConfig, tmpDir string, repoMap *util.RepoMap) error {
func reconcileLocalRepoContent(ctx context.Context, repo *v1alpha1.GitRepository, tgtRepo repoInfo, creds gitProviderCredentials, scheme *runtime.Scheme, tmplConfig v1alpha1.BuildCustomizationSpec, tmpDir string, repoMap *util.RepoMap) error {
logger := log.FromContext(ctx)
tgtCloneDir := util.RepoDir(tgtRepo.cloneUrl, tmpDir)

Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/gitrepository/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type testCase struct {
expect expect
}

func (t testCase) giteaProvider(ctx context.Context, repo *v1alpha1.GitRepository, kubeClient client.Client, scheme *runtime.Scheme, tmplConfig util.CorePackageTemplateConfig) (gitProvider, error) {
func (t testCase) giteaProvider(ctx context.Context, repo *v1alpha1.GitRepository, kubeClient client.Client, scheme *runtime.Scheme, tmplConfig v1alpha1.BuildCustomizationSpec) (gitProvider, error) {
return &giteaProvider{
Client: kubeClient,
Scheme: scheme,
Expand Down
4 changes: 2 additions & 2 deletions pkg/controllers/gitrepository/gitea.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type giteaProvider struct {
client.Client
Scheme *runtime.Scheme
giteaClient GiteaClient
config util.CorePackageTemplateConfig
config v1alpha1.BuildCustomizationSpec
}

func (g *giteaProvider) createRepository(ctx context.Context, repo *v1alpha1.GitRepository) (repoInfo, error) {
Expand Down Expand Up @@ -116,7 +116,7 @@ func (g *giteaProvider) updateRepoContent(
}
}

func writeRepoContents(repo *v1alpha1.GitRepository, dstPath string, config util.CorePackageTemplateConfig, scheme *runtime.Scheme) error {
func writeRepoContents(repo *v1alpha1.GitRepository, dstPath string, config v1alpha1.BuildCustomizationSpec, scheme *runtime.Scheme) error {
if repo.Spec.Source.EmbeddedAppName != "" {
resources, err := localbuild.GetEmbeddedRawInstallResources(
repo.Spec.Source.EmbeddedAppName, config,
Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/gitrepository/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type gitHubProvider struct {
client.Client
Scheme *runtime.Scheme
gitHubClient gitHubClient
config util.CorePackageTemplateConfig
config v1alpha1.BuildCustomizationSpec
}

func (g *gitHubProvider) createRepository(ctx context.Context, repo *v1alpha1.GitRepository) (repoInfo, error) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/controllers/localbuild/argo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestGetRawInstallResources(t *testing.T) {
resourcePath: "resources/argo",
}
resources, err := util.ConvertFSToBytes(e.resourceFS, e.resourcePath,
util.CorePackageTemplateConfig{
v1alpha1.BuildCustomizationSpec{
Protocol: "",
Host: "",
Port: "",
Expand All @@ -70,7 +70,7 @@ func TestGetK8sInstallResources(t *testing.T) {
resourceFS: installArgoFS,
resourcePath: "resources/argo",
}
objs, err := e.installResources(k8s.GetScheme(), util.CorePackageTemplateConfig{
objs, err := e.installResources(k8s.GetScheme(), v1alpha1.BuildCustomizationSpec{
Protocol: "",
Host: "",
Port: "",
Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/localbuild/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type LocalbuildReconciler struct {
CancelFunc context.CancelFunc
ExitOnSync bool
shouldShutdown bool
Config util.CorePackageTemplateConfig
Config v1alpha1.BuildCustomizationSpec
TempDir string
RepoMap *util.RepoMap
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/controllers/localbuild/gitea.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,12 @@ func getGiteaToken(ctx context.Context, baseUrl, username, password string) (str
return token.Token, nil
}

func giteaBaseUrl(config util.CorePackageTemplateConfig) string {
func giteaBaseUrl(config v1alpha1.BuildCustomizationSpec) string {
return fmt.Sprintf(giteaIngressURL, config.Protocol, config.Port)
}

// gitea URL reachable within the cluster with proper coredns config. Mainly for argocd
func giteaInternalBaseUrl(config util.CorePackageTemplateConfig) string {
func giteaInternalBaseUrl(config v1alpha1.BuildCustomizationSpec) string {
if config.UsePathRouting {
return fmt.Sprintf(giteaSvcURL, config.Protocol, "", config.Host, config.Port, "/gitea")
}
Expand Down
Loading

0 comments on commit edaa249

Please sign in to comment.