Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement apply #2

Merged
merged 3 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export CDK_TOKEN=a
export CDK_BASE_URL=http://localhost:8080/api
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ on:
pull_request:
types: [opened, reopened, synchronize, labeled]
jobs:
test:
unit-test:
runs-on: cdk-large
steps:
- uses: actions/checkout@v3
Expand All @@ -11,4 +11,10 @@ jobs:
go-version: 1.22.0
- name: go test
run: go test ./...
integration-test:
runs-on: cdk-large
steps:
- uses: actions/checkout@v3
- name: run test
run: ./test_final_exec.sh

46 changes: 46 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package client

import (
"fmt"
"github.com/conduktor/ctl/resource"
"github.com/go-resty/resty/v2"
"os"
)

type Client struct {
token string
baseUrl string
client *resty.Client
}

func Make(token string, baseUrl string) Client {
return Client{
token: token,
baseUrl: baseUrl,
client: resty.New(),
}
}

func MakeFromEnv() Client {
token := os.Getenv("CDK_TOKEN")
if token == "" {
fmt.Fprintln(os.Stderr, "Please seat CDK_TOKEN")
strokyl marked this conversation as resolved.
Show resolved Hide resolved
os.Exit(1)
}
baseUrl := os.Getenv("CDK_BASE_URL")
if baseUrl == "" {
fmt.Fprintln(os.Stderr, "Please seat CDK_BASE_URL")
strokyl marked this conversation as resolved.
Show resolved Hide resolved
os.Exit(2)
}

return Make(token, baseUrl)
}

func (client *Client) Apply(resource *resource.Resource) error {
url := client.baseUrl + "/" + resource.Kind
resp, err := client.client.R().SetHeader("Authentication", "Bearer "+client.token).SetBody(resource.Json).Put(url)
if resp.IsError() {
return fmt.Errorf("Error applying resource %s/%s, got status code: %d:\n %s", resource.Kind, resource.Name, resp.StatusCode(), string(resp.Body()))
}
return err
}
75 changes: 75 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package client

import (
"github.com/conduktor/ctl/resource"
"github.com/jarcoal/httpmock"
"testing"
)

func TestApplyShouldWork(t *testing.T) {
baseUrl := "http://baseUrl/api"
token := "aToken"
client := Make(token, baseUrl)
httpmock.ActivateNonDefault(
client.client.GetClient(),
)
responder, err := httpmock.NewJsonResponder(200, "")
if err != nil {
panic(err)
}

topic := resource.Resource{
Json: []byte(`{"yolo": "data"}`),
Kind: "topic",
Name: "toto",
ApiVersion: "v1",
}

httpmock.RegisterMatcherResponderWithQuery(
"PUT",
"http://baseUrl/api/topic",
nil,
httpmock.HeaderIs("Authentication", "Bearer "+token).
And(httpmock.BodyContainsBytes(topic.Json)),
responder,
)

err = client.Apply(&topic)
if err != nil {
t.Error(err)
}
}

func TestApplyShouldFailIfNo2xx(t *testing.T) {
baseUrl := "http://baseUrl/api"
token := "aToken"
client := Make(token, baseUrl)
httpmock.ActivateNonDefault(
client.client.GetClient(),
)
responder, err := httpmock.NewJsonResponder(400, "")
if err != nil {
panic(err)
}

topic := resource.Resource{
Json: []byte(`{"yolo": "data"}`),
Kind: "topic",
Name: "toto",
ApiVersion: "v1",
}

httpmock.RegisterMatcherResponderWithQuery(
"PUT",
"http://baseUrl/api/topic",
nil,
httpmock.HeaderIs("Authentication", "Bearer "+token).
And(httpmock.BodyContainsBytes(topic.Json)),
responder,
)

err = client.Apply(&topic)
if err == nil {
t.Failed()
}
}
15 changes: 11 additions & 4 deletions cmd/apply.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"fmt"
"github.com/conduktor/ctl/client"
"github.com/conduktor/ctl/resource"
"github.com/spf13/cobra"
"os"
Expand All @@ -23,7 +21,16 @@ var applyCmd = &cobra.Command{
fmt.Fprintf(os.Stderr, "%s\n", error)
os.Exit(1)
}
fmt.Println(resources)
client := client.MakeFromEnv()
for _, resource := range resources {
err := client.Apply(&resource)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not apply resource %s/%s: %s\n", resource.Kind, resource.Name, err)
os.Exit(1)
} else {
fmt.Printf("%s/%s: ok\n", resource.Kind, resource.Name)
}
}
},
}

Expand Down
11 changes: 11 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:1.22
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -o /conduktor . && rm -rf /app
CMD ["/bin/conduktor"]

FROM scratch
COPY --from=0 /conduktor /bin/conduktor
ENTRYPOINT ["/bin/conduktor"]
17 changes: 17 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3'
services:
conduktor:
build:
dockerfile: docker/Dockerfile
context: ..
environment:
CDK_TOKEN: yo
CDK_BASE_URL: http://mock:1080/api
volumes:
- ./test_resource.yml:/test_resource.yml
mock:
image: mockserver/mockserver:latest
volumes:
- ./initializer.json:/config/initializer.json
environment:
MOCKSERVER_INITIALIZATION_JSON_PATH: /config/initializer.json
18 changes: 18 additions & 0 deletions docker/initializer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"httpRequest": {
"method": "Put",
"path": "/api/Topic",
"headers": {
"Authentication": "Bearer yo"
}
},
"httpResponse": {
"statusCode": 200,
"body": "{}",
"headers": {
"Content-Type": ["application/json"]
}
}
}
]
2 changes: 1 addition & 1 deletion test.yaml → docker/test_resource.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
apiVersion: v1
kind: Topic
metadata:
name: abc.myTopic
name: abcd.topic
spec:
replicationFactor: 1
partitions: 3
Expand Down
11 changes: 8 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ module github.com/conduktor/ctl

go 1.22.0

require github.com/spf13/cobra v1.8.0
require (
github.com/ghodss/yaml v1.0.0
github.com/go-resty/resty/v2 v2.11.0
github.com/spf13/cobra v1.8.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/ghodss/yaml v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jarcoal/httpmock v1.3.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.17.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
47 changes: 47 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,60 @@
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
Expand Down
20 changes: 20 additions & 0 deletions test_final_exec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash -eu

echoerr() { echo "$@" 1>&2; }

SCRIPTDIR=$(dirname "$0")

function cleanup {
docker compose -f "$SCRIPTDIR/docker/docker-compose.yml" down
}


trap cleanup EXIT
main() {
cd "$SCRIPTDIR"
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
}

main "$@"
Loading