Skip to content

Commit

Permalink
Merge pull request #17 from kbst/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
pst authored Feb 23, 2020
2 parents 63f903f + d01243f commit ecd9ed2
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 104 deletions.
128 changes: 24 additions & 104 deletions resource_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@ import (

k8serrors "k8s.io/apimachinery/pkg/api/errors"
k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sunstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
k8sschema "k8s.io/apimachinery/pkg/runtime/schema"
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/restmapper"
)

func kustomizationResource() *schema.Resource {
Expand All @@ -42,37 +38,6 @@ func kustomizationResource() *schema.Resource {
}
}

func getGVR(gvk k8sschema.GroupVersionKind, cs *kubernetes.Clientset) (gvr k8sschema.GroupVersionResource, err error) {
agr, err := restmapper.GetAPIGroupResources(cs.Discovery())
if err != nil {
return gvr, fmt.Errorf("discovering API group resources failed: %s", err)
}

rm := restmapper.NewDiscoveryRESTMapper(agr)

gk := k8sschema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
mapping, err := rm.RESTMapping(gk, gvk.Version)
if err != nil {
return gvr, fmt.Errorf("mapping GroupKind failed for '%s': %s", gvk, err)
}

gvr = mapping.Resource

return gvr, nil
}

func parseJSON(json string) (ur *k8sunstructured.Unstructured, err error) {
body := []byte(json)
u, err := k8sruntime.Decode(k8sunstructured.UnstructuredJSONScheme, body)
if err != nil {
return ur, err
}

ur = u.(*k8sunstructured.Unstructured)

return ur, nil
}

