Răsfoiți Sursa

add swagger inline comments and generation doc

Alexander Belanger 3 ani în urmă
părinte
comite
abfbe90255

+ 1 - 0
.gitignore

@@ -14,6 +14,7 @@ staging.sh
 *.crt
 *.key
 bin
+openapi.yaml
 
 # Local docs directories
 /docs/.obsidian

+ 2 - 0
api/server/handlers/registry/create.go

@@ -49,6 +49,8 @@ func (p *RegistryCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		return
 	}
 
+	//  TODO!!!: validate the credentials here!!!
+
 	// create a registry model
 	regModel := &models.Registry{
 		Name:               request.Name,

+ 102 - 0
api/server/router/v1/cluster.go

@@ -11,6 +11,21 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
+// swagger:parameters createNamespace listNamespaces
+type clusterPathParams struct {
+	// The project id
+	// in: path
+	// required: true
+	// minimum: 1
+	ProjectID uint `json:"project_id"`
+
+	// The cluster id
+	// in: path
+	// required: true
+	// minimum: 1
+	ClusterID uint `json:"cluster_id"`
+}
+
 func NewV1ClusterScopedRegisterer(children ...*router.Registerer) *router.Registerer {
 	return &router.Registerer{
 		GetRoutes: GetV1ClusterScopedRoutes,
@@ -56,6 +71,31 @@ func getV1ClusterRoutes(
 	var routes []*router.Route
 
 	// POST /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces -> cluster.NewCreateNamespaceHandler
+	// swagger:operation POST /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces createNamespace
+	//
+	// Creates a new namespace
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Create a new namespace
+	// tags:
+	// - Namespaces
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - in: body
+	//     name: CreateNamespaceRequest
+	//     description: The namespace to create
+	//     schema:
+	//       $ref: '#/definitions/CreateNamespaceRequest'
+	// responses:
+	//   '201':
+	//     description: Successfully created a new namespace
+	//     schema:
+	//       $ref: '#/definitions/CreateNamespaceResponse'
+	//   '403':
+	//     description: Forbidden
 	createNamespaceEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbCreate,
@@ -85,6 +125,29 @@ func getV1ClusterRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace} -> cluster.NewGetNamespaceHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace} getNamespace
+	//
+	// Gets a namespace
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Get a namespace
+	// tags:
+	// - Namespaces
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - name: namespace
+	// responses:
+	//   '200':
+	//     description: Successfully got the namespace
+	//     schema:
+	//       $ref: '#/definitions/GetNamespaceResponse'
+	//   '403':
+	//     description: Forbidden
+	//   '404':
+	//     description: Not Found
 	getNamespaceEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
@@ -113,6 +176,26 @@ func getV1ClusterRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces -> cluster.NewListNamespacesHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces listNamespaces
+	//
+	// Lists namespaces
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: List all namespaces
+	// tags:
+	// - Namespaces
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	// responses:
+	//   '200':
+	//     description: Successfully listed namespaces
+	//     schema:
+	//       $ref: '#/definitions/ListNamespacesResponse'
+	//   '403':
+	//     description: Forbidden
 	listNamespacesEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
@@ -141,6 +224,25 @@ func getV1ClusterRoutes(
 	})
 
 	// DELETE /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace} -> cluster.NewDeleteNamespaceHandler
+	// swagger:operation DELETE /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace} deleteNamespace
+	//
+	// Deletes a namespace
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Delete a namespace
+	// tags:
+	// - Namespaces
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - name: namespace
+	// responses:
+	//   '200':
+	//     description: Successfully deleted namespace
+	//   '403':
+	//     description: Forbidden
 	deleteNamespaceEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbDelete,

+ 20 - 0
api/server/router/v1/namespace.go

@@ -8,6 +8,26 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
+// swagger:parameters getNamespace deleteNamespace createRelease
+type namespacePathParams struct {
+	// The project id
+	// in: path
+	// required: true
+	// minimum: 1
+	ProjectID uint `json:"project_id"`
+
+	// The cluster id
+	// in: path
+	// required: true
+	// minimum: 1
+	ClusterID uint `json:"cluster_id"`
+
+	// The namespace name
+	// in: path
+	// required: true
+	Namespace string `json:"namespace"`
+}
+
 func NewV1NamespaceScopedRegisterer(children ...*router.Registerer) *router.Registerer {
 	return &router.Registerer{
 		GetRoutes: GetV1NamespaceScopedRoutes,

+ 9 - 0
api/server/router/v1/project.go

@@ -8,6 +8,15 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
+// swagger:parameters createRegistry listRegistries
+type projectPathParams struct {
+	// The project id
+	// in: path
+	// required: true
+	// minimum: 1
+	ProjectID uint `json:"project_id"`
+}
+
 func NewV1ProjectScopedRegisterer(children ...*router.Registerer) *router.Registerer {
 	return &router.Registerer{
 		GetRoutes: GetV1ProjectScopedRoutes,

+ 166 - 0
api/server/router/v1/registry.go

@@ -11,6 +11,21 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
+// swagger:parameters getRegistry deleteRegistry createRegistryRepository listRegistryRepositories listRegistryImages
+type registryPathParams struct {
+	// The project id
+	// in: path
+	// required: true
+	// minimum: 1
+	ProjectID uint `json:"project_id"`
+
+	// The registry id
+	// in: path
+	// required: true
+	// minimum: 1
+	RegistryID uint `json:"registry_id"`
+}
+
 func NewV1RegistryScopedRegisterer(children ...*router.Registerer) *router.Registerer {
 	return &router.Registerer{
 		GetRoutes: GetV1RegistryScopedRoutes,
@@ -56,6 +71,30 @@ func getV1RegistryRoutes(
 	var routes []*router.Route
 
 	// POST /api/v1/projects/{project_id}/registries -> registry.NewRegistryCreateHandler
+	// swagger:operation POST /api/v1/projects/{project_id}/registries createRegistry
+	//
+	// Connects a new image registry
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Connect an image registry
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - in: body
+	//     name: CreateRegistryRequest
+	//     description: The registry to connect
+	//     schema:
+	//       $ref: '#/definitions/CreateRegistryRequest'
+	// responses:
+	//   '201':
+	//     description: Successfully connected the registry
+	//     schema:
+	//       $ref: '#/definitions/CreateRegistryResponse'
+	//   '403':
+	//     description: Forbidden
 	createRegistryEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbCreate,
@@ -84,6 +123,26 @@ func getV1RegistryRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/registries/{registry_id} -> registry.NewRegistryGetHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/registries/{registry_id} getRegistry
+	//
+	// Gets an image registry
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Get an image registry
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - name: registry_id
+	// responses:
+	//   '201':
+	//     description: Successfully got the registry
+	//     schema:
+	//       $ref: '#/definitions/GetRegistryResponse'
+	//   '403':
+	//     description: Forbidden
 	getEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
@@ -112,6 +171,26 @@ func getV1RegistryRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/registries -> registry.NewRegistryListHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/registries listRegistries
+	//
+	// Lists registries
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: List image registries
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - name: registry_id
+	// responses:
+	//   '200':
+	//     description: Successfully listed registries
+	//     schema:
+	//       $ref: '#/definitions/ListRegistriesResponse'
+	//   '403':
+	//     description: Forbidden
 	listRegistriesEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbList,
@@ -139,6 +218,24 @@ func getV1RegistryRoutes(
 	})
 
 	// DELETE /api/v1/projects/{project_id}/registries/{registry_id} -> registry.NewRegistryDeleteHandler
+	// swagger:operation DELETE /api/v1/projects/{project_id}/registries/{registry_id} deleteRegistry
+	//
+	// Deletes an image registry.
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Disconnect image registry
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - name: registry_id
+	// responses:
+	//   '200':
+	//     description: Successfully disconnected image registry
+	//   '403':
+	//     description: Forbidden
 	deleteEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbDelete,
@@ -167,6 +264,30 @@ func getV1RegistryRoutes(
 	})
 
 	// POST /api/v1/projects/{project_id}/registries/{registry_id}/repositories -> registry.NewRegistryCreateRepositoryHandler
+	// swagger:operation POST /api/v1/projects/{project_id}/registries/{registry_id}/repositories createRegistryRepository
+	//
+	// Creates an image repository inside the registry specified by `registry_id`. This method **only** creates repositories for ECR-integrated
+	// repositories.
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Create image repository
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - name: registry_id
+	//   - in: body
+	//     name: CreateRepositoryRequest
+	//     description: The repository to create
+	//     schema:
+	//       $ref: '#/definitions/CreateRegistryRepositoryRequest'
+	// responses:
+	//   '201':
+	//     description: Successfully created the image repository
+	//   '403':
+	//     description: Forbidden
 	createRepositoryEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbCreate,
@@ -196,6 +317,26 @@ func getV1RegistryRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/registries/{registry_id}/repositories -> registry.NewRegistryListRepositoriesHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/registries/{registry_id}/repositories listRegistryRepositories
+	//
+	// Lists image repositories inside the image registry given by `registry_id`
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: List image repositories
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - name: registry_id
+	// responses:
+	//   '200':
+	//     description: Successfully listed image repositories
+	//     schema:
+	//       $ref: '#/definitions/ListRegistryRepositoriesResponse'
+	//   '403':
+	//     description: Forbidden
 	listRepositoriesEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbList,
@@ -224,6 +365,31 @@ func getV1RegistryRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/registries/{registry_id}/repositories/* -> registry.NewRegistryListImagesHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/registries/{registry_id}/repositories/{repository} listRegistryImages
+	//
+	// Lists all images in an image repository.
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: List images
+	// tags:
+	// - Registries
+	// parameters:
+	//   - name: project_id
+	//   - name: registry_id
+	//   - name: repository
+	//     in: path
+	//     description: the image repository name
+	//     type: string
+	//     required: true
+	// responses:
+	//   '200':
+	//     description: Successfully listed images
+	//     schema:
+	//       $ref: '#/definitions/ListImagesResponse'
+	//   '403':
+	//     description: Forbidden
 	listImagesEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbList,

+ 148 - 0
api/server/router/v1/release.go

@@ -10,6 +10,43 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
+// swagger:parameters getRelease updateRelease deleteRelease
+type releasePathParams struct {
+	// The project id
+	// in: path
+	// required: true
+	// minimum: 1
+	ProjectID uint `json:"project_id"`
+
+	// The registry id
+	// in: path
+	// required: true
+	// minimum: 1
+	RegistryID uint `json:"registry_id"`
+
+	// The namespace name
+	// in: path
+	// required: true
+	Namespace string `json:"namespace"`
+
+	// The release name
+	// in: path
+	// required: true
+	Name string `json:"name"`
+
+	// The release version (`0` for latest version)
+	// in: path
+	// required: true
+	// minimum: 0
+	Version uint `json:"version"`
+}
+
+// swagger:parameters listReleases
+type listReleasesRequest struct {
+	*namespacePathParams
+	*types.ListReleasesRequest
+}
+
 func NewV1ReleaseScopedRegisterer(children ...*router.Registerer) *router.Registerer {
 	return &router.Registerer{
 		GetRoutes: GetV1ReleaseScopedRoutes,
@@ -55,6 +92,30 @@ func getV1ReleaseRoutes(
 	var routes []*router.Route
 
 	// POST /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases -> release.NewCreateReleaseHandler
+	// swagger:operation POST /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases createRelease
+	//
+	// Creates a new release
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Create a new release
+	// tags:
+	// - Releases
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - name: namespace
+	//   - in: body
+	//     name: CreateReleaseRequest
+	//     description: The release to create
+	//     schema:
+	//       $ref: '#/definitions/CreateReleaseRequest'
+	// responses:
+	//   '201':
+	//     description: Successfully created the release
+	//   '403':
+	//     description: Forbidden
 	createReleaseEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbCreate,
@@ -85,6 +146,29 @@ func getV1ReleaseRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version} -> release.NewReleaseGetHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version} getRelease
+	//
+	// Gets a release
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Get a release
+	// tags:
+	// - Releases
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - name: namespace
+	//   - name: name
+	//   - name: version
+	// responses:
+	//   '201':
+	//     description: Successfully got the release
+	//     schema:
+	//       $ref: '#/definitions/GetReleaseResponse'
+	//   '403':
+	//     description: Forbidden
 	getEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
@@ -115,6 +199,23 @@ func getV1ReleaseRoutes(
 	})
 
 	// GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases -> namespace.NewListReleasesHandler
+	// swagger:operation GET /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases listReleases
+	//
+	// List releases
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: List releases
+	// tags:
+	// - Releases
+	// responses:
+	//   '201':
+	//     description: Successfully listed releases
+	//     schema:
+	//       $ref: '#/definitions/ListReleasesResponse'
+	//   '403':
+	//     description: Forbidden
 	listReleasesEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
@@ -146,6 +247,32 @@ func getV1ReleaseRoutes(
 
 	// PATCH /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version} ->
 	// release.NewUpgradeReleaseHandler
+	// swagger:operation PATCH /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version} updateRelease
+	//
+	// Updates a release
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Update a release
+	// tags:
+	// - Releases
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - name: namespace
+	//   - name: name
+	//   - name: version
+	//   - in: body
+	//     name: UpdateReleaseRequest
+	//     description: The release to update
+	//     schema:
+	//       $ref: '#/definitions/UpdateReleaseRequest'
+	// responses:
+	//   '200':
+	//     description: Successfully updated the release
+	//   '403':
+	//     description: Forbidden
 	upgradeEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbUpdate,
@@ -178,6 +305,27 @@ func getV1ReleaseRoutes(
 
 	// DELETE /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version} ->
 	// release.NewDeleteReleaseHandler
+	// swagger:operation DELETE /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version} deleteRelease
+	//
+	// Deletes a release
+	//
+	// ---
+	// produces:
+	// - application/json
+	// summary: Delete a release
+	// tags:
+	// - Releases
+	// parameters:
+	//   - name: project_id
+	//   - name: cluster_id
+	//   - name: namespace
+	//   - name: name
+	//   - name: version
+	// responses:
+	//   '200':
+	//     description: Successfully deleted the release
+	//   '403':
+	//     description: Forbidden
 	deleteEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbDelete,

+ 14 - 1
api/types/cluster.go

@@ -185,18 +185,31 @@ const (
 	AWSData          ClusterResolverName = "upload-aws-data"
 )
 
+// swagger:model
 type ListNamespacesResponse struct {
 	*v1.NamespaceList
 }
 
+// swagger:model
 type CreateNamespaceRequest struct {
 	Name string `json:"name" form:"required"`
 }
 
+// swagger:model
 type CreateNamespaceResponse struct {
-	*v1.Namespace
+	Metadata struct {
+		Name string `json:"name,omitempty"`
+	} `json:"metadata,omitempty"`
 }
 
+// swagger:model
+type GetNamespaceResponse struct {
+	Metadata struct {
+		Name string `json:"name,omitempty"`
+	} `json:"metadata,omitempty"`
+}
+
+// swagger:model
 type DeleteNamespaceRequest struct {
 	Name string `json:"name" form:"required"`
 }

+ 25 - 4
api/types/namespace.go

@@ -16,10 +16,30 @@ const (
 // ReleaseListFilter is a struct that represents the various filter options used for
 // retrieving the releases
 type ReleaseListFilter struct {
-	Namespace    string   `json:"namespace"`
-	Limit        int      `json:"limit"`
-	Skip         int      `json:"skip"`
-	ByDate       bool     `json:"byDate"`
+	// swagger:ignore
+	Namespace string `json:"namespace"`
+
+	// the pagination limit
+	//
+	// in: query
+	// example: 50
+	Limit int `json:"limit"`
+
+	// how many items to skip
+	//
+	// in: query
+	// example: 10
+	Skip int `json:"skip"`
+
+	// whether to sort by date
+	//
+	// in: query
+	// example: false
+	ByDate bool `json:"byDate"`
+
+	// which helm statuses to filter by
+	//
+	// in: query
 	StatusFilter []string `json:"statusFilter"`
 }
 
@@ -60,6 +80,7 @@ type ListReleasesRequest struct {
 	*ReleaseListFilter
 }
 
+// swagger:model
 type ListReleasesResponse []*release.Release
 
 type GetConfigMapRequest struct {

+ 11 - 0
api/types/registry.go

@@ -81,8 +81,10 @@ const (
 	DockerHub RegistryService = "dockerhub"
 )
 
+// swagger:model ListRegistriesResponse
 type RegistryListResponse []Registry
 
+// swagger:model
 type CreateRegistryRequest struct {
 	URL                string `json:"url"`
 	Name               string `json:"name" form:"required"`
@@ -97,6 +99,13 @@ type CreateRegistryRequest struct {
 	ACRName              string `json:"acr_name"`
 }
 
+// swagger:model
+type CreateRegistryResponse Registry
+
+// swagger:model
+type GetRegistryResponse Registry
+
+// swagger:model
 type CreateRegistryRepositoryRequest struct {
 	ImageRepoURI string `json:"image_repo_uri" form:"required"`
 }
@@ -125,6 +134,8 @@ type GetRegistryDOCRTokenRequest struct {
 	ServerURL string `schema:"server_url"`
 }
 
+// swagger:model ListRegistryRepositoriesResponse
 type ListRegistryRepositoryResponse []*RegistryRepository
 
+// swagger:model ListImagesResponse
 type ListImageResponse []*Image

+ 4 - 1
api/types/release.go

@@ -24,6 +24,7 @@ type PorterRelease struct {
 	Tags            []string         `json:"tags,omitempty"`
 }
 
+// swagger:model
 type GetReleaseResponse Release
 
 type UpdateNotificationConfigRequest struct {
@@ -35,13 +36,14 @@ type UpdateNotificationConfigRequest struct {
 }
 
 type CreateReleaseBaseRequest struct {
-	RepoURL         string                 `schema:"repo_url"`
+	RepoURL         string                 `json:"-" schema:"repo_url"`
 	TemplateName    string                 `json:"template_name" form:"required"`
 	TemplateVersion string                 `json:"template_version" form:"required"`
 	Values          map[string]interface{} `json:"values"`
 	Name            string                 `json:"name" form:"required"`
 }
 
+// swagger:model
 type CreateReleaseRequest struct {
 	*CreateReleaseBaseRequest
 
@@ -62,6 +64,7 @@ type RollbackReleaseRequest struct {
 	Revision int `json:"revision" form:"required"`
 }
 
+// swagger:model UpdateReleaseRequest
 type UpgradeReleaseRequest struct {
 	Values       string `json:"values" form:"required"`
 	ChartVersion string `json:"version"`

+ 2 - 0
cmd/app/main.go

@@ -1,3 +1,5 @@
+//go:generate swagger generate spec
+
 package main
 
 import (

+ 1 - 0
scripts/build/generate-spec.sh

@@ -0,0 +1 @@
+swagger generate spec --scan-models --include github.com/porter-dev/porter --work-dir ./cmd/app/ --output openapi.yaml