Skip to content

Commit

Permalink
refact(gateapi): swagger 2.4.15 query params are typed now (#292)
Browse files Browse the repository at this point in the history
* chore(gateapi): update gateapi from 5c625da5 using swagger 2.4.14

* feat(contribution): add instructions on how to generate gateapi using 2.4.1

* refact(gateapi): swagger 2.4.14 query params are typed now

* tests(gateapi): gateapi generated code expects valid JSON and headers

This also removes "*malformed" test cases since 2.14.4 doesn't return parsing errors

swagger-api/swagger-codegen#10434 reports the issue.
hopefully swagger-api/swagger-codegen#10429 be merged will add that ability back in.

* refactor(imports): fixed import styling

* chore(gateapi): use swagger-cli 2.4.15
  • Loading branch information
kevinawoo authored Aug 18, 2020
1 parent 58aab9f commit 2b364bb
Show file tree
Hide file tree
Showing 188 changed files with 20,163 additions and 16,265 deletions.
14 changes: 10 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,14 @@ from the root `spin/` directory.

Spin CLI uses [Swagger](https://swagger.io/) to generate the API client library for [Gate](https://github.com/spinnaker/gate). To update the client library:

- From the root of the Gate directory, execute `swagger/generate_swagger.sh` to create the `swagger.json` API spec.
- Get the [Swagger Codegen CLI](https://github.com/swagger-api/swagger-codegen). Use the version specified [here](https://github.com/spinnaker/spin/blob/master/gateapi/.swagger-codegen/VERSION).
- Remove the existing generated code from the spin directory `rm -r ~/spin/gateapi`
- Use the Swagger Codegen CLI to generate the new library and drop it into the spin project `java -jar ~/swagger-codegen-cli.jar generate -i ~/gate/swagger/swagger.json -l go -o ~/spin/gateapi`
- Use the Swagger Codegen to generate the new library and drop it into the spin project
```bash
GATE_REPO_PATH=PATH_TO_YOUR_GATE_REPO
SWAGGER_CODEGEN_VERSION=$(cat gateapi/.swagger-codegen/VERSION)
rm -rf gateapi/ \
&& docker run -it \
-v "${GATE_REPO_PATH}/swagger/:/tmp/gate" \
-v "$PWD/gateapi/:/tmp/go/" \
"swaggerapi/swagger-codegen-cli:${SWAGGER_CODEGEN_VERSION}" generate -i /tmp/gate/swagger.json -l go -o /tmp/go/
```
- Commit the changes and open a PR.
4 changes: 3 additions & 1 deletion cmd/account/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"fmt"
"net/http"

gate "github.com/spinnaker/spin/gateapi"

"github.com/spf13/cobra"

"github.com/spinnaker/spin/util"
Expand Down Expand Up @@ -57,7 +59,7 @@ func getAccount(cmd *cobra.Command, options *getOptions, args []string) error {
return err
}

account, resp, err := options.GateClient.CredentialsControllerApi.GetAccountUsingGET(options.GateClient.Context, accountName, map[string]interface{}{})
account, resp, err := options.GateClient.CredentialsControllerApi.GetAccountUsingGET(options.GateClient.Context, accountName, &gate.CredentialsControllerApiGetAccountUsingGETOpts{})
if resp != nil {
if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Account '%s' not found\n", accountName)
Expand Down
36 changes: 1 addition & 35 deletions cmd/account/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,6 @@ func TestAccountGet_flags(t *testing.T) {
}
}

func TestAccountGet_malformed(t *testing.T) {
ts := testGateAccountGetMalformed()
defer ts.Close()

rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard)
rootCmd.AddCommand(NewAccountCmd(rootOpts))

args := []string{"account", "get", ACCOUNT, "--gate-endpoint=" + ts.URL}
rootCmd.SetArgs(args)
err := rootCmd.Execute()
if err == nil { // Success is actually failure here, return payload is malformed.
t.Fatalf("Command failed with: %d", err)
}
}

func TestAccountGet_fail(t *testing.T) {
ts := testGateFail()
defer ts.Close()
Expand All @@ -142,31 +127,12 @@ func TestAccountGet_fail(t *testing.T) {
func testGateAccountGetSuccess() *httptest.Server {
mux := util.TestGateMuxWithVersionHandler()
mux.Handle("/credentials/"+ACCOUNT, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("content-type", "application/json")
fmt.Fprintln(w, strings.TrimSpace(accountJson))
}))
return httptest.NewServer(mux)
}

// testGateAccountGetMalformed returns a malformed list of pipeline configs.
func testGateAccountGetMalformed() *httptest.Server {
mux := util.TestGateMuxWithVersionHandler()
mux.Handle("/credentials/"+ACCOUNT, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, strings.TrimSpace(malformedAccountGetJson))
}))
return httptest.NewServer(mux)
}