func kustomizationResourceCreate(d *schema.ResourceData, m interface{}) error {
client := m.(*Config).Client
clientset := m.(*Config).Clientset
Expand Down Expand Up @@ -200,57 +165,33 @@ func kustomizationResourceDiff(d *schema.ResourceDiff, m interface{}) error {
client := m.(*Config).Client
clientset := m.(*Config).Clientset

originalJSON, modifiedJSON := d.GetChange("manifest")

if !d.HasChange("manifest") {
return nil
}

oldJSON, newJSON := d.GetChange("manifest")

if oldJSON.(string) == "" {
if originalJSON.(string) == "" {
return nil
}

n, err := parseJSON(newJSON.(string))
if err != nil {
return fmt.Errorf("ResourceDiff: %s", err)
}
o, err := parseJSON(oldJSON.(string))
if err != nil {
return fmt.Errorf("ResourceDiff: %s", err)
}

gvr, err := getGVR(o.GroupVersionKind(), clientset)
if err != nil {
return fmt.Errorf("ResourceDiff: %s", err)
}
namespace := o.GetNamespace()
name := o.GetName()

setLastAppliedConfig(o, oldJSON.(string))
setLastAppliedConfig(n, newJSON.(string))

original, err := o.MarshalJSON()
u, err := parseJSON(originalJSON.(string))
if err != nil {
return fmt.Errorf("ResourceDiff: %s", err)
}

modified, err := n.MarshalJSON()
gvr, err := getGVR(u.GroupVersionKind(), clientset)
if err != nil {
return fmt.Errorf("ResourceDiff: %s", err)
}
namespace := u.GetNamespace()
name := u.GetName()

c, err := client.
Resource(gvr).
Namespace(namespace).
Get(name, k8smetav1.GetOptions{})
if err != nil {
if k8serrors.IsNotFound(err) {
return nil
}
return fmt.Errorf("ResourceDiff: reading '%s' failed: %s", gvr, err)
}

current, err := c.MarshalJSON()
original, modified, current, err := getOriginalModifiedCurrent(
originalJSON.(string),
modifiedJSON.(string),
true,
m)
if err != nil {
return fmt.Errorf("ResourceDiff: %s", err)
}
Expand Down Expand Up @@ -325,54 +266,33 @@ func kustomizationResourceUpdate(d *schema.ResourceData, m interface{}) error {
client := m.(*Config).Client
clientset := m.(*Config).Clientset

oldJSON, newJSON := d.GetChange("manifest")
originalJSON, modifiedJSON := d.GetChange("manifest")

if !d.HasChange("manifest") {
msg := fmt.Sprintf(
"Update called without change. old: %s, new: %s",
oldJSON,
newJSON)
originalJSON,
modifiedJSON)
return errors.New(msg)
}

n, err := parseJSON(newJSON.(string))
if err != nil {
return fmt.Errorf("ResourceUpdate: %s", err)
}
o, err := parseJSON(oldJSON.(string))
u, err := parseJSON(originalJSON.(string))
if err != nil {
return fmt.Errorf("ResourceUpdate: %s", err)
}

gvr, err := getGVR(o.GroupVersionKind(), clientset)
if err != nil {
return fmt.Errorf("ResourceUpdate: %s", err)
}
namespace := o.GetNamespace()
name := o.GetName()

setLastAppliedConfig(o, oldJSON.(string))
setLastAppliedConfig(n, newJSON.(string))

original, err := o.MarshalJSON()
if err != nil {
return fmt.Errorf("ResourceUpdate: %s", err)
}

modified, err := n.MarshalJSON()
gvr, err := getGVR(u.GroupVersionKind(), clientset)
if err != nil {
return fmt.Errorf("ResourceUpdate: %s", err)
}
namespace := u.GetNamespace()
name := u.GetName()

c, err := client.
Resource(gvr).
Namespace(namespace).
Get(name, k8smetav1.GetOptions{})
if err != nil {
return fmt.Errorf("ResourceUpdate: reading '%s' failed: %s", gvr, err)
}

current, err := c.MarshalJSON()
original, modified, current, err := getOriginalModifiedCurrent(
originalJSON.(string),
modifiedJSON.(string),
false,
m)
if err != nil {
return fmt.Errorf("ResourceUpdate: %s", err)
}
Expand Down
90 changes: 90 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import (
"fmt"

k8scorev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sunstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
k8sschema "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/restmapper"

"k8s.io/apimachinery/pkg/util/jsonmergepatch"
"k8s.io/apimachinery/pkg/util/mergepatch"
Expand All @@ -25,6 +31,59 @@ func getLastAppliedConfig(u *k8sunstructured.Unstructured) string {
return u.GetAnnotations()[lastAppliedConfig]
}

func getOriginalModifiedCurrent(originalJSON string, modifiedJSON string, currentAllowNotFound bool, m interface{}) (original []byte, modified []byte, current []byte, err error) {
client := m.(*Config).Client
clientset := m.(*Config).Clientset

n, err := parseJSON(modifiedJSON)
if err != nil {
return nil, nil, nil, err
}
o, err := parseJSON(originalJSON)
if err != nil {
return nil, nil, nil, err
}

setLastAppliedConfig(o, originalJSON)
setLastAppliedConfig(n, modifiedJSON)

gvr, err := getGVR(o.GroupVersionKind(), clientset)
if err != nil {
return nil, nil, nil, err
}
namespace := o.GetNamespace()
name := o.GetName()

original, err = o.MarshalJSON()
if err != nil {
return nil, nil, nil, err
}

modified, err = n.MarshalJSON()
if err != nil {
return nil, nil, nil, err
}

c, err := client.
Resource(gvr).
Namespace(namespace).
Get(name, k8smetav1.GetOptions{})
if err != nil {
if k8serrors.IsNotFound(err) && currentAllowNotFound {
return original, modified, current, nil
}

return nil, nil, nil, fmt.Errorf("reading '%s' failed: %s", gvr, err)
}

current, err = c.MarshalJSON()
if err != nil {
return nil, nil, nil, err
}

return original, modified, current, nil
}

func getPatch(original []byte, modified []byte, current []byte) (patch []byte, err error) {
preconditions := []mergepatch.PreconditionFunc{
mergepatch.RequireKeyUnchanged("apiVersion"),
Expand All @@ -37,3 +96,34 @@ func getPatch(original []byte, modified []byte, current []byte) (patch []byte, e
}
return patch, nil
}

func getGVR(gvk k8sschema.GroupVersionKind, cs *kubernetes.Clientset) (gvr k8sschema.GroupVersionResource, err error) {
agr, err := restmapper.GetAPIGroupResources(cs.Discovery())
if err != nil {
return gvr, fmt.Errorf("discovering API group resources failed: %s", err)
}

rm := restmapper.NewDiscoveryRESTMapper(agr)

gk := k8sschema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
mapping, err := rm.RESTMapping(gk, gvk.Version)
if err != nil {
return gvr, fmt.Errorf("mapping GroupKind failed for '%s': %s", gvk, err)
}

gvr = mapping.Resource

return gvr, nil
}

func parseJSON(json string) (ur *k8sunstructured.Unstructured, err error) {
body := []byte(json)
u, err := k8sruntime.Decode(k8sunstructured.UnstructuredJSONScheme, body)
if err != nil {
return ur, err
}

ur = u.(*k8sunstructured.Unstructured)

return ur, nil
}
42 changes: 42 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"testing"
)

func TestLastAppliedConfig(t *testing.T) {
srcJSON := "{\"apiVersion\": \"v1\", \"kind\": \"Namespace\", \"metadata\": {\"name\": \"test-unit\"}}"
u, err := parseJSON(srcJSON)
if err != nil {
t.Errorf("Error: %s", err)
}
setLastAppliedConfig(u, srcJSON)

annotations := u.GetAnnotations()
count := len(annotations)
if count != 1 {
t.Errorf("TestLastAppliedConfig: incorect number of annotations, got: %d, want: %d.", count, 1)
}

lac := getLastAppliedConfig(u)
if lac != srcJSON {
t.Errorf("TestLastAppliedConfig: incorect annotation value, got: %s, want: %s.", srcJSON, lac)
}
}

func TestGetPatch(t *testing.T) {
srcJSON := "{\"apiVersion\": \"v1\", \"kind\": \"Namespace\", \"metadata\": {\"name\": \"test-unit\"}}"

o, _ := parseJSON(srcJSON)
m, _ := parseJSON(srcJSON)
c, _ := parseJSON(srcJSON)

original, _ := o.MarshalJSON()
modified, _ := m.MarshalJSON()
current, _ := c.MarshalJSON()

_, err := getPatch(original, modified, current)
if err != nil {
t.Errorf("TestGetPatch: %s", err)
}
}

0 comments on commit ecd9ed2

Please sign in to comment.