Skip to content

Commit

Permalink
feat: use dyn client to create/patch resources instead of kubectl app…
Browse files Browse the repository at this point in the history
…ly (#10)
  • Loading branch information
minhthong582000 authored Jun 29, 2024
2 parents 4ef6db3 + 449f81d commit de5382d
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 21 deletions.
2 changes: 1 addition & 1 deletion gitops/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.1.0-alpha.11
v0.1.0-alpha.12
2 changes: 2 additions & 0 deletions gitops/example/nginx/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
label:
app: nginx
spec:
selector:
matchLabels:
Expand Down
2 changes: 2 additions & 0 deletions gitops/example/nginx/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
Expand Down
13 changes: 8 additions & 5 deletions gitops/internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,13 @@ func (c *Controller) createResources(ctx context.Context, app *v1alpha1.Applicat
return fmt.Errorf("error diffing resources: %s", err)
}
if diff {
// Apply manifests
err = c.k8sUtil.ApplyResources(path.Join(repoPath, app.Spec.Path))
if err != nil {
return fmt.Errorf("error applying resources: %s", err)
// Create resources
for _, r := range generatedResources {
// TODO: use namespace from application spec
err := c.k8sUtil.CreateResource(ctx, r, app.GetNamespace())
if err != nil {
return fmt.Errorf("error creating resources: %s", err)
}
}
} else {
log.WithField("application", app.Name).Info("No changes in resources")
Expand Down Expand Up @@ -299,7 +302,7 @@ func (c *Controller) deleteResources(app *v1alpha1.Application) error {
for _, r := range resources {
err := c.k8sUtil.DeleteResource(context.Background(), r, r.GetNamespace())
if err != nil {
log.Errorf("error deleting resources: %s", err)
return fmt.Errorf("error deleting resources: %s", err)
}
}

Expand Down
2 changes: 1 addition & 1 deletion gitops/internal/controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ spec:
mock.EXPECT().GetResourceWithLabel(gomock.Any()).Return(nil, nil)
mock.EXPECT().DiffResources(gomock.Any(), gomock.Any()).Return(true, nil)
mock.EXPECT().SetLabelsForResources(gomock.Any(), gomock.Any()).Return(nil)
mock.EXPECT().ApplyResources(gomock.Any()).Return(nil)
mock.EXPECT().CreateResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
return mock
}(),
expectedStatus: v1alpha1.HealthStatusCode(v1alpha1.HealthStatusHealthy),
Expand Down
61 changes: 53 additions & 8 deletions gitops/utils/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"reflect"
"strings"
Expand All @@ -16,14 +15,17 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
)

type K8s interface {
ApplyResources(path string) error
CreateResource(ctx context.Context, obj *unstructured.Unstructured, namespace string) error
PatchResource(ctx context.Context, currentObj *unstructured.Unstructured, namespace string) error
DeleteResource(ctx context.Context, currentObj *unstructured.Unstructured, namespace string) error
GenerateManifests(path string) ([]*unstructured.Unstructured, error)
GetResourceWithLabel(label map[string]string) ([]*unstructured.Unstructured, error)
Expand All @@ -43,13 +45,56 @@ func NewK8s(discoveryClient discovery.DiscoveryInterface, dynClientSet dynamic.I
}
}

func (k *k8s) ApplyResources(path string) error {
// Run kubeclt apply -f path
cmd := exec.Command("kubectl", "apply", "-Rf", path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
func (k *k8s) CreateResource(ctx context.Context, obj *unstructured.Unstructured, namespace string) error {
gvk := obj.GroupVersionKind()
apiResource, err := ServerResourceForGroupVersionKind(
k.discoveryClient,
gvk,
"create",
)
if err != nil {
return err
}

resource := gvk.GroupVersion().WithResource(apiResource.Name)

var dynInterface dynamic.ResourceInterface = k.dynClientSet.Resource(resource)
if apiResource.Namespaced {
dynInterface = k.dynClientSet.Resource(resource).Namespace(namespace)
}
_, err = dynInterface.Create(ctx, obj, metav1.CreateOptions{})
return err
}

func (k *k8s) PatchResource(ctx context.Context, currentObj *unstructured.Unstructured, namespace string) error {
gvk := currentObj.GroupVersionKind()
apiResource, err := ServerResourceForGroupVersionKind(
k.discoveryClient,
gvk,
"patch",
)
if err != nil {
return err
}

resource := gvk.GroupVersion().WithResource(apiResource.Name)

return cmd.Run()
var dynInterface dynamic.ResourceInterface = k.dynClientSet.Resource(resource)
if apiResource.Namespaced {
dynInterface = k.dynClientSet.Resource(resource).Namespace(namespace)
}
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, currentObj)
if err != nil {
return err
}
_, err = dynInterface.Patch(
ctx,
currentObj.GetName(),
types.ApplyPatchType,
outBytes,
metav1.PatchOptions{},
)
return err
}

func (k *k8s) DeleteResource(ctx context.Context, currentObj *unstructured.Unstructured, namespace string) error {
Expand Down
26 changes: 20 additions & 6 deletions gitops/utils/kube/mock/mock_kube.go

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

0 comments on commit de5382d

Please sign in to comment.