const malformedAccountGetJson = `
"type": "kubernetes",
"providerVersion": "v2",
"environment": "self",
"skin": "v2",
"name": "self",
"cloudProvider": "kubernetes",
"accountType": "self"
}
`

const accountJson = `
{
"type": "kubernetes",
Expand Down
5 changes: 4 additions & 1 deletion cmd/account/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import (
"fmt"
"net/http"

"github.com/antihax/optional"
"github.com/spf13/cobra"

gate "github.com/spinnaker/spin/gateapi"
)

type listOptions struct {
Expand Down Expand Up @@ -52,7 +55,7 @@ func NewListCmd(accOptions *accountOptions) *cobra.Command {
}

func listAccount(cmd *cobra.Command, options *listOptions, args []string) error {
accountList, resp, err := options.GateClient.CredentialsControllerApi.GetAccountsUsingGET(options.GateClient.Context, map[string]interface{}{"expand": options.expand})
accountList, resp, err := options.GateClient.CredentialsControllerApi.GetAccountsUsingGET(options.GateClient.Context, &gate.CredentialsControllerApiGetAccountsUsingGETOpts{Expand: optional.NewBool(options.expand)})
if err != nil {
return err
}
Expand Down
40 changes: 1 addition & 39 deletions cmd/account/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,6 @@ func TestAccountList_basic(t *testing.T) {
}
}

func TestAccountList_malformed(t *testing.T) {
ts := testGateAccountListMalformed()
defer ts.Close()

rootCmd, options := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard)
rootCmd.AddCommand(NewAccountCmd(options))

args := []string{"account", "list", "--gate-endpoint=" + ts.URL}
rootCmd.SetArgs(args)
err := rootCmd.Execute()
if err == nil {
t.Fatalf("Command failed with: %s", err)
}
}

func TestAccountList_fail(t *testing.T) {
ts := testGateFail()
defer ts.Close()
Expand All @@ -74,35 +59,12 @@ func TestAccountList_fail(t *testing.T) {
func testGateAccountListSuccess() *httptest.Server {
mux := util.TestGateMuxWithVersionHandler()
mux.Handle("/credentials/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("content-type", "application/json")
fmt.Fprintln(w, strings.TrimSpace(accountListJson))
}))
return httptest.NewServer(mux)
}

func testGateAccountListMalformed() *httptest.Server {
mux := util.TestGateMuxWithVersionHandler()
mux.Handle("/credentials/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, strings.TrimSpace(malformedAccountListJson))
}))
return httptest.NewServer(mux)
}

const malformedAccountListJson = `
{
"type": "kubernetes",
"skin": "v2",
"providerVersion": "v2",
"name": "foobar"
},
{
"type": "dockerRegistry",
"skin": "v1",
"providerVersion": "v1",
"name": "dockerhub"
}
]
`

const accountListJson = `[
{
"type": "kubernetes",
Expand Down
7 changes: 4 additions & 3 deletions cmd/application/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import (
"fmt"
"net/http"

orca_tasks "github.com/spinnaker/spin/cmd/orca-tasks"

"github.com/antihax/optional"
"github.com/spf13/cobra"

orca_tasks "github.com/spinnaker/spin/cmd/orca-tasks"
gate "github.com/spinnaker/spin/gateapi"
"github.com/spinnaker/spin/util"
)

Expand Down Expand Up @@ -65,7 +66,7 @@ func deleteApplication(cmd *cobra.Command, options *deleteOptions, args []string
},
}

_, resp, err := options.GateClient.ApplicationControllerApi.GetApplicationUsingGET(options.GateClient.Context, applicationName, map[string]interface{}{"expand": false})
_, resp, err := options.GateClient.ApplicationControllerApi.GetApplicationUsingGET(options.GateClient.Context, applicationName, &gate.ApplicationControllerApiGetApplicationUsingGETOpts{Expand: optional.NewBool(false)})

if resp != nil && resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Attempting to delete application '%s' which does not exist, exiting...", applicationName)
Expand Down
3 changes: 3 additions & 0 deletions cmd/application/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,23 @@ func testGateApplicationDeleteSuccess() *httptest.Server {
mux.Handle("/applications/"+APP, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
payload := map[string]string{} // We don't use the payload, we are just checking if the target app exists.
b, _ := json.Marshal(&payload)
w.Header().Add("content-type", "application/json")
fmt.Fprintln(w, string(b))
}))
mux.Handle("/tasks", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
payload := map[string]string{
"ref": "/tasks/id",
}
b, _ := json.Marshal(&payload)
w.Header().Add("content-type", "application/json")
fmt.Fprintln(w, string(b))
}))
mux.Handle("/tasks/id", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
payload := map[string]string{
"status": "SUCCEEDED",
}
b, _ := json.Marshal(&payload)
w.Header().Add("content-type", "application/json")
fmt.Fprintln(w, string(b))
}))
return httptest.NewServer(mux)
Expand Down
8 changes: 5 additions & 3 deletions cmd/application/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import (
"fmt"
"net/http"

"github.com/spinnaker/spin/util"

"github.com/antihax/optional"
"github.com/spf13/cobra"

gate "github.com/spinnaker/spin/gateapi"
"github.com/spinnaker/spin/util"
)

