Skip to content

Commit

Permalink
Support delete -f (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
strokyl authored Jul 17, 2024
1 parent 3afb03a commit a5e552b
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 31 deletions.
24 changes: 24 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,30 @@ func (client *Client) Delete(kind *schema.Kind, parentPathValue []string, name s
return err
}

func (client *Client) DeleteResource(resource *resource.Resource) error {
client.setApiKeyFromEnvIfNeeded()
kinds := client.GetKinds()
kind, ok := kinds[resource.Kind]
if !ok {
return fmt.Errorf("kind %s not found", resource.Kind)
}
deletePath, err := kind.DeletePath(resource)
if err != nil {
return err
}
url := client.baseUrl + deletePath
resp, err := client.client.R().Delete(url)
if err != nil {
return err
} else if resp.IsError() {
return fmt.Errorf(extractApiError(resp))
} else {
fmt.Printf("%s/%s deleted\n", kind.GetName(), resource.Name)
}

return err
}

func (client *Client) GetOpenApi() ([]byte, error) {
url := client.baseUrl + "/public/docs/docs.yaml"
resp, err := client.client.R().Get(url)
Expand Down
38 changes: 38 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,44 @@ func TestDeleteShouldWork(t *testing.T) {
t.Error(err)
}
}

func TestDeleteResourceShouldWork(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
apiKey := "aToken"
client, err := Make(ApiParameter{
ApiKey: apiKey,
BaseUrl: baseUrl,
})
if err != nil {
panic(err)
}
httpmock.ActivateNonDefault(
client.client.GetClient(),
)
responder, err := httpmock.NewJsonResponder(200, "[]")
if err != nil {
panic(err)
}

httpmock.RegisterMatcherResponderWithQuery(
"DELETE",
"http://baseUrl/public/kafka/v2/cluster/local/topic/toto",
nil,
httpmock.HeaderIs("Authorization", "Bearer "+apiKey).
And(httpmock.HeaderIs("X-CDK-CLIENT", "CLI/unknown")),
responder,
)

resource, err := resource.FromYamlByte([]byte(`{"apiVersion":"v2","kind":"Topic","metadata":{"name":"toto","cluster":"local"},"spec":{}}`))
if err != nil {
t.Error(err)
}
err = client.DeleteResource(&resource[0])
if err != nil {
t.Error(err)
}
}
func TestDeleteShouldFailOnNot2XX(t *testing.T) {
defer httpmock.Reset()
baseUrl := "http://baseUrl"
Expand Down
17 changes: 4 additions & 13 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/spf13/cobra"
)

var filePath *[]string
var dryRun *bool

func resourceForPath(path string) ([]resource.Resource, error) {
Expand All @@ -27,22 +26,15 @@ func resourceForPath(path string) ([]resource.Resource, error) {

func initApply(kinds schema.KindCatalog) {
// applyCmd represents the apply command
var filePath *[]string
var applyCmd = &cobra.Command{
Use: "apply",
Short: "Upsert a resource on Conduktor",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
var resources = make([]resource.Resource, 0)
for _, path := range *filePath {
r, err := resourceForPath(path)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
resources = append(resources, r...)
}
var allSuccess = true
schema.SortResources(kinds, resources, *debug)
resources := loadResourceFromFileFlag(*filePath)
schema.SortResourcesForApply(kinds, resources, *debug)
allSuccess := true
for _, resource := range resources {
upsertResult, err := apiClient().Apply(&resource, *dryRun)
if err != nil {
Expand All @@ -60,7 +52,6 @@ func initApply(kinds schema.KindCatalog) {

rootCmd.AddCommand(applyCmd)

// Here you will define your flags and configuration settings.
filePath = applyCmd.
PersistentFlags().StringArrayP("file", "f", make([]string, 0, 0), "Specify the files to apply")

Expand Down
46 changes: 31 additions & 15 deletions cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,44 @@ package cmd

import (
"fmt"
"github.com/conduktor/ctl/schema"
"github.com/spf13/cobra"
"os"
"strings"
)

// applyCmd represents the apply command
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete resource of a given kind and name",
Long: ``,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
// Root command does nothing
cmd.Help()
os.Exit(1)
},
}
"github.com/conduktor/ctl/schema"
"github.com/spf13/cobra"
)

func initDelete(kinds schema.KindCatalog) {
var filePath *[]string
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete resource of a given kind and name",
Long: ``,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
// Root command does nothing
resources := loadResourceFromFileFlag(*filePath)
schema.SortResourcesForDelete(kinds, resources, *debug)
allSuccess := true
for _, resource := range resources {
err := apiClient().DeleteResource(&resource)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not delete resource %s/%s: %s\n", resource.Kind, resource.Name, err)
allSuccess = false
}
}
if !allSuccess {
os.Exit(1)
}
},
}

rootCmd.AddCommand(deleteCmd)

filePath = deleteCmd.Flags().StringArrayP("file", "f", make([]string, 0, 0), "the files to apply")

deleteCmd.MarkFlagRequired("file")

for name, kind := range kinds {
flags := kind.GetFlag()
parentFlagValue := make([]*string, len(flags))
Expand Down
21 changes: 21 additions & 0 deletions cmd/load_resource_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cmd

import (
"fmt"
"os"

"github.com/conduktor/ctl/resource"
)

func loadResourceFromFileFlag(filePath []string) []resource.Resource {
var resources = make([]resource.Resource, 0)
for _, path := range filePath {
r, err := resourceForPath(path)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
resources = append(resources, r...)
}
return resources
}
36 changes: 36 additions & 0 deletions docker/initializer.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,42 @@
}
}
},
{
"httpRequest": {
"method": "Delete",
"path": "/public/kafka/v2/cluster/my-cluster/topic/abcd.topic",
"headers": {
"Authorization": "Bearer yo"
}
},
"httpResponse": {
"statusCode": 200,
"body": "{}",
"headers": {
"Content-Type": [
"application/json"
]
}
}
},
{
"httpRequest": {
"method": "Delete",
"path": "/public/kafka/v2/cluster/my-cluster/topic/abcd.myTopicWrong",
"headers": {
"Authorization": "Bearer yo"
}
},
"httpResponse": {
"statusCode": 200,
"body": "{}",
"headers": {
"Content-Type": [
"application/json"
]
}
}
},
{
"httpRequest": {
"method": "Post",
Expand Down
9 changes: 9 additions & 0 deletions schema/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,12 @@ func (kind *Kind) ApplyPath(resource *resource.Resource) (string, error) {
}
return kind.ListPath(parentPathValues), nil
}

func (kind *Kind) DeletePath(resource *resource.Resource) (string, error) {
applyPath, err := kind.ApplyPath(resource)
if err != nil {
return "", err
}

return applyPath + "/" + resource.Name, nil
}
16 changes: 14 additions & 2 deletions schema/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,21 @@ func resourcePriority(catalog KindCatalog, resource resource.Resource, debug, fa
}
}

func SortResources(catalog KindCatalog, resources []resource.Resource, debug bool) {
func SortResourcesForApply(catalog KindCatalog, resources []resource.Resource, debug bool) {
sortResources(catalog, resources, debug, false)
}

func SortResourcesForDelete(catalog KindCatalog, resources []resource.Resource, debug bool) {
sortResources(catalog, resources, debug, true)
}

func sortResources(catalog KindCatalog, resources []resource.Resource, debug bool, reverse bool) {
sort.SliceStable(resources, func(i, j int) bool {
return resourcePriority(catalog, resources[i], debug, true) < resourcePriority(catalog, resources[j], debug, true)
if reverse {
return resourcePriority(catalog, resources[i], debug, true) > resourcePriority(catalog, resources[j], debug, true)
} else {
return resourcePriority(catalog, resources[i], debug, true) < resourcePriority(catalog, resources[j], debug, true)
}
})

}
2 changes: 1 addition & 1 deletion schema/sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestSortResources(t *testing.T) {
{Kind: "kind2", Version: "v1"},
}

SortResources(catalog, resources, false)
SortResourcesForApply(catalog, resources, false)

expected := []resource.Resource{
{Kind: "kind1", Version: "v1"},
Expand Down
3 changes: 3 additions & 0 deletions test_final_exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ main() {
docker compose -f docker/docker-compose.yml up -d mock
sleep 1
docker compose -f docker/docker-compose.yml run conduktor apply -f /test_resource.yml
docker compose -f docker/docker-compose.yml run conduktor apply -f /
docker compose -f docker/docker-compose.yml run conduktor delete -f /test_resource.yml
docker compose -f docker/docker-compose.yml run conduktor apply -f /
docker compose -f docker/docker-compose.yml run conduktor get Topic yolo --cluster=my-cluster
docker compose -f docker/docker-compose.yml run conduktor delete Topic yolo -v --cluster=my-cluster
docker compose -f docker/docker-compose.yml run -e CDK_USER=admin -e CDK_PASSWORD=secret conduktor login
Expand Down

0 comments on commit a5e552b

Please sign in to comment.