diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ecf366e..ef5fe0a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,5 +1,5 @@ name: Test -on: push +on: [push,workflow_dispatch] jobs: build: runs-on: ubuntu-18.04 diff --git a/.gitignore b/.gitignore index fcb046b..7695a62 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ bin/* src coverage* +.idea diff --git a/Makefile b/Makefile index 5c57f2c..c9b9fc4 100644 --- a/Makefile +++ b/Makefile @@ -28,3 +28,14 @@ docker: --interactive --tty --entrypoint /bin/bash \ --volume $(CURDIR):/usr/src/app --workdir /usr/src/app \ golang:1.12 + +.PHONY: docker.rabbitmq +docker.rabbitmq: + docker run -p 15672:15672 -p 5672:5672 -p 4639:4639 --name rabbithole_rabbitmq -dit rabbitmq:3.8-management + sleep 10 + docker exec -ti rabbithole_rabbitmq /bin/bash -c "rabbitmqctl set_cluster_name rabbitmq@localhost" + docker exec -ti rabbithole_rabbitmq /bin/bash -c "rabbitmqctl add_vhost /" + docker exec -ti rabbithole_rabbitmq /bin/bash -c "rabbitmqctl set_permissions -p / guest \".*\" \".*\" \".*\"" + docker exec -ti rabbithole_rabbitmq /bin/bash -c "rabbitmqctl add_vhost rabbit/hole" + docker exec -ti rabbithole_rabbitmq /bin/bash -c "rabbitmqctl set_permissions -p rabbit/hole guest \".*\" \".*\" \".*\"" + docker exec -ti rabbithole_rabbitmq /bin/bash -c "rabbitmq-plugins enable rabbitmq_federation rabbitmq_federation_management rabbitmq_shovel rabbitmq_shovel_management" diff --git a/definitions.go b/definitions.go index c71bd95..f4199af 100644 --- a/definitions.go +++ b/definitions.go @@ -1,6 +1,10 @@ package rabbithole -import "net/url" +import ( + "encoding/json" + "net/http" + "net/url" +) // ExportedDefinitions represents definitions exported from a RabbitMQ cluster type ExportedDefinitions struct { @@ -55,3 +59,24 @@ func (c *Client) ListVhostDefinitions(vhost string) (p *ExportedDefinitions, err return p, nil } + +// +// POST /api/definitions +// + +// UploadDefinitions uploads a set of definitions and returns an error indicating if the operation was a failure +func (c *Client) UploadDefinitions(p *ExportedDefinitions) (res *http.Response, err error) { + body, err := json.Marshal(p) + if err != nil { + return nil, err + } + req, err := newRequestWithBody(c, http.MethodPost, "definitions", body) + if err != nil { + return nil, err + } + + if res, err = executeRequest(c, req); err != nil { + return nil, err + } + return res, nil +} diff --git a/global_parameters.go b/global_parameters.go index 0074930..025f17c 100644 --- a/global_parameters.go +++ b/global_parameters.go @@ -14,7 +14,6 @@ type GlobalRuntimeParameter struct { Value interface{} `json:"value"` } - // // GET /api/global-parameters // @@ -58,8 +57,8 @@ func (c *Client) GetGlobalParameter(name string) (p *GlobalRuntimeParameter, err // PutRuntimeParameter creates or updates a runtime parameter. func (c *Client) PutGlobalParameter(name string, value interface{}) (res *http.Response, err error) { p := GlobalRuntimeParameter{ - Name: name, - Value: value, + Name: name, + Value: value, } body, err := json.Marshal(p) @@ -96,4 +95,3 @@ func (c *Client) DeleteGlobalParameter(name string) (res *http.Response, err err return res, nil } - diff --git a/go.mod b/go.mod index 246309d..22a9978 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ require ( github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.16.0 github.com/streadway/amqp v1.0.0 + golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/sys v0.0.0-20211031064116-611d5d643895 // indirect - golang.org/x/tools v0.1.7 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index d7657ec..e1adf89 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -46,25 +44,21 @@ github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1Sd github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -75,10 +69,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211031064116-611d5d643895 h1:iaNpwpnrgL5jzWS0vCNnfa8HqzxveCFpFx3uC/X4Tps= golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -89,8 +81,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/rabbithole_test.go b/rabbithole_test.go index 998c7f2..0e86a89 100644 --- a/rabbithole_test.go +++ b/rabbithole_test.go @@ -75,7 +75,7 @@ func listConnectionsUntil(c *Client, i int) { } func awaitEventPropagation() { - time.Sleep(1150 * time.Millisecond) + time.Sleep(5000 * time.Millisecond) } type portTestStruct struct { @@ -3265,4 +3265,49 @@ var _ = Describe("RabbitMQ HTTP API client", func() { }) }) }) + Context("POST /api/definitions", func() { + queueName, exchangeName := "definitions_test_queue", "definitions_test_exchange" + bi := BindingInfo{ + Source: exchangeName, + Vhost: "/", + DestinationType: "queue", + Destination: queueName, + Arguments: map[string]interface{}{}, + } + It("should create queues and exchanges as specified in the definitions", func() { + defsToUpload := &ExportedDefinitions{ + Policies: &[]PolicyDefinition{}, + Queues: &[]QueueInfo{{ + Name: queueName, + Vhost: "/", + Durable: true, + Arguments: map[string]interface{}{}, + }}, + Exchanges: &[]ExchangeInfo{{ + Name: exchangeName, + Vhost: "/", + Durable: true, + Type: "direct", + Arguments: map[string]interface{}{}, + }}, + Bindings: &[]BindingInfo{bi}, + } + _, err := rmqc.UploadDefinitions(defsToUpload) + Expect(err).Should(BeNil()) + + defs, err := rmqc.ListDefinitions() + Expect(err).Should(BeNil()) + + queueDefs := defs.Queues + exchangeDefs := defs.Exchanges + bindingDefs := defs.Bindings + Expect(queueDefs).Should(BeEquivalentTo(defsToUpload.Queues)) + Expect(exchangeDefs).Should(BeEquivalentTo(defsToUpload.Exchanges)) + Expect(bindingDefs).Should(BeEquivalentTo(defs.Bindings)) + + _, _ = rmqc.DeleteExchange("/", exchangeName) + _, _ = rmqc.DeleteQueue("/", queueName) + _, _ = rmqc.DeleteBinding("/", bi) + }) + }) })