Skip to content

Commit

Permalink
feat: add upsert operation (#106)
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Helfand <helfand.4@gmail.com>
  • Loading branch information
danielhelfand authored Jul 21, 2023
1 parent 7325567 commit 447cf20
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 12 deletions.
12 changes: 6 additions & 6 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ Below you will find the step syntax next to the name of the method it utilizes.
- `<GK> [I] store [the] current time as <any-characters-except-(")>` kdt.KubeClientSet.SetTimestamp

### Unstructured Resources
- `<GK> [I] (create|submit|delete|update) [the] resource <non-whitespace-characters>` kdt.KubeClientSet.ResourceOperation
- `<GK> [I] (create|submit|delete|update) [the] resource <non-whitespace-characters> in [the] <any-characters-except-(")> namespace` kdt.KubeClientSet.ResourceOperationInNamespace
- `<GK> [I] (create|submit|delete|update) [the] resources in <non-whitespace-characters>` kdt.KubeClientSet.ResourcesOperation
- `<GK> [I] (create|submit|delete|update) [the] resources in <non-whitespace-characters> in [the] <any-characters-except-(")> namespace` kdt.KubeClientSet.ResourcesOperationInNamespace
- `<GK> [I] (create|submit|delete|update) [the] resource <non-whitespace-characters>, the operation should (succeed|fail)` kdt.KubeClientSet.ResourceOperationWithResult
- `<GK> [I] (create|submit|delete|update) [the] resource <non-whitespace-characters> in [the] <any-characters-except-(")> namespace, the operation should (succeed|fail)` kdt.KubeClientSet.ResourceOperationWithResultInNamespace
- `<GK> [I] (create|submit|delete|update|upsert) [the] resource <non-whitespace-characters>` kdt.KubeClientSet.ResourceOperation
- `<GK> [I] (create|submit|delete|update|upsert) [the] resource <non-whitespace-characters> in [the] <any-characters-except-(")> namespace` kdt.KubeClientSet.ResourceOperationInNamespace
- `<GK> [I] (create|submit|delete|update|upsert) [the] resources in <non-whitespace-characters>` kdt.KubeClientSet.ResourcesOperation
- `<GK> [I] (create|submit|delete|update|upsert) [the] resources in <non-whitespace-characters> in [the] <any-characters-except-(")> namespace` kdt.KubeClientSet.ResourcesOperationInNamespace
- `<GK> [I] (create|submit|delete|update|upsert) [the] resource <non-whitespace-characters>, the operation should (succeed|fail)` kdt.KubeClientSet.ResourceOperationWithResult
- `<GK> [I] (create|submit|delete|update|upsert) [the] resource <non-whitespace-characters> in [the] <any-characters-except-(")> namespace, the operation should (succeed|fail)` kdt.KubeClientSet.ResourceOperationWithResultInNamespace
- `<GK> [the] resource <any-characters-except-(")> should be (created|deleted)` kdt.KubeClientSet.ResourceShouldBe
- `<GK> [the] resource <any-characters-except-(")> [should] converge to selector <non-whitespace-characters>` kdt.KubeClientSet.ResourceShouldConvergeToSelector
- `<GK> [the] resource <any-characters-except-(")> condition <any-characters-except-(")> should be <any-characters-except-(")>` kdt.KubeClientSet.ResourceConditionShouldBe
Expand Down
12 changes: 6 additions & 6 deletions kubedog.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ func (kdt *Test) SetScenario(scenario *godog.ScenarioContext) {
kdt.scenario.Step(`^(?:the )?Kubernetes cluster should be (created|deleted|upgraded)$`, kdt.KubeClientSet.KubernetesClusterShouldBe)
kdt.scenario.Step(`^(?:I )?store (?:the )?current time as ([^"]*)$`, kdt.KubeClientSet.SetTimestamp)
//syntax-generation:title-1:Unstructured Resources
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update) (?:the )?resource (\S+)$`, kdt.KubeClientSet.ResourceOperation)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update) (?:the )?resource (\S+) in (?:the )?([^"]*) namespace$`, kdt.KubeClientSet.ResourceOperationInNamespace)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update) (?:the )?resources in (\S+)$`, kdt.KubeClientSet.ResourcesOperation)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update) (?:the )?resources in (\S+) in (?:the )?([^"]*) namespace$`, kdt.KubeClientSet.ResourcesOperationInNamespace)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update) (?:the )?resource (\S+), the operation should (succeed|fail)$`, kdt.KubeClientSet.ResourceOperationWithResult)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update) (?:the )?resource (\S+) in (?:the )?([^"]*) namespace, the operation should (succeed|fail)$`, kdt.KubeClientSet.ResourceOperationWithResultInNamespace)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update|upsert) (?:the )?resource (\S+)$`, kdt.KubeClientSet.ResourceOperation)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update|upsert) (?:the )?resource (\S+) in (?:the )?([^"]*) namespace$`, kdt.KubeClientSet.ResourceOperationInNamespace)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update|upsert) (?:the )?resources in (\S+)$`, kdt.KubeClientSet.ResourcesOperation)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update|upsert) (?:the )?resources in (\S+) in (?:the )?([^"]*) namespace$`, kdt.KubeClientSet.ResourcesOperationInNamespace)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update|upsert) (?:the )?resource (\S+), the operation should (succeed|fail)$`, kdt.KubeClientSet.ResourceOperationWithResult)
kdt.scenario.Step(`^(?:I )?(create|submit|delete|update|upsert) (?:the )?resource (\S+) in (?:the )?([^"]*) namespace, the operation should (succeed|fail)$`, kdt.KubeClientSet.ResourceOperationWithResultInNamespace)
kdt.scenario.Step(`^(?:the )?resource ([^"]*) should be (created|deleted)$`, kdt.KubeClientSet.ResourceShouldBe)
kdt.scenario.Step(`^(?:the )?resource ([^"]*) (?:should )?converge to selector (\S+)$`, kdt.KubeClientSet.ResourceShouldConvergeToSelector)
kdt.scenario.Step(`^(?:the )?resource ([^"]*) condition ([^"]*) should be ([^"]*)$`, kdt.KubeClientSet.ResourceConditionShouldBe)
Expand Down
1 change: 1 addition & 0 deletions pkg/kube/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
OperationSubmit = "submit"
OperationUpdate = "update"
OperationDelete = "delete"
OperationUpsert = "upsert"

StateCreated = "created"
StateDeleted = "deleted"
Expand Down
24 changes: 24 additions & 0 deletions pkg/kube/unstructured/unstructured.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,30 @@ func ResourceOperationInNamespace(dynamicClient dynamic.Interface, resource unst

unstruct.SetResourceVersion(currentResourceVersion.DeepCopy().GetResourceVersion())

_, err = dynamicClient.Resource(gvr.Resource).Namespace(namespace).Update(context.Background(), unstruct, metav1.UpdateOptions{})
if err != nil {
return err
}
log.Infof("%s %s has been updated in namespace %s", unstruct.GetKind(), unstruct.GetName(), namespace)
case common.OperationUpsert:
currentResourceVersion, err := dynamicClient.Resource(gvr.Resource).Namespace(namespace).Get(context.Background(), unstruct.GetName(), metav1.GetOptions{})
if err != nil {
if kerrors.IsNotFound(err) {
_, err = dynamicClient.Resource(gvr.Resource).Namespace(namespace).Create(context.Background(), unstruct, metav1.CreateOptions{})
if err != nil {
return err
}

log.Infof("%s %s has been created in namespace %s", unstruct.GetKind(), unstruct.GetName(), namespace)

return nil
} else {
return err
}
}

unstruct.SetResourceVersion(currentResourceVersion.DeepCopy().GetResourceVersion())

_, err = dynamicClient.Resource(gvr.Resource).Namespace(namespace).Update(context.Background(), unstruct, metav1.UpdateOptions{})
if err != nil {
return err
Expand Down
33 changes: 33 additions & 0 deletions pkg/kube/unstructured/unstructured_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,39 @@ func TestResourceOperationInNamespace(t *testing.T) {
}
}

func TestResourceOperationInNamespaceUpsertOperation(t *testing.T) {
dynScheme := runtime.NewScheme()
fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(dynScheme)

deploymentFromYaml, err := resourceFromYaml("../../test/templates/resource-without-namespace.yaml")
if err != nil {
t.Errorf(err.Error())
}

deploymentUnstructured := unstructuredResource{
GVR: &meta.RESTMapping{},
Resource: deploymentFromYaml,
}

if err := ResourceOperationInNamespace(fakeDynamicClient, deploymentUnstructured, "upsert", "test-namespace"); err != nil {
t.Errorf("ResourceOperationInNamespace() error = %v", err)
}

deploymentFromYamlUpdate, err := resourceFromYaml("../../test/templates/resource-without-namespace-update.yaml")
if err != nil {
t.Errorf(err.Error())
}

deploymentUnstructuredUpdate := unstructuredResource{
GVR: &meta.RESTMapping{},
Resource: deploymentFromYamlUpdate,
}

if err := ResourceOperationInNamespace(fakeDynamicClient, deploymentUnstructuredUpdate, "upsert", "test-namespace"); err != nil {
t.Errorf("ResourceOperationInNamespace() error = %v", err)
}
}

func resourcePath(resourceFileName string) string {
return filepath.Join("../../../test/templates", resourceFileName)
}
Expand Down

0 comments on commit 447cf20

Please sign in to comment.