Skip to content

Commit

Permalink
feat: iterate over common/base repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
Azhovan committed Oct 17, 2023
1 parent d7d7043 commit d0b9dba
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 15 deletions.
59 changes: 45 additions & 14 deletions apptests/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"time"

Expand All @@ -23,7 +24,9 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
genericCLient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)

const (
Expand All @@ -49,7 +52,7 @@ type Env struct {
func (e *Env) Provision(ctx context.Context) error {
var err error

kustomizePath, err := AbsolutePathToBase()
kustomizePath, err := absolutePathToBase()
if err != nil {
return err
}
Expand Down Expand Up @@ -155,11 +158,15 @@ func waitForFluxDeploymentsReady(ctx context.Context, typedClient *typedclient.C
isDeploymentReady := func(ctx context.Context, deployment appsv1.Deployment) wait.ConditionWithContextFunc {
return func(ctx context.Context) (done bool, err error) {
deploymentObj, err := typedClient.Clientset().AppsV1().
Deployments(kommanderFluxNamespace).
Deployments(deployment.Namespace).
Get(ctx, deployment.Name, metav1.GetOptions{})
if err != nil {
return false, err
}
if deploymentObj.Generation > deploymentObj.Status.ObservedGeneration {
return false, nil
}

return deploymentObj.Status.ReadyReplicas == deploymentObj.Status.Replicas, nil
}
}
Expand All @@ -184,6 +191,8 @@ func (e *Env) SetK8sClient(k8sClient *typedclient.Client) {

// ApplyKustomizations applies the kustomizations located in the given path.
func (e *Env) ApplyKustomizations(ctx context.Context, path string, substitutions map[string]string) error {
log.SetLogger(klog.NewKlogr())

if path == "" {
return fmt.Errorf("requirement argument: path is not specified")
}
Expand All @@ -199,25 +208,47 @@ func (e *Env) ApplyKustomizations(ctx context.Context, path string, substitution

buf := bytes.NewBuffer(out)
dec := yaml.NewYAMLOrJSONDecoder(buf, 1<<20) // default buffer size is 1MB
obj := unstructured.Unstructured{}
if err = dec.Decode(&obj); err != nil && err != io.EOF {
return fmt.Errorf("could not decode kustomization for path: %s :%w", path, err)
}

genericClient, err := genericCLient.New(e.K8sClient.Config(), genericCLient.Options{})
genericClient, err := genericCLient.New(e.K8sClient.Config(), genericCLient.Options{
Scheme: flux.NewScheme(),
})
if err != nil {
return fmt.Errorf("could not create the generic client for path: %s :%w", path, err)
}

err = genericClient.Patch(ctx, &obj, genericCLient.Apply, genericCLient.ForceOwnership, genericCLient.FieldOwner("k-cli"))
if err != nil {
return fmt.Errorf("could not patch the kustomization resources for path: %s :%w", path, err)
for {
var obj unstructured.Unstructured
err = dec.Decode(&obj)
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("could not decode kustomization for path: %s :%w", path, err)
}

err = genericClient.Patch(ctx, &obj, genericCLient.Apply, genericCLient.ForceOwnership, genericCLient.FieldOwner("k-cli"))
if err != nil {
return fmt.Errorf("could not patch the kustomization resources for path: %s :%w", path, err)
}
}

return nil
}

// AbsolutePathToBase returns the absolute path to common/base directory.
func AbsolutePathToBase() (string, error) {
return filepath.Abs("../../common/base")
// absolutePathToBase returns the absolute path to common/base directory from the given working directory.
func absolutePathToBase() (string, error) {
wd, err := os.Getwd()
if err != nil {
return "", err
}

// determining the execution path.
var base string
_, err = os.Stat(filepath.Join(wd, "common", "base"))
if os.IsNotExist(err) {
base = "../.."
} else {
base = ""
}

return filepath.Join(wd, base, "common", "base"), nil
}
68 changes: 68 additions & 0 deletions apptests/environment/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ package environment

import (
"context"
"fmt"
"testing"
"time"

"github.com/fluxcd/flux2/v2/pkg/manifestgen"
sourcev1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/mesosphere/kommander-applications/apptests/flux"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/wait"
genericCLient "sigs.k8s.io/controller-runtime/pkg/client"
)

func TestProvision(t *testing.T) {
Expand Down Expand Up @@ -41,5 +47,67 @@ func TestProvision(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, deploymentObj.Status.Replicas, deploymentObj.Status.ReadyReplicas)
}
}

func TestApplyKustomizations(t *testing.T) {
ctx := context.Background()
env := &Env{}

// set the kustomizePath to common/base directory
kustomizePath, err := absolutePathToBase()
assert.NoError(t, err)
fmt.Println(kustomizePath)

// create a kind cluster and install fluxcd on it
cluster, k8sClient, err := provisionEnv(ctx)
assert.NoError(t, err)
defer env.Destroy(ctx)

env.SetK8sClient(k8sClient)
env.SetCluster(cluster)

// apply common/base kustomizations
err = env.ApplyKustomizations(ctx, kustomizePath, nil)
assert.NoError(t, err)

// assert that following HelmRepository (as an example) is created
hr := &sourcev1beta2.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: "source.toolkit.fluxcd.io",
APIVersion: "v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "vmware-tanzu.github.io",
Namespace: kommanderFluxNamespace,
},
}

client, err := genericCLient.New(env.K8sClient.Config(), genericCLient.Options{Scheme: flux.NewScheme()})
assert.NoError(t, err)

// set timeout on the context
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel()

// assert that eventually helmRelease object is reconciled
err = wait.PollUntilContextCancel(ctx, pollInterval, true, func(ctx context.Context) (done bool, err error) {
err = client.Get(ctx, genericCLient.ObjectKeyFromObject(hr), hr)
if err != nil {
return false, err
}
for _, cond := range hr.Status.Conditions {
if cond.Status == metav1.ConditionTrue {
return true, nil
}
}
return false, nil
})
assert.NoError(t, err)
assert.NotNil(t, hr)
}

func TestAbsolutePathToBase(t *testing.T) {
pathToBase, err := absolutePathToBase()
assert.NoError(t, err)
assert.Contains(t, pathToBase, "kommander-applications/common/base")
}
2 changes: 1 addition & 1 deletion apptests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
k8s.io/apimachinery v0.28.2
k8s.io/cli-runtime v0.28.2
k8s.io/client-go v0.28.2
k8s.io/klog/v2 v2.100.1
sigs.k8s.io/cli-utils v0.35.0
sigs.k8s.io/controller-runtime v0.16.2
sigs.k8s.io/kind v0.20.0
Expand Down Expand Up @@ -107,7 +108,6 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.28.2 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20231009201959-f62364c3c354 // indirect
k8s.io/kubectl v0.28.2 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
Expand Down

0 comments on commit d0b9dba

Please sign in to comment.