From fa3525e3007b9c522f4cdab366ff0c1d2d3f05d7 Mon Sep 17 00:00:00 2001 From: Matt Siwiec Date: Wed, 17 Jan 2024 09:11:21 -0700 Subject: [PATCH] Update ipam-client (#69) # Summary - [x] Update the client types to use standard gql naming practices from [PR](https://github.com/infratographer/ipam-api/pull/55) - [x] Update the ipam-api client `GetIPAddressesByNode(...)` to not use `_entities` query directly against ipam-api. Now uses [node-resolver](https://github.com/infratographer/node-resolver) via the supergraph. ``` query NodeIPAddresses { node(id:"loadbal-example") { id ... on LoadBalancer { id IPAddresses { id ip reserved } } } } ``` - [x] Move to hasura gql [client](https://github.com/hasura/go-graphql-client/pulls), - [x] Cleanup types to reduce duplication and ensure `graphql/json` struct tags are present ## Dependencies - [x] https://github.com/infratographer/ipam-api/pull/55 Signed-off-by: Matt Siwiec --- go.mod | 3 +- go.sum | 48 +++++++++++- pkg/ipamclient/client.go | 38 +++++----- pkg/ipamclient/client_test.go | 107 +++++++++++++++++---------- pkg/ipamclient/internal/mock/mock.go | 14 ++-- pkg/ipamclient/types.go | 69 +++++++++-------- 6 files changed, 177 insertions(+), 102 deletions(-) diff --git a/go.mod b/go.mod index 8b18c35f..da27d204 100644 --- a/go.mod +++ b/go.mod @@ -10,11 +10,11 @@ require ( github.com/Yamashou/gqlgenc v0.14.0 github.com/brianvoe/gofakeit/v6 v6.23.2 github.com/hashicorp/go-multierror v1.1.1 + github.com/hasura/go-graphql-client v0.10.1 github.com/labstack/echo/v4 v4.10.2 github.com/lib/pq v1.10.9 github.com/mattn/go-sqlite3 v1.14.17 github.com/mitchellh/go-homedir v1.1.0 - github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 @@ -163,4 +163,5 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/go.sum b/go.sum index 2ce76618..f61966c6 100644 --- a/go.sum +++ b/go.sum @@ -83,11 +83,13 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/brianvoe/gofakeit/v6 v6.23.2 h1:lVde18uhad5wII/f5RMVFLtdQNE0HaGFuBUXmYKk8i8= github.com/brianvoe/gofakeit/v6 v6.23.2/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -133,8 +135,13 @@ github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/garsue/watermillzap v1.2.0 h1:IA0zGb5b7mIGLXN9P2/6CmP5+f7Qgb00BdL2VCAk2SA= github.com/garsue/watermillzap v1.2.0/go.mod h1:uo3SDSGYaw6RBzUx9jcHMYqypOTqlQ4/vz+8r1olRto= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -147,8 +154,22 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.0.4 h1:5eXU1CZhpQdq5kXbKb+sECH5Ia5KiO6CYzIzdlVx6Bs= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= @@ -203,6 +224,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -224,8 +246,11 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-transport-ws v0.0.2 h1:DbmSkbIGzj8SvHei6n8Mh9eLQin8PtA8xY9eCzjRpvo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -241,6 +266,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= +github.com/hasura/go-graphql-client v0.10.1 h1:9lY5mFfKRIjkPJ/EUq41mWYJZpTdAVjs24nibWoGyDo= +github.com/hasura/go-graphql-client v0.10.1/go.mod h1:z9UPkMmCBMuJjvBEtdE6F+oTR2r15AcjirVNq/8P+Ig= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= @@ -299,13 +326,17 @@ github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jaevor/go-nanoid v1.3.0 h1:nD+iepesZS6pr3uOVf20vR9GdGgJW1HPaR46gtrxzkg= github.com/jaevor/go-nanoid v1.3.0/go.mod h1:SI+jFaPuddYkqkVQoNGHs81navCtH388TcrH0RqFKgY= github.com/jensneuse/diffview v1.0.0 h1:4b6FQJ7y3295JUHU3tRko6euyEboL825ZsXeZZM47Z4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -326,6 +357,8 @@ github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -366,6 +399,10 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5 github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4= @@ -419,8 +456,6 @@ github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NF github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 h1:B1PEwpArrNp4dkQrfxh/abbBAOZBVp0ds+fBEOUOqOc= -github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -463,6 +498,11 @@ github.com/testcontainers/testcontainers-go v0.21.0 h1:syePAxdeTzfkap+RrJaQZpJQ/ github.com/testcontainers/testcontainers-go v0.21.0/go.mod h1:c1ez3WVRHq7T/Aj+X3TIipFBwkBaNT5iNCY8+1b83Ng= github.com/testcontainers/testcontainers-go/modules/postgres v0.21.0 h1:rFPyTR7pPMiHcDktXwd5iZ+mA1cHH/WRa+knxBcY8wU= github.com/testcontainers/testcontainers-go/modules/postgres v0.21.0/go.mod h1:Uoia8PX1RewxkJTbeXGBK6vgMjlmRbnL/4n0EXH2Z54= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= @@ -544,6 +584,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -911,6 +952,7 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -935,6 +977,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/pkg/ipamclient/client.go b/pkg/ipamclient/client.go index 7b723fe1..015d9151 100644 --- a/pkg/ipamclient/client.go +++ b/pkg/ipamclient/client.go @@ -5,15 +5,15 @@ import ( "net/http" "github.com/3th1nk/cidr" - "github.com/shurcooL/graphql" + graphql "github.com/hasura/go-graphql-client" "go.infratographer.com/x/gidx" "golang.org/x/exp/slices" ) // GQLClient is an interface for a graphql client type GQLClient interface { - Query(ctx context.Context, q interface{}, variables map[string]interface{}) error - Mutate(ctx context.Context, m interface{}, variables map[string]interface{}) error + Query(ctx context.Context, q interface{}, variables map[string]interface{}, options ...graphql.Option) error + Mutate(ctx context.Context, m interface{}, variables map[string]interface{}, options ...graphql.Option) error } // Client creates a new lb api client against a specific endpoint @@ -22,11 +22,11 @@ type Client struct { httpClient *http.Client } -// ClientOption is a function that modifies a client -type ClientOption func(*Client) +// Option is a function that modifies a client +type Option func(*Client) -// NewClient creates a new lb api client -func NewClient(url string, opts ...ClientOption) *Client { +// New creates a new ipam api client +func New(url string, opts ...Option) *Client { c := &Client{ httpClient: http.DefaultClient, } @@ -41,7 +41,7 @@ func NewClient(url string, opts ...ClientOption) *Client { } // WithHTTPClient functional option to set the http client -func WithHTTPClient(cli *http.Client) ClientOption { +func WithHTTPClient(cli *http.Client) Option { return func(c *Client) { c.httpClient = cli } @@ -55,7 +55,7 @@ func (c *Client) GetIPAddress(ctx context.Context, id string) (*GetIPAddress, er } vars := map[string]interface{}{ - "id": id, + "id": graphql.ID(id), } var ipa GetIPAddress @@ -74,7 +74,7 @@ func (c *Client) GetIPBlock(ctx context.Context, id string) (*GetIPBlock, error) } vars := map[string]interface{}{ - "id": id, + "id": graphql.ID(id), } var ipb GetIPBlock @@ -128,7 +128,7 @@ func (c *Client) GetNextAvailableAddressFromBlock(ctx context.Context, id string } // CreateIPAddressFromBlock creates an IP Address from the next available address in a given block -func (c *Client) CreateIPAddressFromBlock(ctx context.Context, blockid string, nodeid string, nodeownerid string, reserve bool) (*CreateIPAddress, error) { +func (c *Client) CreateIPAddressFromBlock(ctx context.Context, blockid string, nodeid string, nodeownerid string, reserve bool) (*CreateIPAddressResult, error) { _, err := gidx.Parse(blockid) if err != nil { return nil, err @@ -164,7 +164,7 @@ func (c *Client) CreateIPAddressFromBlock(ctx context.Context, blockid string, n return nil, err } - return &ipn, err + return &ipn.CreateIPAddressResult, err } // DeleteIPAddress deletes an IP Address by id @@ -175,7 +175,7 @@ func (c *Client) DeleteIPAddress(ctx context.Context, id string) (*DeleteIPAddre } vars := map[string]interface{}{ - "id": id, + "id": graphql.ID(id), } var ipd DeleteIPAddress @@ -186,21 +186,21 @@ func (c *Client) DeleteIPAddress(ctx context.Context, id string) (*DeleteIPAddre return &ipd, nil } -// GetIPAddresses returns a list of IP Addresses by node id -func (c *Client) GetIPAddresses(ctx context.Context, nodeID string) (*GetIPAddressesByNode, error) { +// GetIPAddresses returns a list of loadbalancer IP Addresses from node id +func (c *Client) GetIPAddresses(ctx context.Context, nodeID string) ([]IPAddressNode, error) { _, err := gidx.Parse(nodeID) if err != nil { return nil, err } vars := map[string]interface{}{ - "id": nodeID, + "id": graphql.ID(nodeID), } - var ipas GetIPAddressesByNode - if err := c.gqlCli.Query(ctx, &ipas, vars); err != nil { + var nodeIPs GetIPAddressesByNode + if err := c.gqlCli.Query(ctx, &nodeIPs, vars); err != nil { return nil, err } - return &ipas, nil + return nodeIPs.NodeIPAddress.LoadBalancerFragment.IPAddresses, nil } diff --git a/pkg/ipamclient/client_test.go b/pkg/ipamclient/client_test.go index a279f839..c3607fc4 100644 --- a/pkg/ipamclient/client_test.go +++ b/pkg/ipamclient/client_test.go @@ -7,7 +7,7 @@ import ( "net/http/httptest" "testing" - "github.com/shurcooL/graphql" + "github.com/hasura/go-graphql-client" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -16,7 +16,7 @@ import ( func newGQLClientMock() *mock.GQLClient { mockCli := &mock.GQLClient{} - mockCli.DoMutate = func(ctx context.Context, m interface{}, variables map[string]interface{}) error { + mockCli.DoMutate = func(ctx context.Context, m interface{}, variables map[string]interface{}, options ...graphql.Option) error { block, ok := m.(*GetIPBlock) if ok { block.IPBlock.ID = "ipamibk-12345" @@ -42,7 +42,7 @@ func newGQLClientMock() *mock.GQLClient { return nil } - mockCli.DoQuery = func(ctx context.Context, q interface{}, variables map[string]interface{}) error { + mockCli.DoQuery = func(ctx context.Context, q interface{}, variables map[string]interface{}, options ...graphql.Option) error { block, ok := q.(*GetIPBlock) if ok { block.IPBlock.ID = "ipamibk-12345" @@ -73,7 +73,16 @@ func newGQLClientMock() *mock.GQLClient { func TestGetIPBlock(t *testing.T) { cli := Client{ - gqlCli: newGQLClientMock(), + gqlCli: mustNewGQLTestClient(`{ + "data": { + "ipBlock": { + "allowAutoAllocate": true, + "allowAutoSubnet": true, + "id": "ipamibk-12345", + "prefix": "192.168.10.0/28" + } + } +}`), } block, err := cli.GetIPBlock(context.TODO(), "ipamibk-12345") @@ -91,15 +100,25 @@ func TestGetIPBlock(t *testing.T) { func TestGetIPAddress(t *testing.T) { cli := Client{ - gqlCli: newGQLClientMock(), + gqlCli: mustNewGQLTestClient( + `{ + "data": { + "ipAddress": { + "id": "ipamipa-12345", + "ip": "192.168.10.1", + "reserved": false + } + } +}`), } - address, err := cli.GetIPAddress(context.Background(), "ipamipa-12345") + ipResult, err := cli.GetIPAddress(context.Background(), "ipamipa-12345") require.NoError(t, err) - require.NotNil(t, address) + require.NotNil(t, ipResult) - assert.Equal(t, address.IPAddress.ID, "ipamipa-12345") - assert.Equal(t, address.IPAddress.IP, "192.168.10.1") + assert.Equal(t, ipResult.IPAddress.ID, "ipamipa-12345") + assert.Equal(t, ipResult.IPAddress.IP, "192.168.10.1") + assert.False(t, ipResult.IPAddress.Reserved) baddress, err := cli.GetIPAddress(context.TODO(), "badprefix-test") require.Error(t, err) @@ -108,7 +127,16 @@ func TestGetIPAddress(t *testing.T) { func TestGetNextAvailableAddressFromBlock(t *testing.T) { cli := Client{ - gqlCli: newGQLClientMock(), + gqlCli: mustNewGQLTestClient(`{ + "data": { + "ipBlock": { + "allowAutoAllocate": true, + "allowAutoSubnet": true, + "id": "ipamibk-12345", + "prefix": "192.168.10.0/28" + } + } +}`), } ip, err := cli.GetNextAvailableAddressFromBlock(context.Background(), "ipamibk-12345") @@ -127,7 +155,13 @@ func TestGetNextAvailableAddressFromBlock(t *testing.T) { func TestDeleteIPAddress(t *testing.T) { cli := Client{ - gqlCli: newGQLClientMock(), + gqlCli: mustNewGQLTestClient(`{ + "data": { + "deleteIPAddress": { + "deletedID": "ipamipa-12345" + } + } +}`), } // TODO: build better mock to build more expressive tests @@ -159,24 +193,24 @@ func TestCreateIPAddressFromBlock(t *testing.T) { func TestGetIPAddressesByNodeID(t *testing.T) { cli := Client{ - gqlCli: mustNewGQLTestClient(`{ + gqlCli: mustNewGQLTestClient( + `{ "data": { - "_entities": [ - { - "IPAddresses": [ - { - "id": "ipamipa-8IPzP37YJ1iTxJdMrCods", - "ip": "192.168.1.142", - "reserved": false - }, - { - "id": "ipamipa-rPBY83fPw6Ll5sueCMpDr", - "ip": "192.168.1.1", - "reserved": true - } - ] - } - ] + "node": { + "id": "loadbal-randovalue", + "IPAddresses": [ + { + "id": "ipamipa-8IPzP37YJ1iTxJdMrCods", + "ip": "192.168.1.142", + "reserved": false + }, + { + "id": "ipamipa-rPBY83fPw6Ll5sueCMpDr", + "ip": "192.168.1.1", + "reserved": true + } + ] + } } }`), } @@ -190,18 +224,15 @@ func TestGetIPAddressesByNodeID(t *testing.T) { t.Run("retrieves nodeID ip addresses", func(t *testing.T) { ips, err := cli.GetIPAddresses(context.Background(), "loadbal-randovalue") require.NoError(t, err) - require.NotNil(t, ips) - - require.Len(t, ips.Entities, 1) - require.Len(t, ips.Entities[0].IPAddresses, 2) + require.Len(t, ips, 2) - assert.Equal(t, "ipamipa-8IPzP37YJ1iTxJdMrCods", ips.Entities[0].IPAddresses[0].ID) - assert.Equal(t, "192.168.1.142", ips.Entities[0].IPAddresses[0].IP) - assert.False(t, ips.Entities[0].IPAddresses[0].Reserved) + assert.Equal(t, "ipamipa-8IPzP37YJ1iTxJdMrCods", ips[0].ID) + assert.Equal(t, "192.168.1.142", ips[0].IP) + assert.False(t, ips[0].Reserved) - assert.Equal(t, "ipamipa-rPBY83fPw6Ll5sueCMpDr", ips.Entities[0].IPAddresses[1].ID) - assert.Equal(t, "192.168.1.1", ips.Entities[0].IPAddresses[1].IP) - assert.True(t, ips.Entities[0].IPAddresses[1].Reserved) + assert.Equal(t, "ipamipa-rPBY83fPw6Ll5sueCMpDr", ips[1].ID) + assert.Equal(t, "192.168.1.1", ips[1].IP) + assert.True(t, ips[1].Reserved) }) } diff --git a/pkg/ipamclient/internal/mock/mock.go b/pkg/ipamclient/internal/mock/mock.go index a9cd7b3a..a2b15196 100644 --- a/pkg/ipamclient/internal/mock/mock.go +++ b/pkg/ipamclient/internal/mock/mock.go @@ -2,20 +2,22 @@ package mock import ( "context" + + "github.com/hasura/go-graphql-client" ) // GQLClient is the mock http client type GQLClient struct { - DoQuery func(ctx context.Context, q interface{}, variables map[string]interface{}) error - DoMutate func(ctx context.Context, m interface{}, variables map[string]interface{}) error + DoQuery func(ctx context.Context, q interface{}, variables map[string]interface{}, options ...graphql.Option) error + DoMutate func(ctx context.Context, m interface{}, variables map[string]interface{}, options ...graphql.Option) error } // Query is the mock for a gqlclient query -func (c *GQLClient) Query(ctx context.Context, q interface{}, variables map[string]interface{}) error { - return c.DoQuery(ctx, q, variables) +func (c *GQLClient) Query(ctx context.Context, q interface{}, variables map[string]interface{}, options ...graphql.Option) error { + return c.DoQuery(ctx, q, variables, options...) } // Mutate is the mock for a gqlclient mutate -func (c *GQLClient) Mutate(ctx context.Context, m interface{}, variables map[string]interface{}) error { - return c.DoMutate(ctx, m, variables) +func (c *GQLClient) Mutate(ctx context.Context, m interface{}, variables map[string]interface{}, options ...graphql.Option) error { + return c.DoMutate(ctx, m, variables, options...) } diff --git a/pkg/ipamclient/types.go b/pkg/ipamclient/types.go index c731e238..8ea0b87b 100644 --- a/pkg/ipamclient/types.go +++ b/pkg/ipamclient/types.go @@ -2,84 +2,77 @@ package ipamclient // GetIPAddressResult is the result of a query for an IP Address type GetIPAddressResult struct { - ID string - IP string - Reserved bool - IPBlock IPBlock + IPAddressNode + IPBlock IPBlock `graphql:"ipBlock" json:"ipBlock"` } // GetIPBlockResult is the result of a query for an IP Block type GetIPBlockResult struct { - ID string - Prefix string - AllowAutoSubnet bool - AllowAutoAllocate bool - IPBlockType IPBlockType - IPAddress IPAddresses + IPBlock + + IPAddress IPAddresses `graphql:"ipAddress" json:"ipAddress"` } // IPBlock is part of a returned query including an associated block type IPBlock struct { - ID string - Prefix string - AllowAutoSubnet bool - AllowAutoAllocate bool - IPBlockType IPBlockType + ID string `graphql:"id" json:"id"` + Prefix string `graphql:"prefix" json:"prefix"` + AllowAutoSubnet bool `graphql:"allowAutoSubnet" json:"allowAutoSubnet"` + AllowAutoAllocate bool `graphql:"allowAutoAllocate" json:"allowAutoAllocate"` + IPBlockType IPBlockType `graphql:"ipBlockType" json:"ipBlockType"` } // IPAddresses is part of a returned query including the edges of an associated IP Address type IPAddresses struct { - Edges []IPAddressEdge + Edges []IPAddressEdge `graphql:"edges" json:"edges"` } // IPAddressEdge is part of a returned query including an edge(s) associated to an IP Address type IPAddressEdge struct { - Node IPAddressNode + Node IPAddressNode `graphql:"node" json:"node"` } // IPAddressNode is part of a returned query including an associated IP address type IPAddressNode struct { - ID string - IP string - Reserved bool + ID string `graphql:"id" json:"id"` + IP string `graphql:"ip" json:"ip"` + Reserved bool `graphql:"reserved" json:"reserved"` } // IPBlockType is part of a returned query including an associated block type type IPBlockType struct { - ID string - Name string - Owner Owner + ID string `graphql:"id" json:"id"` + Name string `graphql:"name" json:"name"` + Owner Owner `graphql:"owner" json:"owner"` } // Owner is part of a returned query including an associated owner type Owner struct { - ID string + ID string `graphql:"id" json:"id"` } // GetIPAddress is the query used for getting an IP Address type GetIPAddress struct { - IPAddress GetIPAddressResult `graphql:"ip_address(id: $id)"` + IPAddress GetIPAddressResult `graphql:"ipAddress(id: $id)"` } // GetIPBlock is the query used for getting an IP Block type GetIPBlock struct { - IPBlock GetIPBlockResult `graphql:"ip_block(id: $id)"` + IPBlock GetIPBlockResult `graphql:"ipBlock(id: $id)"` } // CreateIPAddress is the mutation for creating an IP Address type CreateIPAddress struct { - IPAddress CreateIPAddressResult `graphql:"createIPAddress(input: $input)"` + CreateIPAddressResult `graphql:"createIPAddress(input: $input)"` } // CreateIPAddressResult is the result of the mutation to create an IP Address type CreateIPAddressResult struct { - // IPAddress StupidIPAddress `graphql:"ip_address"` + // IPAddress MyIPAddress `graphql:"ipAddress"` IPAddress struct { - ID string - IP string - Reserved bool - IPBlock IPBlock - } `graphql:"ip_address"` + IPAddressNode + IPBlock IPBlock + } `graphql:"ipAddress"` } // CreateIPAddressInput is the set of input required for creating an IP address @@ -108,7 +101,11 @@ type IPAddressableFragment struct { // GetIPAddressesByNode query for getting IP Addresses by node type GetIPAddressesByNode struct { - Entities []struct { - IPAddressableFragment `graphql:"... on IPAddressable"` - } `graphql:"_entities(representations: {__typename:\"IPAddressable\", id:$id})"` + NodeIPAddress struct { + ID string `graphql:"id" json:"id"` + + LoadBalancerFragment struct { + IPAddressableFragment + } `graphql:"... on LoadBalancer"` + } `graphql:"node(id: $id)"` }