type getOptions struct {
Expand Down Expand Up @@ -63,7 +65,7 @@ func getApplication(cmd *cobra.Command, options *getOptions, args []string) erro
return err
}

app, resp, err := options.GateClient.ApplicationControllerApi.GetApplicationUsingGET(options.GateClient.Context, applicationName, map[string]interface{}{"expand": options.expand})
app, resp, err := options.GateClient.ApplicationControllerApi.GetApplicationUsingGET(options.GateClient.Context, applicationName, &gate.ApplicationControllerApiGetApplicationUsingGETOpts{Expand: optional.NewBool(options.expand)})
if resp != nil {
if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Application '%s' not found\n", applicationName)
Expand Down
53 changes: 1 addition & 52 deletions cmd/application/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,6 @@ func TestApplicationGet_flags(t *testing.T) {
}
}

func TestApplicationGet_malformed(t *testing.T) {
ts := testGateApplicationGetMalformed()
defer ts.Close()

rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard)
rootCmd.AddCommand(NewApplicationCmd(rootOpts))

args := []string{"application", "get", APP, "--gate-endpoint=" + ts.URL}
rootCmd.SetArgs(args)
err := rootCmd.Execute()
if err == nil { // Success is actually failure here, return payload is malformed.
t.Fatalf("Command failed with: %d", err)
}
}

func TestApplicationGet_fail(t *testing.T) {
ts := testGateFail()
defer ts.Close()
Expand All @@ -149,48 +134,12 @@ func TestApplicationGet_fail(t *testing.T) {
func testGateApplicationGetSuccess() *httptest.Server {
mux := util.TestGateMuxWithVersionHandler()
mux.Handle("/applications/"+APP, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("content-type", "application/json")
fmt.Fprintln(w, strings.TrimSpace(applicationJsonExpanded))
}))
return httptest.NewServer(mux)
}

// testGateApplicationGetMalformed returns a malformed list of pipeline configs.
func testGateApplicationGetMalformed() *httptest.Server {
mux := util.TestGateMuxWithVersionHandler()
mux.Handle("/applications/"+APP, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, strings.TrimSpace(malformedApplicationGetJson))
}))
return httptest.NewServer(mux)
}

const malformedApplicationGetJson = `
"accounts": "account1",
"cloudproviders": [
"gce",
"kubernetes"
],
"createTs": "1527261941734",
"email": "app",
"instancePort": 80,
"lastModifiedBy": "anonymous",
"name": "app",
"permissions": {
"EXECUTE": [
"admin-group"
],
"READ": [
"admin-group",
"user-group"
],
"WRITE": [
"admin-group"
]
},
"updateTs": "1527261941735",
"user": "anonymous"
}
`

// GET /applications/{app} returns an envelope with 'attributes' and 'clusters'.
const applicationJsonExpanded = `
{
Expand Down
4 changes: 3 additions & 1 deletion cmd/application/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"fmt"
"net/http"

gate "github.com/spinnaker/spin/gateapi"

"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -49,7 +51,7 @@ func NewListCmd(appOptions *applicationOptions) *cobra.Command {
}

func listApplication(cmd *cobra.Command, options *listOptions, args []string) error {
appList, resp, err := options.GateClient.ApplicationControllerApi.GetAllApplicationsUsingGET(options.GateClient.Context, map[string]interface{}{})
appList, resp, err := options.GateClient.ApplicationControllerApi.GetAllApplicationsUsingGET(options.GateClient.Context, &gate.ApplicationControllerApiGetAllApplicationsUsingGETOpts{})
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 2b364bb

Please sign in to comment.