diff --git a/api/openapispec/docs.go b/api/openapispec/docs.go index f7291295..6cb1e249 100644 --- a/api/openapispec/docs.go +++ b/api/openapispec/docs.go @@ -2281,7 +2281,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/v1.Spec" + "type": "string" } }, "400": { @@ -2350,7 +2350,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/v1.Spec" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Spec" } }, "400": { @@ -2471,22 +2471,49 @@ const docTemplate = `{ } } }, - "/api/v1/workspaces": { + "/api/v1/variable-labels": { "get": { - "description": "List all workspaces", + "description": "List variable labels", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable_labels" + ], + "summary": "List variable labels", + "operationId": "listVariableLabels", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Variable labels to filter variables by. Default to all(empty) labels.", + "name": "labels", + "in": "query" + }, + { + "type": "string", + "description": "Page number of the paginated list results. Default to 1.", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "Page size of the paginated list results. If not set, the result won't be paginated.", + "name": "pageSize", + "in": "query" + } ], - "summary": "List workspaces", - "operationId": "listWorkspace", "responses": { "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "type": "array", + "items": { + "$ref": "#/definitions/entity.VariableLabelsListResult" + } } }, "400": { @@ -2512,7 +2539,7 @@ const docTemplate = `{ } }, "post": { - "description": "Create a new workspace", + "description": "Create a new set of variable labels", "consumes": [ "application/json" ], @@ -2520,18 +2547,18 @@ const docTemplate = `{ "application/json" ], "tags": [ - "workspace" + "variable_labels" ], - "summary": "Create workspace", - "operationId": "createWorkspace", + "summary": "Create variable labels", + "operationId": "createVariableLabels", "parameters": [ { - "description": "Created workspace", - "name": "workspace", + "description": "Created variable labels", + "name": "variable_labels", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.CreateWorkspaceRequest" + "$ref": "#/definitions/request.CreateVariableLabelsRequest" } } ], @@ -2539,7 +2566,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "$ref": "#/definitions/entity.VariableLabels" } }, "400": { @@ -2565,9 +2592,57 @@ const docTemplate = `{ } } }, - "/api/v1/workspaces/configs/validate": { - "post": { - "description": "Validate the configurations in the specified workspace", + "/api/v1/variable-labels/{key}": { + "get": { + "description": "Get variable labels by variable key", + "produces": [ + "application/json" + ], + "tags": [ + "variable_labels" + ], + "summary": "Get variable labels", + "operationId": "getVariableLabels", + "parameters": [ + { + "type": "string", + "description": "Variable Key", + "name": "key", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.VariableLabels" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "put": { + "description": "Update the specified variable labels", "consumes": [ "application/json" ], @@ -2575,18 +2650,25 @@ const docTemplate = `{ "application/json" ], "tags": [ - "workspace" + "variable_labels" ], - "summary": "Validate workspace configurations", - "operationId": "validateWorkspaceConfigs", + "summary": "Update variable labels", + "operationId": "updateVariableLabels", "parameters": [ { - "description": "Workspace configurations to be validated", - "name": "workspace", + "type": "string", + "description": "Variable Key", + "name": "key", + "in": "path", + "required": true + }, + { + "description": "Updated Variable Labels", + "name": "variable_labels", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/request.UpdateVariableLabelsRequest" } } ], @@ -2594,7 +2676,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/entity.VariableLabels" } }, "400": { @@ -2618,24 +2700,22 @@ const docTemplate = `{ "schema": {} } } - } - }, - "/api/v1/workspaces/{id}": { - "get": { - "description": "Get workspace information by workspace ID", + }, + "delete": { + "description": "Delete a specified variable with labels", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable_labels" ], - "summary": "Get workspace", - "operationId": "getWorkspace", + "summary": "Delete variable labels", + "operationId": "deleteVariableLabels", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Key", + "name": "key", "in": "path", "required": true } @@ -2644,7 +2724,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "type": "string" } }, "400": { @@ -2668,35 +2748,27 @@ const docTemplate = `{ "schema": {} } } - }, - "put": { - "description": "Update the specified workspace", - "consumes": [ - "application/json" - ], + } + }, + "/api/v1/variables": { + "get": { + "description": "List variables", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Update workspace", - "operationId": "updateWorkspace", + "summary": "List variables", + "operationId": "listVariables", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Updated workspace", - "name": "workspace", + "description": "Variable labels to filter variables by.", + "name": "variable", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.UpdateWorkspaceRequest" + "$ref": "#/definitions/request.ListVariableSetRequest" } } ], @@ -2704,7 +2776,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "$ref": "#/definitions/entity.VariableLabelsListResult" } }, "400": { @@ -2729,30 +2801,35 @@ const docTemplate = `{ } } }, - "delete": { - "description": "Delete specified workspace by ID", + "post": { + "description": "Create a new variable", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Delete workspace", - "operationId": "deleteWorkspace", + "summary": "Create variable", + "operationId": "createVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", - "in": "path", - "required": true + "description": "Created variable", + "name": "variable", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CreateVariableSetRequest" + } } ], "responses": { "200": { "description": "Success", "schema": { - "type": "string" + "$ref": "#/definitions/entity.Variable" } }, "400": { @@ -2778,25 +2855,22 @@ const docTemplate = `{ } } }, - "/api/v1/workspaces/{id}/configs": { + "/api/v1/variables/{fqn}": { "get": { - "description": "Get configurations in the specified workspace", - "consumes": [ - "application/json" - ], + "description": "Get variable by variable fqn", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "get workspace configurations", - "operationId": "getWorkspaceConfigs", + "summary": "Get variable", + "operationId": "getVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Fqn", + "name": "fqn", "in": "path", "required": true } @@ -2805,7 +2879,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/entity.Variable" } }, "400": { @@ -2831,7 +2905,7 @@ const docTemplate = `{ } }, "put": { - "description": "Update the configurations in the specified workspace", + "description": "Update the specified variable", "consumes": [ "application/json" ], @@ -2839,25 +2913,25 @@ const docTemplate = `{ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Update workspace configurations", - "operationId": "updateWorkspaceConfigs", + "summary": "Update variable", + "operationId": "updateVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Fqn", + "name": "fqn", "in": "path", "required": true }, { - "description": "Updated workspace configurations", - "name": "workspace", + "description": "Updated Variable", + "name": "variable", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/request.UpdateVariableRequest" } } ], @@ -2865,7 +2939,7 @@ const docTemplate = `{ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/entity.Variable" } }, "400": { @@ -2889,27 +2963,22 @@ const docTemplate = `{ "schema": {} } } - } - }, - "/api/v1/workspaces/{id}/configs/mod-deps": { - "post": { - "description": "Create the module dependencies in kcl.mod of the specified workspace", - "consumes": [ - "application/json" - ], + }, + "delete": { + "description": "Delete a specified variable with fqn", "produces": [ - "text/plain" + "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Create the module dependencies of the workspace", - "operationId": "createWorkspaceModDeps", + "summary": "Delete variable", + "operationId": "deleteVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Fqn", + "name": "fqn", "in": "path", "required": true } @@ -2944,54 +3013,527 @@ const docTemplate = `{ } } }, - "/endpoints": { + "/api/v1/workspaces": { "get": { - "description": "List all registered endpoints in the router", - "consumes": [ - "text/plain" - ], + "description": "List all workspaces", "produces": [ - "text/plain" + "application/json" ], "tags": [ - "debug" + "workspace" ], - "summary": "List all available endpoints", + "summary": "List workspaces", + "operationId": "listWorkspace", "responses": { "200": { - "description": "Endpoints listed successfully", + "description": "Success", "schema": { - "type": "string" + "$ref": "#/definitions/entity.Workspace" } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} } } - } - } - }, - "definitions": { - "constant.RunStatus": { - "type": "string", - "enum": [ - "Scheduling", - "InProgress", - "Failed", - "Succeeded", - "Cancelled", - "Queued" - ], - "x-enum-varnames": [ - "RunStatusScheduling", - "RunStatusInProgress", - "RunStatusFailed", - "RunStatusSucceeded", - "RunStatusCancelled", - "RunStatusQueued" - ] - }, - "constant.RunType": { - "type": "string", - "enum": [ - "Generate", + }, + "post": { + "description": "Create a new workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Create workspace", + "operationId": "createWorkspace", + "parameters": [ + { + "description": "Created workspace", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CreateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.Workspace" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/configs/validate": { + "post": { + "description": "Validate the configurations in the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Validate workspace configurations", + "operationId": "validateWorkspaceConfigs", + "parameters": [ + { + "description": "Workspace configurations to be validated", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/{id}": { + "get": { + "description": "Get workspace information by workspace ID", + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Get workspace", + "operationId": "getWorkspace", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.Workspace" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "put": { + "description": "Update the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Update workspace", + "operationId": "updateWorkspace", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Updated workspace", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.Workspace" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "delete": { + "description": "Delete specified workspace by ID", + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Delete workspace", + "operationId": "deleteWorkspace", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/{id}/configs": { + "get": { + "description": "Get configurations in the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "get workspace configurations", + "operationId": "getWorkspaceConfigs", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "put": { + "description": "Update the configurations in the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Update workspace configurations", + "operationId": "updateWorkspaceConfigs", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Updated workspace configurations", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/{id}/configs/mod-deps": { + "post": { + "description": "Create the module dependencies in kcl.mod of the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "text/plain" + ], + "tags": [ + "workspace" + ], + "summary": "Create the module dependencies of the workspace", + "operationId": "createWorkspaceModDeps", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/endpoints": { + "get": { + "description": "List all registered endpoints in the router", + "consumes": [ + "text/plain" + ], + "produces": [ + "text/plain" + ], + "tags": [ + "debug" + ], + "summary": "List all available endpoints", + "responses": { + "200": { + "description": "Endpoints listed successfully", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "constant.RunStatus": { + "type": "string", + "enum": [ + "Scheduling", + "InProgress", + "Failed", + "Succeeded", + "Cancelled", + "Queued" + ], + "x-enum-varnames": [ + "RunStatusScheduling", + "RunStatusInProgress", + "RunStatusFailed", + "RunStatusSucceeded", + "RunStatusCancelled", + "RunStatusQueued" + ] + }, + "constant.RunType": { + "type": "string", + "enum": [ + "Generate", "Preview", "Apply", "Destroy" @@ -3003,650 +3545,1091 @@ const docTemplate = `{ "RunTypeDestroy" ] }, - "constant.SourceProviderType": { - "type": "string", - "enum": [ - "git", - "git", - "github", - "oci", - "local" - ], - "x-enum-varnames": [ - "DefaultSourceType", - "SourceProviderTypeGit", - "SourceProviderTypeGithub", - "SourceProviderTypeOCI", - "SourceProviderTypeLocal" - ] + "constant.SourceProviderType": { + "type": "string", + "enum": [ + "git", + "git", + "github", + "oci", + "local" + ], + "x-enum-varnames": [ + "DefaultSourceType", + "SourceProviderTypeGit", + "SourceProviderTypeGithub", + "SourceProviderTypeOCI", + "SourceProviderTypeLocal" + ] + }, + "constant.StackState": { + "type": "string", + "enum": [ + "UnSynced", + "Synced", + "OutOfSync", + "Creating", + "Generating", + "GenerateFailed", + "Generated", + "Previewing", + "PreviewFailed", + "Previewed", + "Applying", + "ApplyFailed", + "ApplySucceeded", + "Destroying", + "DestroyFailed", + "DestroySucceeded" + ], + "x-enum-varnames": [ + "StackStateUnSynced", + "StackStateSynced", + "StackStateOutOfSync", + "StackStateCreating", + "StackStateGenerating", + "StackStateGenerateFailed", + "StackStateGenerated", + "StackStatePreviewing", + "StackStatePreviewFailed", + "StackStatePreviewed", + "StackStateApplying", + "StackStateApplyFailed", + "StackStateApplySucceeded", + "StackStateDestroying", + "StackStateDestroyFailed", + "StackStateDestroySucceeded" + ] + }, + "entity.Backend": { + "type": "object", + "properties": { + "backendConfig": { + "description": "// Type is the type of the backend.\nType string ` + "`" + `yaml:\"type\" json:\"type\"` + "`" + `\nBackend is the configuration of the backend.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig" + } + ] + }, + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the backend.", + "type": "string" + }, + "description": { + "description": "Description is a human-readable description of the backend.", + "type": "string" + }, + "id": { + "description": "ID is the id of the backend.", + "type": "integer" + }, + "name": { + "description": "Name is the name of the backend.", + "type": "string" + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the backend.", + "type": "string" + } + } + }, + "entity.Module": { + "type": "object", + "properties": { + "description": { + "description": "Description is a human-readable description of the module.", + "type": "string" + }, + "doc": { + "description": "Doc is the documentation URL of the module.", + "allOf": [ + { + "$ref": "#/definitions/url.URL" + } + ] + }, + "name": { + "description": "Name is the module name.", + "type": "string" + }, + "owners": { + "description": "Owners is a list of owners for the module.", + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "description": "URL is the module oci artifact registry URL.", + "allOf": [ + { + "$ref": "#/definitions/url.URL" + } + ] + } + } + }, + "entity.Organization": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the organization.", + "type": "string" + }, + "description": { + "description": "Description is a human-readable description of the organization.", + "type": "string" + }, + "displayName": { + "description": "DisplayName is the human-readable display name.", + "type": "string" + }, + "id": { + "description": "ID is the id of the organization.", + "type": "integer" + }, + "labels": { + "description": "Labels are custom labels associated with the organization.", + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "description": "Name is the name of the organization.", + "type": "string" + }, + "owners": { + "description": "Owners is a list of owners for the organization.", + "type": "array", + "items": { + "type": "string" + } + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the organization.", + "type": "string" + } + } + }, + "entity.Project": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the project.", + "type": "string" + }, + "description": { + "description": "Description is a human-readable description of the project.", + "type": "string" + }, + "displayName": { + "description": "DisplayName is the human-readable display name.", + "type": "string" + }, + "id": { + "description": "ID is the id of the project.", + "type": "integer" + }, + "labels": { + "description": "Labels are custom labels associated with the project.", + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "description": "Name is the name of the project.", + "type": "string" + }, + "organization": { + "description": "Organization is the configuration source associated with the project.", + "allOf": [ + { + "$ref": "#/definitions/entity.Organization" + } + ] + }, + "owners": { + "description": "Owners is a list of owners for the project.", + "type": "array", + "items": { + "type": "string" + } + }, + "path": { + "description": "Path is the relative path of the project within the sources.", + "type": "string" + }, + "source": { + "description": "Source is the configuration source associated with the project.", + "allOf": [ + { + "$ref": "#/definitions/entity.Source" + } + ] + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the project.", + "type": "string" + } + } }, - "constant.StackState": { - "type": "string", - "enum": [ - "UnSynced", - "Synced", - "OutOfSync", - "Creating", - "Generating", - "GenerateFailed", - "Generated", - "Previewing", - "PreviewFailed", - "Previewed", - "Applying", - "ApplyFailed", - "ApplySucceeded", - "Destroying", - "DestroyFailed", - "DestroySucceeded" - ], - "x-enum-varnames": [ - "StackStateUnSynced", - "StackStateSynced", - "StackStateOutOfSync", - "StackStateCreating", - "StackStateGenerating", - "StackStateGenerateFailed", - "StackStateGenerated", - "StackStatePreviewing", - "StackStatePreviewFailed", - "StackStatePreviewed", - "StackStateApplying", - "StackStateApplyFailed", - "StackStateApplySucceeded", - "StackStateDestroying", - "StackStateDestroyFailed", - "StackStateDestroySucceeded" - ] + "entity.Resource": { + "type": "object", + "properties": { + "LastAppliedRevision": { + "description": "LastAppliedRevision is the revision of the last sync.", + "type": "string" + }, + "LastAppliedTimestamp": { + "description": "LastAppliedTimestamp is the timestamp of the last sync.", + "type": "string" + }, + "attributes": { + "description": "Attributes is the attributes of the resource.", + "type": "object", + "additionalProperties": true + }, + "cloudResourceID": { + "description": "CloudResourceID is the id of the resource in the cloud.", + "type": "string" + }, + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the resource.", + "type": "string" + }, + "dependsOn": { + "description": "DependsOn is the depends on of the resource.", + "type": "array", + "items": { + "type": "string" + } + }, + "extensions": { + "description": "Extensions is the extensions of the resource.", + "type": "object", + "additionalProperties": true + }, + "iamResourceID": { + "description": "IAMResourceID is the id of the resource in IAM.", + "type": "string" + }, + "id": { + "description": "ID is the id of the resource.", + "type": "integer" + }, + "kusionResourceID": { + "description": "KusionResourceID is the id of the resource in Kusion.", + "type": "string" + }, + "labels": { + "description": "Labels are custom labels associated with the resource.", + "type": "array", + "items": { + "type": "string" + } + }, + "owners": { + "description": "Owners is a list of owners for the resource.", + "type": "array", + "items": { + "type": "string" + } + }, + "provider": { + "description": "Provider is the provider of the resource.", + "type": "string" + }, + "resourceName": { + "description": "ResourceName is the name of the resource.", + "type": "string" + }, + "resourcePlane": { + "description": "ResourcePlane is the plane of the resource.", + "type": "string" + }, + "resourceType": { + "description": "ResourceType is the type of the resource.", + "type": "string" + }, + "stack": { + "description": "Stack is the stack associated with the resource.", + "allOf": [ + { + "$ref": "#/definitions/entity.Stack" + } + ] + }, + "status": { + "description": "Status is the status of the resource.", + "type": "string" + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the resource.", + "type": "string" + } + } + }, + "entity.ResourceGraph": { + "type": "object", + "properties": { + "relations": { + "type": "array", + "items": { + "$ref": "#/definitions/entity.ResourceRelation" + } + }, + "resources": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/entity.ResourceInfo" + } + }, + "workload": { + "type": "string" + } + } }, - "entity.Backend": { + "entity.ResourceInfo": { "type": "object", "properties": { - "backendConfig": { - "description": "// Type is the type of the backend.\nType string ` + "`" + `yaml:\"type\" json:\"type\"` + "`" + `\nBackend is the configuration of the backend.", - "allOf": [ - { - "$ref": "#/definitions/v1.BackendConfig" - } - ] + "cloudResourceID": { + "description": "CloudResourceID is the id of the resource in the cloud.", + "type": "string" }, - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the backend.", + "iamResourceID": { + "description": "IAMResourceID is the id of the resource in IAM.", "type": "string" }, - "description": { - "description": "Description is a human-readable description of the backend.", + "resourceName": { + "description": "ResourceName is the name of the resource.", "type": "string" }, - "id": { - "description": "ID is the id of the backend.", - "type": "integer" + "resourcePlane": { + "description": "ResourcePlane is the plane of the resource.", + "type": "string" }, - "name": { - "description": "Name is the name of the backend.", + "resourceType": { + "description": "ResourceType is the type of the resource.", "type": "string" }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the backend.", + "status": { + "description": "Status is the status of the resource.", "type": "string" } } }, - "entity.Module": { + "entity.ResourceRelation": { "type": "object", "properties": { - "description": { - "description": "Description is a human-readable description of the module.", + "dependencyResource": { "type": "string" }, - "doc": { - "description": "Doc is the documentation URL of the module.", + "dependentResource": { + "type": "string" + } + } + }, + "entity.Run": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the run.", + "type": "string" + }, + "id": { + "description": "ID is the id of the run.", + "type": "integer" + }, + "logs": { + "description": "Logs is the logs of the run.", + "type": "string" + }, + "result": { + "description": "Result is the result of the run.", + "type": "string" + }, + "stack": { + "description": "Stack is the stack of the run.", "allOf": [ { - "$ref": "#/definitions/url.URL" + "$ref": "#/definitions/entity.Stack" } ] }, - "name": { - "description": "Name is the module name.", - "type": "string" + "status": { + "description": "Status is the status of the run.", + "allOf": [ + { + "$ref": "#/definitions/constant.RunStatus" + } + ] }, - "owners": { - "description": "Owners is a list of owners for the module.", - "type": "array", - "items": { - "type": "string" - } + "trace": { + "description": "Trace is the trace of the run.", + "type": "string" }, - "url": { - "description": "URL is the module oci artifact registry URL.", + "type": { + "description": "RunType is the type of the run provider.", "allOf": [ { - "$ref": "#/definitions/url.URL" + "$ref": "#/definitions/constant.RunType" } ] + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the run.", + "type": "string" + }, + "workspace": { + "description": "Workspace is the target workspace of the run.", + "type": "string" } } }, - "entity.Organization": { + "entity.SecretStore": { "type": "object", "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the organization.", + "provider": { + "type": "object", + "additionalProperties": {} + }, + "providerType": { + "type": "string" + } + } + }, + "entity.SecretValue": { + "type": "object", + "properties": { + "ref": { + "description": "Ref will only return with the update secret variable", "type": "string" }, - "description": { - "description": "Description is a human-readable description of the organization.", + "secretStore": { + "$ref": "#/definitions/entity.SecretStore" + }, + "value": { + "description": "Value to store in the secret store.", + "type": "string" + } + } + }, + "entity.Source": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the source.", "type": "string" }, - "displayName": { - "description": "DisplayName is the human-readable display name.", + "description": { + "description": "Description is a human-readable description of the source.", "type": "string" }, "id": { - "description": "ID is the id of the organization.", + "description": "ID is the id of the source.", "type": "integer" }, "labels": { - "description": "Labels are custom labels associated with the organization.", + "description": "Labels are custom labels associated with the source.", "type": "array", "items": { "type": "string" } }, "name": { - "description": "Name is the name of the organization.", + "description": "Name is the name of the source.", "type": "string" }, "owners": { - "description": "Owners is a list of owners for the organization.", + "description": "Owners is a list of owners for the source.", "type": "array", "items": { "type": "string" } }, + "remote": { + "description": "Remote is the source URL, including scheme.", + "allOf": [ + { + "$ref": "#/definitions/url.URL" + } + ] + }, + "sourceProvider": { + "description": "SourceProvider is the type of the source provider.", + "allOf": [ + { + "$ref": "#/definitions/constant.SourceProviderType" + } + ] + }, "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the organization.", + "description": "UpdateTimestamp is the timestamp of the updated for the source.", "type": "string" } } }, - "entity.Project": { + "entity.Stack": { "type": "object", "properties": { "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the project.", + "description": "CreationTimestamp is the timestamp of the created for the stack.", "type": "string" }, "description": { - "description": "Description is a human-readable description of the project.", + "description": "Description is a human-readable description of the stack.", + "type": "string" + }, + "desiredVersion": { + "description": "Desired is the desired version of stack.", "type": "string" }, "displayName": { - "description": "DisplayName is the human-readable display name.", + "description": "DisplayName is the human-readable display nams.", "type": "string" }, "id": { - "description": "ID is the id of the project.", + "description": "ID is the id of the stack.", "type": "integer" }, "labels": { - "description": "Labels are custom labels associated with the project.", + "description": "Labels are custom labels associated with the stack.", "type": "array", "items": { "type": "string" } }, - "name": { - "description": "Name is the name of the project.", + "lastAppliedRevision": { + "description": "LastAppliedRevision is the spec ID of the last apply operation for the stack.", "type": "string" }, - "organization": { - "description": "Organization is the configuration source associated with the project.", - "allOf": [ - { - "$ref": "#/definitions/entity.Organization" - } - ] + "lastAppliedTimestamp": { + "description": "LastAppliedTimestamp is the timestamp of the last apply operation for the stack.", + "type": "string" + }, + "lastGeneratedRevision": { + "description": "LastGeneratedRevision is the spec ID of the last generate operation for the stack.", + "type": "string" + }, + "lastPreviewedRevision": { + "description": "LastPreviewedRevision is the spec ID of the last preview operation for the stack.", + "type": "string" + }, + "name": { + "description": "Name is the name of the stack.", + "type": "string" }, "owners": { - "description": "Owners is a list of owners for the project.", + "description": "Owners is a list of owners for the stack.", "type": "array", "items": { "type": "string" } }, "path": { - "description": "Path is the relative path of the project within the sources.", + "description": "Path is the relative path of the stack within the sourcs.", "type": "string" }, - "source": { - "description": "Source is the configuration source associated with the project.", + "project": { + "description": "Project is the project associated with the stack.", "allOf": [ { - "$ref": "#/definitions/entity.Source" + "$ref": "#/definitions/entity.Project" + } + ] + }, + "syncState": { + "description": "SyncState is the current state of the stack.", + "allOf": [ + { + "$ref": "#/definitions/constant.StackState" } ] }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the project.", + "type": { + "description": "Type is the type of the stack.", + "type": "string" + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the stack.", + "type": "string" + } + } + }, + "entity.Variable": { + "type": "object", + "properties": { + "fqn": { + "description": "Fqn is the fully qualified name of the variable.", + "type": "string" + }, + "labels": { + "description": "Labels clarifies the scope of the variable.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "type": { + "description": "Type is the type of the variable.", + "type": "string" + }, + "value": { + "description": "Value is the value of the variable.", + "type": "string" + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", "type": "string" } } }, - "entity.Resource": { + "entity.VariableLabels": { "type": "object", "properties": { - "LastAppliedRevision": { - "description": "LastAppliedRevision is the revision of the last sync.", - "type": "string" - }, - "LastAppliedTimestamp": { - "description": "LastAppliedTimestamp is the timestamp of the last sync.", - "type": "string" - }, - "attributes": { - "description": "Attributes is the attributes of the resource.", - "type": "object", - "additionalProperties": true - }, - "cloudResourceID": { - "description": "CloudResourceID is the id of the resource in the cloud.", - "type": "string" + "labels": { + "description": "Labels is the list of variable labels, which should be sorted\nin ascending order of priority.", + "type": "array", + "items": { + "type": "string" + } }, - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the resource.", + "variableKey": { + "description": "VariableKey is the access path for the variable.", "type": "string" + } + } + }, + "entity.VariableLabelsListResult": { + "type": "object", + "properties": { + "total": { + "type": "integer" }, - "dependsOn": { - "description": "DependsOn is the depends on of the resource.", + "variableLabels": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/entity.VariableLabels" } + } + } + }, + "entity.Workspace": { + "type": "object", + "properties": { + "backend": { + "description": "Backend is the corresponding backend for this workspace.", + "allOf": [ + { + "$ref": "#/definitions/entity.Backend" + } + ] }, - "extensions": { - "description": "Extensions is the extensions of the resource.", - "type": "object", - "additionalProperties": true + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the workspace.", + "type": "string" }, - "iamResourceID": { - "description": "IAMResourceID is the id of the resource in IAM.", + "description": { + "description": "Description is a human-readable description of the workspace.", + "type": "string" + }, + "displayName": { + "description": "DisplayName is the human-readable display name.", "type": "string" }, "id": { - "description": "ID is the id of the resource.", + "description": "ID is the id of the workspace.", "type": "integer" }, - "kusionResourceID": { - "description": "KusionResourceID is the id of the resource in Kusion.", - "type": "string" - }, "labels": { - "description": "Labels are custom labels associated with the resource.", + "description": "Labels are custom labels associated with the workspace.", "type": "array", "items": { "type": "string" } }, + "name": { + "description": "Name is the name of the workspace.", + "type": "string" + }, "owners": { - "description": "Owners is a list of owners for the resource.", + "description": "Owners is a list of owners for the workspace.", "type": "array", "items": { "type": "string" } }, - "provider": { - "description": "Provider is the provider of the resource.", + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the workspace.", "type": "string" - }, - "resourceName": { - "description": "ResourceName is the name of the resource.", + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AWSProvider": { + "type": "object", + "properties": { + "profile": { + "description": "The profile to be used to interact with AWS Secrets Manager.\nIf not set, the default profile created with ` + "`" + `aws configure` + "`" + ` will be used.", "type": "string" }, - "resourcePlane": { - "description": "ResourcePlane is the plane of the resource.", + "region": { + "description": "AWS Region to be used to interact with AWS Secrets Manager.\nExamples are us-east-1, us-west-2, etc.", "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource.", + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AlicloudProvider": { + "type": "object", + "properties": { + "region": { + "description": "Alicloud Region to be used to interact with Alicloud Secrets Manager.\nExamples are cn-beijing, cn-shanghai, etc.", "type": "string" - }, - "stack": { - "description": "Stack is the stack associated with the resource.", + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureEnvironmentType": { + "type": "string", + "enum": [ + "PublicCloud", + "USGovernmentCloud", + "ChinaCloud", + "GermanCloud" + ], + "x-enum-varnames": [ + "AzureEnvironmentPublicCloud", + "AzureEnvironmentUSGovernmentCloud", + "AzureEnvironmentChinaCloud", + "AzureEnvironmentGermanCloud" + ] + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureKVProvider": { + "type": "object", + "properties": { + "environmentType": { + "description": "EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure.\nBy-default it points to the public cloud AAD endpoint, and the following endpoints are available:\nPublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\nRef: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152", "allOf": [ { - "$ref": "#/definitions/entity.Stack" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureEnvironmentType" } ] }, - "status": { - "description": "Status is the status of the resource.", + "tenantId": { + "description": "TenantID configures the Azure Tenant to send requests to.", "type": "string" }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the resource.", + "vaultUrl": { + "description": "Vault Url from which the secrets to be fetched from.", "type": "string" } } }, - "entity.ResourceGraph": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig": { "type": "object", "properties": { - "relations": { - "type": "array", - "items": { - "$ref": "#/definitions/entity.ResourceRelation" - } - }, - "resources": { + "configs": { + "description": "Configs contains config items of the backend, whose keys differ from different backend types.", "type": "object", - "additionalProperties": { - "$ref": "#/definitions/entity.ResourceInfo" - } + "additionalProperties": {} }, - "workload": { + "type": { + "description": "Type is the backend type, supports BackendTypeLocal, BackendTypeOss, BackendTypeS3.", "type": "string" } } }, - "entity.ResourceInfo": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Configs": { "type": "object", "properties": { - "cloudResourceID": { - "description": "CloudResourceID is the id of the resource in the cloud.", + "default": { + "description": "Default is default block of the module config.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig" + } + ] + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProvider": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProviderData" + } + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProviderData": { + "type": "object", + "properties": { + "key": { "type": "string" }, - "iamResourceID": { - "description": "IAMResourceID is the id of the resource in IAM.", + "value": { "type": "string" }, - "resourceName": { - "description": "ResourceName is the name of the resource.", - "type": "string" + "valueMap": { + "type": "object", + "additionalProperties": { + "type": "string" + } }, - "resourcePlane": { - "description": "ResourcePlane is the plane of the resource.", + "version": { "type": "string" + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig": { + "type": "object", + "additionalProperties": {} + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfig": { + "type": "object", + "properties": { + "configs": { + "description": "Configs contains all levels of module configs", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Configs" + } + ] }, - "resourceType": { - "description": "ResourceType is the type of the resource.", + "path": { + "description": "Path is the path of the module. It can be a local path or a remote URL", "type": "string" }, - "status": { - "description": "Status is the status of the resource.", + "version": { + "description": "Version is the version of the module.", "type": "string" } } }, - "entity.ResourceRelation": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfigs": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfig" + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModulePatcherConfig": { "type": "object", "properties": { - "dependencyResource": { - "type": "string" - }, - "dependentResource": { - "type": "string" + "projectSelector": { + "description": "ProjectSelector contains the selected projects.", + "type": "array", + "items": { + "type": "string" + } } } }, - "entity.Run": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.OnPremisesProvider": { "type": "object", "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the run.", - "type": "string" - }, - "id": { - "description": "ID is the id of the run.", - "type": "integer" - }, - "logs": { - "description": "Result RunResult ` + "`" + `yaml:\"result\" json:\"result\"` + "`" + `\nLogs is the logs of the run.", - "type": "string" - }, - "result": { - "description": "Result is the result of the run.", - "type": "string" + "attributes": { + "description": "attributes of the provider", + "type": "object", + "additionalProperties": { + "type": "string" + } }, - "stack": { - "description": "Stack is the stack of the run.", + "name": { + "description": "platform name of the provider", + "type": "string" + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ProviderSpec": { + "type": "object", + "properties": { + "alicloud": { + "description": "Alicloud configures a store to retrieve secrets from Alicloud Secrets Manager.", "allOf": [ { - "$ref": "#/definitions/entity.Stack" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AlicloudProvider" } ] }, - "status": { - "description": "Status is the status of the run.", + "aws": { + "description": "AWS configures a store to retrieve secrets from AWS Secrets Manager.", "allOf": [ { - "$ref": "#/definitions/constant.RunStatus" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AWSProvider" } ] }, - "type": { - "description": "RunType is the type of the run provider.", + "azure": { + "description": "Azure configures a store to retrieve secrets from Azure KeyVault.", "allOf": [ { - "$ref": "#/definitions/constant.RunType" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureKVProvider" } ] }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the run.", - "type": "string" - }, - "workspace": { - "description": "Workspace is the target workspace of the run.", - "type": "string" - } - } - }, - "entity.Source": { - "type": "object", - "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the source.", - "type": "string" - }, - "description": { - "description": "Description is a human-readable description of the source.", - "type": "string" - }, - "id": { - "description": "ID is the id of the source.", - "type": "integer" - }, - "labels": { - "description": "Labels are custom labels associated with the source.", - "type": "array", - "items": { - "type": "string" - } - }, - "name": { - "description": "Name is the name of the source.", - "type": "string" - }, - "owners": { - "description": "Owners is a list of owners for the source.", - "type": "array", - "items": { - "type": "string" - } + "fake": { + "description": "Fake configures a store with static key/value pairs", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProvider" + } + ] }, - "remote": { - "description": "Remote is the source URL, including scheme.", + "onpremises": { + "description": "Onprem configures a store in on-premises environments", "allOf": [ { - "$ref": "#/definitions/url.URL" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.OnPremisesProvider" } ] }, - "sourceProvider": { - "description": "SourceProvider is the type of the source provider.", + "vault": { + "description": "Vault configures a store to retrieve secrets from HashiCorp Vault.", "allOf": [ { - "$ref": "#/definitions/constant.SourceProviderType" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultProvider" } ] }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the source.", - "type": "string" + "viettelcloud": { + "description": "ViettelCloud configures a store to retrieve secrets from ViettelCloud Secrets Manager.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ViettelCloudProvider" + } + ] } } }, - "entity.Stack": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Resource": { "type": "object", "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the stack.", - "type": "string" - }, - "description": { - "description": "Description is a human-readable description of the stack.", - "type": "string" - }, - "desiredVersion": { - "description": "Desired is the desired version of stack.", - "type": "string" - }, - "displayName": { - "description": "DisplayName is the human-readable display nams.", - "type": "string" - }, - "id": { - "description": "ID is the id of the stack.", - "type": "integer" + "attributes": { + "description": "Attributes represents all specified attributes of this resource", + "type": "object", + "additionalProperties": true }, - "labels": { - "description": "Labels are custom labels associated with the stack.", + "dependsOn": { + "description": "DependsOn contains all resources this resource depends on", "type": "array", "items": { "type": "string" } }, - "lastAppliedRevision": { - "description": "LastAppliedRevision is the spec ID of the last apply operation for the stack.", - "type": "string" - }, - "lastAppliedTimestamp": { - "description": "LastAppliedTimestamp is the timestamp of the last apply operation for the stack.", - "type": "string" - }, - "lastGeneratedRevision": { - "description": "LastGeneratedRevision is the spec ID of the last generate operation for the stack.", - "type": "string" - }, - "lastPreviewedRevision": { - "description": "LastPreviewedRevision is the spec ID of the last preview operation for the stack.", - "type": "string" - }, - "name": { - "description": "Name is the name of the stack.", - "type": "string" - }, - "owners": { - "description": "Owners is a list of owners for the stack.", - "type": "array", - "items": { - "type": "string" - } + "extensions": { + "description": "Extensions specifies arbitrary metadata of this resource", + "type": "object", + "additionalProperties": true }, - "path": { - "description": "Path is the relative path of the stack within the sourcs.", + "id": { + "description": "ID is the unique key of this resource.\nApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources.\nproviderNamespace:providerName:resourceType:resourceName for Terraform resources", "type": "string" }, - "project": { - "description": "Project is the project associated with the stack.", - "allOf": [ - { - "$ref": "#/definitions/entity.Project" - } - ] - }, - "syncState": { - "description": "SyncState is the current state of the stack.", + "type": { + "description": "Type represents all Context we supported like Kubernetes and Terraform", "allOf": [ { - "$ref": "#/definitions/constant.StackState" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type" } ] - }, - "type": { - "description": "Type is the type of the stack.", - "type": "string" - }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the stack.", - "type": "string" } } }, - "entity.Workspace": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore": { "type": "object", "properties": { - "backend": { - "description": "Backend is the corresponding backend for this workspace.", + "provider": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ProviderSpec" + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Spec": { + "type": "object", + "properties": { + "context": { + "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", "allOf": [ { - "$ref": "#/definitions/entity.Backend" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig" } ] }, - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the workspace.", - "type": "string" + "resources": { + "description": "Resources is the list of Resource this Spec contains.", + "type": "array", + "items": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Resource" + } }, - "description": { - "description": "Description is a human-readable description of the workspace.", + "secretStore": { + "description": "SecretSore represents a external secret store location for storing secrets.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore" + } + ] + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type": { + "type": "string", + "enum": [ + "Kubernetes", + "Terraform" + ], + "x-enum-varnames": [ + "Kubernetes", + "Terraform" + ] + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultKVStoreVersion": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "x-enum-varnames": [ + "VaultKVStoreV1", + "VaultKVStoreV2" + ] + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultProvider": { + "type": "object", + "properties": { + "path": { + "description": "Path is the mount path of the Vault KV backend endpoint, e.g: \"secret\".", "type": "string" }, - "displayName": { - "description": "DisplayName is the human-readable display name.", + "server": { + "description": "Server is the target Vault server address to connect, e.g: \"https://vault.example.com:8200\".", "type": "string" }, - "id": { - "description": "ID is the id of the workspace.", - "type": "integer" - }, - "labels": { - "description": "Labels are custom labels associated with the workspace.", - "type": "array", - "items": { - "type": "string" - } - }, - "name": { - "description": "Name is the name of the workspace.", + "version": { + "description": "Version is the Vault KV secret engine version. Version can be either \"v1\" or\n\"v2\", defaults to \"v2\".", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultKVStoreVersion" + } + ] + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ViettelCloudProvider": { + "type": "object", + "properties": { + "cmpURL": { + "description": "ViettelCloud CMP URL to be used to interact with ViettelCloud Secrets Manager.\nExamples are https://console.viettelcloud.vn/api/", "type": "string" }, - "owners": { - "description": "Owners is a list of owners for the workspace.", - "type": "array", - "items": { - "type": "string" - } - }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the workspace.", + "projectID": { + "description": "ProjectID to be used to interact with ViettelCloud Secrets Manager.", "type": "string" } } }, - "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type": { - "type": "string", - "enum": [ - "Kubernetes", - "Terraform" - ], - "x-enum-varnames": [ - "Kubernetes", - "Terraform" - ] - }, "models.ActionType": { "type": "integer", "enum": [ @@ -3721,7 +4704,7 @@ const docTemplate = `{ "description": "BackendConfig is the configuration of the backend.", "allOf": [ { - "$ref": "#/definitions/v1.BackendConfig" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig" } ] }, @@ -3933,6 +4916,55 @@ const docTemplate = `{ } } }, + "request.CreateVariableLabelsRequest": { + "type": "object", + "required": [ + "labels", + "variableKey" + ], + "properties": { + "labels": { + "description": "Labels is the list of variable labels, which should be sorted\nin ascending order of priority.", + "type": "array", + "items": { + "type": "string" + } + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", + "type": "string" + } + } + }, + "request.CreateVariableSetRequest": { + "type": "object", + "required": [ + "type", + "value", + "variableKey" + ], + "properties": { + "labels": { + "description": "Labels clarifies the scope of the variable.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "type": { + "description": "Type is the type of the variable.", + "type": "string" + }, + "value": { + "description": "Value is the value of the variable.", + "type": "string" + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", + "type": "string" + } + } + }, "request.CreateWorkspaceRequest": { "type": "object", "required": [ @@ -3969,6 +5001,21 @@ const docTemplate = `{ } } }, + "request.ListVariableSetRequest": { + "type": "object", + "required": [ + "labels" + ], + "properties": { + "labels": { + "description": "Labels clarifies the scope of the variables.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, "request.StackImportRequest": { "type": "object", "properties": { @@ -3991,7 +5038,7 @@ const docTemplate = `{ "description": "BackendConfig is the configuration of the backend.", "allOf": [ { - "$ref": "#/definitions/v1.BackendConfig" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig" } ] }, @@ -4218,488 +5265,184 @@ const docTemplate = `{ }, "projectName": { "description": "ProjectName is the project name of the stack within the source.", - "type": "string" - }, - "type": { - "description": "Type is the type of the stack.", - "type": "string" - } - } - }, - "request.UpdateWorkspaceRequest": { - "type": "object", - "required": [ - "backendID", - "id", - "owners" - ], - "properties": { - "backendID": { - "description": "BackendID is the configuration backend id associated with the workspace.", - "type": "integer" - }, - "description": { - "description": "Description is a human-readable description of the workspace.", - "type": "string" - }, - "id": { - "description": "ID is the id of the workspace.", - "type": "integer" - }, - "labels": { - "description": "Labels are custom labels associated with the workspace.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "name": { - "description": "Name is the name of the workspace.", - "type": "string" - }, - "owners": { - "description": "Owners is a list of owners for the workspace.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "request.WorkspaceConfigs": { - "type": "object", - "properties": { - "context": { - "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", - "allOf": [ - { - "$ref": "#/definitions/v1.GenericConfig" - } - ] - }, - "modules": { - "description": "Modules are the configs of a set of modules.", - "allOf": [ - { - "$ref": "#/definitions/v1.ModuleConfigs" - } - ] - }, - "secretStore": { - "description": "SecretStore represents a secure external location for storing secrets.", - "allOf": [ - { - "$ref": "#/definitions/v1.SecretStore" - } - ] - } - } - }, - "url.URL": { - "type": "object", - "properties": { - "forceQuery": { - "description": "append a query ('?') even if RawQuery is empty", - "type": "boolean" - }, - "fragment": { - "description": "fragment for references, without '#'", - "type": "string" - }, - "host": { - "description": "host or host:port (see Hostname and Port methods)", - "type": "string" - }, - "omitHost": { - "description": "do not emit empty host (authority)", - "type": "boolean" - }, - "opaque": { - "description": "encoded opaque data", - "type": "string" - }, - "path": { - "description": "path (relative paths may omit leading slash)", - "type": "string" - }, - "rawFragment": { - "description": "encoded fragment hint (see EscapedFragment method)", - "type": "string" - }, - "rawPath": { - "description": "encoded path hint (see EscapedPath method)", - "type": "string" - }, - "rawQuery": { - "description": "encoded query values, without '?'", - "type": "string" - }, - "scheme": { - "type": "string" - }, - "user": { - "description": "username and password information", - "allOf": [ - { - "$ref": "#/definitions/url.Userinfo" - } - ] - } - } - }, - "url.Userinfo": { - "type": "object" - }, - "v1.AWSProvider": { - "type": "object", - "properties": { - "profile": { - "description": "The profile to be used to interact with AWS Secrets Manager.\nIf not set, the default profile created with ` + "`" + `aws configure` + "`" + ` will be used.", - "type": "string" - }, - "region": { - "description": "AWS Region to be used to interact with AWS Secrets Manager.\nExamples are us-east-1, us-west-2, etc.", - "type": "string" - } - } - }, - "v1.AlicloudProvider": { - "type": "object", - "properties": { - "region": { - "description": "Alicloud Region to be used to interact with Alicloud Secrets Manager.\nExamples are cn-beijing, cn-shanghai, etc.", - "type": "string" - } - } - }, - "v1.AzureEnvironmentType": { - "type": "string", - "enum": [ - "PublicCloud", - "USGovernmentCloud", - "ChinaCloud", - "GermanCloud" - ], - "x-enum-varnames": [ - "AzureEnvironmentPublicCloud", - "AzureEnvironmentUSGovernmentCloud", - "AzureEnvironmentChinaCloud", - "AzureEnvironmentGermanCloud" - ] - }, - "v1.AzureKVProvider": { - "type": "object", - "properties": { - "environmentType": { - "description": "EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure.\nBy-default it points to the public cloud AAD endpoint, and the following endpoints are available:\nPublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\nRef: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152", - "allOf": [ - { - "$ref": "#/definitions/v1.AzureEnvironmentType" - } - ] - }, - "tenantId": { - "description": "TenantID configures the Azure Tenant to send requests to.", - "type": "string" - }, - "vaultUrl": { - "description": "Vault Url from which the secrets to be fetched from.", - "type": "string" - } - } - }, - "v1.BackendConfig": { - "type": "object", - "properties": { - "configs": { - "description": "Configs contains config items of the backend, whose keys differ from different backend types.", - "type": "object", - "additionalProperties": {} + "type": "string" }, "type": { - "description": "Type is the backend type, supports BackendTypeLocal, BackendTypeOss, BackendTypeS3.", + "description": "Type is the type of the stack.", "type": "string" } } }, - "v1.Configs": { - "type": "object", - "properties": { - "default": { - "description": "Default is default block of the module config.", - "allOf": [ - { - "$ref": "#/definitions/v1.GenericConfig" - } - ] - } - } - }, - "v1.FakeProvider": { + "request.UpdateVariableLabelsRequest": { "type": "object", + "required": [ + "labels", + "variableKey" + ], "properties": { - "data": { + "labels": { + "description": "Labels is the list of variable labels, which should be sorted\nin ascending order of priority.", "type": "array", "items": { - "$ref": "#/definitions/v1.FakeProviderData" + "type": "string" } + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", + "type": "string" } } }, - "v1.FakeProviderData": { + "request.UpdateVariableRequest": { "type": "object", "properties": { + "isSecret": { + "type": "boolean" + }, "key": { + "description": "key is the unique index to use value in specific stack", "type": "string" }, - "value": { + "path": { + "description": "Path is the relative path of the stack within the source.", "type": "string" }, - "valueMap": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "project": { + "description": "Project is the project related to stack", + "type": "string" }, - "version": { + "secretValue": { + "$ref": "#/definitions/entity.SecretValue" + }, + "value": { + "description": "value is the plain value of no sensitive data", "type": "string" } } }, - "v1.GenericConfig": { - "type": "object", - "additionalProperties": {} - }, - "v1.ModuleConfig": { + "request.UpdateWorkspaceRequest": { "type": "object", + "required": [ + "backendID", + "id", + "owners" + ], "properties": { - "configs": { - "description": "Configs contains all levels of module configs", - "allOf": [ - { - "$ref": "#/definitions/v1.Configs" - } - ] + "backendID": { + "description": "BackendID is the configuration backend id associated with the workspace.", + "type": "integer" }, - "path": { - "description": "Path is the path of the module. It can be a local path or a remote URL", + "description": { + "description": "Description is a human-readable description of the workspace.", "type": "string" }, - "version": { - "description": "Version is the version of the module.", - "type": "string" - } - } - }, - "v1.ModuleConfigs": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1.ModuleConfig" - } - }, - "v1.ModulePatcherConfig": { - "type": "object", - "properties": { - "projectSelector": { - "description": "ProjectSelector contains the selected projects.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "v1.OnPremisesProvider": { - "type": "object", - "properties": { - "attributes": { - "description": "attributes of the provider", + "id": { + "description": "ID is the id of the workspace.", + "type": "integer" + }, + "labels": { + "description": "Labels are custom labels associated with the workspace.", "type": "object", "additionalProperties": { "type": "string" } }, "name": { - "description": "platform name of the provider", + "description": "Name is the name of the workspace.", "type": "string" + }, + "owners": { + "description": "Owners is a list of owners for the workspace.", + "type": "array", + "items": { + "type": "string" + } } } }, - "v1.ProviderSpec": { + "request.WorkspaceConfigs": { "type": "object", "properties": { - "alicloud": { - "description": "Alicloud configures a store to retrieve secrets from Alicloud Secrets Manager.", - "allOf": [ - { - "$ref": "#/definitions/v1.AlicloudProvider" - } - ] - }, - "aws": { - "description": "AWS configures a store to retrieve secrets from AWS Secrets Manager.", - "allOf": [ - { - "$ref": "#/definitions/v1.AWSProvider" - } - ] - }, - "azure": { - "description": "Azure configures a store to retrieve secrets from Azure KeyVault.", - "allOf": [ - { - "$ref": "#/definitions/v1.AzureKVProvider" - } - ] - }, - "fake": { - "description": "Fake configures a store with static key/value pairs", - "allOf": [ - { - "$ref": "#/definitions/v1.FakeProvider" - } - ] - }, - "onpremises": { - "description": "Onprem configures a store in on-premises environments", + "context": { + "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", "allOf": [ { - "$ref": "#/definitions/v1.OnPremisesProvider" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig" } ] }, - "vault": { - "description": "Vault configures a store to retrieve secrets from HashiCorp Vault.", + "modules": { + "description": "Modules are the configs of a set of modules.", "allOf": [ { - "$ref": "#/definitions/v1.VaultProvider" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfigs" } ] }, - "viettelcloud": { - "description": "ViettelCloud configures a store to retrieve secrets from ViettelCloud Secrets Manager.", + "secretStore": { + "description": "SecretStore represents a secure external location for storing secrets.", "allOf": [ { - "$ref": "#/definitions/v1.ViettelCloudProvider" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore" } ] } } }, - "v1.Resource": { + "url.URL": { "type": "object", "properties": { - "attributes": { - "description": "Attributes represents all specified attributes of this resource", - "type": "object", - "additionalProperties": true - }, - "dependsOn": { - "description": "DependsOn contains all resources this resource depends on", - "type": "array", - "items": { - "type": "string" - } + "forceQuery": { + "description": "append a query ('?') even if RawQuery is empty", + "type": "boolean" }, - "extensions": { - "description": "Extensions specifies arbitrary metadata of this resource", - "type": "object", - "additionalProperties": true + "fragment": { + "description": "fragment for references, without '#'", + "type": "string" }, - "id": { - "description": "ID is the unique key of this resource.\nApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources.\nproviderNamespace:providerName:resourceType:resourceName for Terraform resources", + "host": { + "description": "host or host:port (see Hostname and Port methods)", "type": "string" }, - "type": { - "description": "Type represents all Context we supported like Kubernetes and Terraform", - "allOf": [ - { - "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type" - } - ] - } - } - }, - "v1.SecretStore": { - "type": "object", - "properties": { - "provider": { - "$ref": "#/definitions/v1.ProviderSpec" - } - } - }, - "v1.Spec": { - "type": "object", - "properties": { - "context": { - "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", - "allOf": [ - { - "$ref": "#/definitions/v1.GenericConfig" - } - ] + "omitHost": { + "description": "do not emit empty host (authority)", + "type": "boolean" }, - "resources": { - "description": "Resources is the list of Resource this Spec contains.", - "type": "array", - "items": { - "$ref": "#/definitions/v1.Resource" - } + "opaque": { + "description": "encoded opaque data", + "type": "string" }, - "secretStore": { - "description": "SecretSore represents a external secret store location for storing secrets.", - "allOf": [ - { - "$ref": "#/definitions/v1.SecretStore" - } - ] - } - } - }, - "v1.VaultKVStoreVersion": { - "type": "string", - "enum": [ - "v1", - "v2" - ], - "x-enum-varnames": [ - "VaultKVStoreV1", - "VaultKVStoreV2" - ] - }, - "v1.VaultProvider": { - "type": "object", - "properties": { "path": { - "description": "Path is the mount path of the Vault KV backend endpoint, e.g: \"secret\".", + "description": "path (relative paths may omit leading slash)", "type": "string" }, - "server": { - "description": "Server is the target Vault server address to connect, e.g: \"https://vault.example.com:8200\".", + "rawFragment": { + "description": "encoded fragment hint (see EscapedFragment method)", "type": "string" }, - "version": { - "description": "Version is the Vault KV secret engine version. Version can be either \"v1\" or\n\"v2\", defaults to \"v2\".", + "rawPath": { + "description": "encoded path hint (see EscapedPath method)", + "type": "string" + }, + "rawQuery": { + "description": "encoded query values, without '?'", + "type": "string" + }, + "scheme": { + "type": "string" + }, + "user": { + "description": "username and password information", "allOf": [ { - "$ref": "#/definitions/v1.VaultKVStoreVersion" + "$ref": "#/definitions/url.Userinfo" } ] } } }, - "v1.ViettelCloudProvider": { - "type": "object", - "properties": { - "cmpURL": { - "description": "ViettelCloud CMP URL to be used to interact with ViettelCloud Secrets Manager.\nExamples are https://console.viettelcloud.vn/api/", - "type": "string" - }, - "projectID": { - "description": "ProjectID to be used to interact with ViettelCloud Secrets Manager.", - "type": "string" - } - } + "url.Userinfo": { + "type": "object" } } }` diff --git a/api/openapispec/swagger.json b/api/openapispec/swagger.json index f2cab74d..24766a34 100644 --- a/api/openapispec/swagger.json +++ b/api/openapispec/swagger.json @@ -2270,7 +2270,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/v1.Spec" + "type": "string" } }, "400": { @@ -2339,7 +2339,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/v1.Spec" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Spec" } }, "400": { @@ -2460,22 +2460,49 @@ } } }, - "/api/v1/workspaces": { + "/api/v1/variable-labels": { "get": { - "description": "List all workspaces", + "description": "List variable labels", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable_labels" + ], + "summary": "List variable labels", + "operationId": "listVariableLabels", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Variable labels to filter variables by. Default to all(empty) labels.", + "name": "labels", + "in": "query" + }, + { + "type": "string", + "description": "Page number of the paginated list results. Default to 1.", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "Page size of the paginated list results. If not set, the result won't be paginated.", + "name": "pageSize", + "in": "query" + } ], - "summary": "List workspaces", - "operationId": "listWorkspace", "responses": { "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "type": "array", + "items": { + "$ref": "#/definitions/entity.VariableLabelsListResult" + } } }, "400": { @@ -2501,7 +2528,7 @@ } }, "post": { - "description": "Create a new workspace", + "description": "Create a new set of variable labels", "consumes": [ "application/json" ], @@ -2509,18 +2536,18 @@ "application/json" ], "tags": [ - "workspace" + "variable_labels" ], - "summary": "Create workspace", - "operationId": "createWorkspace", + "summary": "Create variable labels", + "operationId": "createVariableLabels", "parameters": [ { - "description": "Created workspace", - "name": "workspace", + "description": "Created variable labels", + "name": "variable_labels", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.CreateWorkspaceRequest" + "$ref": "#/definitions/request.CreateVariableLabelsRequest" } } ], @@ -2528,7 +2555,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "$ref": "#/definitions/entity.VariableLabels" } }, "400": { @@ -2554,9 +2581,57 @@ } } }, - "/api/v1/workspaces/configs/validate": { - "post": { - "description": "Validate the configurations in the specified workspace", + "/api/v1/variable-labels/{key}": { + "get": { + "description": "Get variable labels by variable key", + "produces": [ + "application/json" + ], + "tags": [ + "variable_labels" + ], + "summary": "Get variable labels", + "operationId": "getVariableLabels", + "parameters": [ + { + "type": "string", + "description": "Variable Key", + "name": "key", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.VariableLabels" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "put": { + "description": "Update the specified variable labels", "consumes": [ "application/json" ], @@ -2564,18 +2639,25 @@ "application/json" ], "tags": [ - "workspace" + "variable_labels" ], - "summary": "Validate workspace configurations", - "operationId": "validateWorkspaceConfigs", + "summary": "Update variable labels", + "operationId": "updateVariableLabels", "parameters": [ { - "description": "Workspace configurations to be validated", - "name": "workspace", + "type": "string", + "description": "Variable Key", + "name": "key", + "in": "path", + "required": true + }, + { + "description": "Updated Variable Labels", + "name": "variable_labels", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/request.UpdateVariableLabelsRequest" } } ], @@ -2583,7 +2665,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/entity.VariableLabels" } }, "400": { @@ -2607,24 +2689,22 @@ "schema": {} } } - } - }, - "/api/v1/workspaces/{id}": { - "get": { - "description": "Get workspace information by workspace ID", + }, + "delete": { + "description": "Delete a specified variable with labels", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable_labels" ], - "summary": "Get workspace", - "operationId": "getWorkspace", + "summary": "Delete variable labels", + "operationId": "deleteVariableLabels", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Key", + "name": "key", "in": "path", "required": true } @@ -2633,7 +2713,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "type": "string" } }, "400": { @@ -2657,35 +2737,27 @@ "schema": {} } } - }, - "put": { - "description": "Update the specified workspace", - "consumes": [ - "application/json" - ], + } + }, + "/api/v1/variables": { + "get": { + "description": "List variables", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Update workspace", - "operationId": "updateWorkspace", + "summary": "List variables", + "operationId": "listVariables", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Updated workspace", - "name": "workspace", + "description": "Variable labels to filter variables by.", + "name": "variable", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.UpdateWorkspaceRequest" + "$ref": "#/definitions/request.ListVariableSetRequest" } } ], @@ -2693,7 +2765,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/entity.Workspace" + "$ref": "#/definitions/entity.VariableLabelsListResult" } }, "400": { @@ -2718,30 +2790,35 @@ } } }, - "delete": { - "description": "Delete specified workspace by ID", + "post": { + "description": "Create a new variable", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Delete workspace", - "operationId": "deleteWorkspace", + "summary": "Create variable", + "operationId": "createVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", - "in": "path", - "required": true + "description": "Created variable", + "name": "variable", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CreateVariableSetRequest" + } } ], "responses": { "200": { "description": "Success", "schema": { - "type": "string" + "$ref": "#/definitions/entity.Variable" } }, "400": { @@ -2767,25 +2844,22 @@ } } }, - "/api/v1/workspaces/{id}/configs": { + "/api/v1/variables/{fqn}": { "get": { - "description": "Get configurations in the specified workspace", - "consumes": [ - "application/json" - ], + "description": "Get variable by variable fqn", "produces": [ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "get workspace configurations", - "operationId": "getWorkspaceConfigs", + "summary": "Get variable", + "operationId": "getVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Fqn", + "name": "fqn", "in": "path", "required": true } @@ -2794,7 +2868,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/entity.Variable" } }, "400": { @@ -2820,7 +2894,7 @@ } }, "put": { - "description": "Update the configurations in the specified workspace", + "description": "Update the specified variable", "consumes": [ "application/json" ], @@ -2828,25 +2902,25 @@ "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Update workspace configurations", - "operationId": "updateWorkspaceConfigs", + "summary": "Update variable", + "operationId": "updateVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Fqn", + "name": "fqn", "in": "path", "required": true }, { - "description": "Updated workspace configurations", - "name": "workspace", + "description": "Updated Variable", + "name": "variable", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/request.UpdateVariableRequest" } } ], @@ -2854,7 +2928,7 @@ "200": { "description": "Success", "schema": { - "$ref": "#/definitions/request.WorkspaceConfigs" + "$ref": "#/definitions/entity.Variable" } }, "400": { @@ -2878,27 +2952,22 @@ "schema": {} } } - } - }, - "/api/v1/workspaces/{id}/configs/mod-deps": { - "post": { - "description": "Create the module dependencies in kcl.mod of the specified workspace", - "consumes": [ - "application/json" - ], + }, + "delete": { + "description": "Delete a specified variable with fqn", "produces": [ - "text/plain" + "application/json" ], "tags": [ - "workspace" + "variable" ], - "summary": "Create the module dependencies of the workspace", - "operationId": "createWorkspaceModDeps", + "summary": "Delete variable", + "operationId": "deleteVariable", "parameters": [ { - "type": "integer", - "description": "Workspace ID", - "name": "id", + "type": "string", + "description": "Variable Fqn", + "name": "fqn", "in": "path", "required": true } @@ -2933,54 +3002,527 @@ } } }, - "/endpoints": { + "/api/v1/workspaces": { "get": { - "description": "List all registered endpoints in the router", - "consumes": [ - "text/plain" - ], + "description": "List all workspaces", "produces": [ - "text/plain" + "application/json" ], "tags": [ - "debug" + "workspace" ], - "summary": "List all available endpoints", + "summary": "List workspaces", + "operationId": "listWorkspace", "responses": { "200": { - "description": "Endpoints listed successfully", + "description": "Success", "schema": { - "type": "string" + "$ref": "#/definitions/entity.Workspace" } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} } } - } - } - }, - "definitions": { - "constant.RunStatus": { - "type": "string", - "enum": [ - "Scheduling", - "InProgress", - "Failed", - "Succeeded", - "Cancelled", - "Queued" - ], - "x-enum-varnames": [ - "RunStatusScheduling", - "RunStatusInProgress", - "RunStatusFailed", - "RunStatusSucceeded", - "RunStatusCancelled", - "RunStatusQueued" - ] - }, - "constant.RunType": { - "type": "string", - "enum": [ - "Generate", + }, + "post": { + "description": "Create a new workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Create workspace", + "operationId": "createWorkspace", + "parameters": [ + { + "description": "Created workspace", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CreateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.Workspace" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/configs/validate": { + "post": { + "description": "Validate the configurations in the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Validate workspace configurations", + "operationId": "validateWorkspaceConfigs", + "parameters": [ + { + "description": "Workspace configurations to be validated", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/{id}": { + "get": { + "description": "Get workspace information by workspace ID", + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Get workspace", + "operationId": "getWorkspace", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.Workspace" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "put": { + "description": "Update the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Update workspace", + "operationId": "updateWorkspace", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Updated workspace", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/entity.Workspace" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "delete": { + "description": "Delete specified workspace by ID", + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Delete workspace", + "operationId": "deleteWorkspace", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/{id}/configs": { + "get": { + "description": "Get configurations in the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "get workspace configurations", + "operationId": "getWorkspaceConfigs", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + }, + "put": { + "description": "Update the configurations in the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workspace" + ], + "summary": "Update workspace configurations", + "operationId": "updateWorkspaceConfigs", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Updated workspace configurations", + "name": "workspace", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/request.WorkspaceConfigs" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/api/v1/workspaces/{id}/configs/mod-deps": { + "post": { + "description": "Create the module dependencies in kcl.mod of the specified workspace", + "consumes": [ + "application/json" + ], + "produces": [ + "text/plain" + ], + "tags": [ + "workspace" + ], + "summary": "Create the module dependencies of the workspace", + "operationId": "createWorkspaceModDeps", + "parameters": [ + { + "type": "integer", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": {} + }, + "401": { + "description": "Unauthorized", + "schema": {} + }, + "404": { + "description": "Not Found", + "schema": {} + }, + "429": { + "description": "Too Many Requests", + "schema": {} + }, + "500": { + "description": "Internal Server Error", + "schema": {} + } + } + } + }, + "/endpoints": { + "get": { + "description": "List all registered endpoints in the router", + "consumes": [ + "text/plain" + ], + "produces": [ + "text/plain" + ], + "tags": [ + "debug" + ], + "summary": "List all available endpoints", + "responses": { + "200": { + "description": "Endpoints listed successfully", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "constant.RunStatus": { + "type": "string", + "enum": [ + "Scheduling", + "InProgress", + "Failed", + "Succeeded", + "Cancelled", + "Queued" + ], + "x-enum-varnames": [ + "RunStatusScheduling", + "RunStatusInProgress", + "RunStatusFailed", + "RunStatusSucceeded", + "RunStatusCancelled", + "RunStatusQueued" + ] + }, + "constant.RunType": { + "type": "string", + "enum": [ + "Generate", "Preview", "Apply", "Destroy" @@ -2992,650 +3534,1091 @@ "RunTypeDestroy" ] }, - "constant.SourceProviderType": { - "type": "string", - "enum": [ - "git", - "git", - "github", - "oci", - "local" - ], - "x-enum-varnames": [ - "DefaultSourceType", - "SourceProviderTypeGit", - "SourceProviderTypeGithub", - "SourceProviderTypeOCI", - "SourceProviderTypeLocal" - ] + "constant.SourceProviderType": { + "type": "string", + "enum": [ + "git", + "git", + "github", + "oci", + "local" + ], + "x-enum-varnames": [ + "DefaultSourceType", + "SourceProviderTypeGit", + "SourceProviderTypeGithub", + "SourceProviderTypeOCI", + "SourceProviderTypeLocal" + ] + }, + "constant.StackState": { + "type": "string", + "enum": [ + "UnSynced", + "Synced", + "OutOfSync", + "Creating", + "Generating", + "GenerateFailed", + "Generated", + "Previewing", + "PreviewFailed", + "Previewed", + "Applying", + "ApplyFailed", + "ApplySucceeded", + "Destroying", + "DestroyFailed", + "DestroySucceeded" + ], + "x-enum-varnames": [ + "StackStateUnSynced", + "StackStateSynced", + "StackStateOutOfSync", + "StackStateCreating", + "StackStateGenerating", + "StackStateGenerateFailed", + "StackStateGenerated", + "StackStatePreviewing", + "StackStatePreviewFailed", + "StackStatePreviewed", + "StackStateApplying", + "StackStateApplyFailed", + "StackStateApplySucceeded", + "StackStateDestroying", + "StackStateDestroyFailed", + "StackStateDestroySucceeded" + ] + }, + "entity.Backend": { + "type": "object", + "properties": { + "backendConfig": { + "description": "// Type is the type of the backend.\nType string `yaml:\"type\" json:\"type\"`\nBackend is the configuration of the backend.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig" + } + ] + }, + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the backend.", + "type": "string" + }, + "description": { + "description": "Description is a human-readable description of the backend.", + "type": "string" + }, + "id": { + "description": "ID is the id of the backend.", + "type": "integer" + }, + "name": { + "description": "Name is the name of the backend.", + "type": "string" + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the backend.", + "type": "string" + } + } + }, + "entity.Module": { + "type": "object", + "properties": { + "description": { + "description": "Description is a human-readable description of the module.", + "type": "string" + }, + "doc": { + "description": "Doc is the documentation URL of the module.", + "allOf": [ + { + "$ref": "#/definitions/url.URL" + } + ] + }, + "name": { + "description": "Name is the module name.", + "type": "string" + }, + "owners": { + "description": "Owners is a list of owners for the module.", + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "description": "URL is the module oci artifact registry URL.", + "allOf": [ + { + "$ref": "#/definitions/url.URL" + } + ] + } + } + }, + "entity.Organization": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the organization.", + "type": "string" + }, + "description": { + "description": "Description is a human-readable description of the organization.", + "type": "string" + }, + "displayName": { + "description": "DisplayName is the human-readable display name.", + "type": "string" + }, + "id": { + "description": "ID is the id of the organization.", + "type": "integer" + }, + "labels": { + "description": "Labels are custom labels associated with the organization.", + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "description": "Name is the name of the organization.", + "type": "string" + }, + "owners": { + "description": "Owners is a list of owners for the organization.", + "type": "array", + "items": { + "type": "string" + } + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the organization.", + "type": "string" + } + } + }, + "entity.Project": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the project.", + "type": "string" + }, + "description": { + "description": "Description is a human-readable description of the project.", + "type": "string" + }, + "displayName": { + "description": "DisplayName is the human-readable display name.", + "type": "string" + }, + "id": { + "description": "ID is the id of the project.", + "type": "integer" + }, + "labels": { + "description": "Labels are custom labels associated with the project.", + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "description": "Name is the name of the project.", + "type": "string" + }, + "organization": { + "description": "Organization is the configuration source associated with the project.", + "allOf": [ + { + "$ref": "#/definitions/entity.Organization" + } + ] + }, + "owners": { + "description": "Owners is a list of owners for the project.", + "type": "array", + "items": { + "type": "string" + } + }, + "path": { + "description": "Path is the relative path of the project within the sources.", + "type": "string" + }, + "source": { + "description": "Source is the configuration source associated with the project.", + "allOf": [ + { + "$ref": "#/definitions/entity.Source" + } + ] + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the project.", + "type": "string" + } + } }, - "constant.StackState": { - "type": "string", - "enum": [ - "UnSynced", - "Synced", - "OutOfSync", - "Creating", - "Generating", - "GenerateFailed", - "Generated", - "Previewing", - "PreviewFailed", - "Previewed", - "Applying", - "ApplyFailed", - "ApplySucceeded", - "Destroying", - "DestroyFailed", - "DestroySucceeded" - ], - "x-enum-varnames": [ - "StackStateUnSynced", - "StackStateSynced", - "StackStateOutOfSync", - "StackStateCreating", - "StackStateGenerating", - "StackStateGenerateFailed", - "StackStateGenerated", - "StackStatePreviewing", - "StackStatePreviewFailed", - "StackStatePreviewed", - "StackStateApplying", - "StackStateApplyFailed", - "StackStateApplySucceeded", - "StackStateDestroying", - "StackStateDestroyFailed", - "StackStateDestroySucceeded" - ] + "entity.Resource": { + "type": "object", + "properties": { + "LastAppliedRevision": { + "description": "LastAppliedRevision is the revision of the last sync.", + "type": "string" + }, + "LastAppliedTimestamp": { + "description": "LastAppliedTimestamp is the timestamp of the last sync.", + "type": "string" + }, + "attributes": { + "description": "Attributes is the attributes of the resource.", + "type": "object", + "additionalProperties": true + }, + "cloudResourceID": { + "description": "CloudResourceID is the id of the resource in the cloud.", + "type": "string" + }, + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the resource.", + "type": "string" + }, + "dependsOn": { + "description": "DependsOn is the depends on of the resource.", + "type": "array", + "items": { + "type": "string" + } + }, + "extensions": { + "description": "Extensions is the extensions of the resource.", + "type": "object", + "additionalProperties": true + }, + "iamResourceID": { + "description": "IAMResourceID is the id of the resource in IAM.", + "type": "string" + }, + "id": { + "description": "ID is the id of the resource.", + "type": "integer" + }, + "kusionResourceID": { + "description": "KusionResourceID is the id of the resource in Kusion.", + "type": "string" + }, + "labels": { + "description": "Labels are custom labels associated with the resource.", + "type": "array", + "items": { + "type": "string" + } + }, + "owners": { + "description": "Owners is a list of owners for the resource.", + "type": "array", + "items": { + "type": "string" + } + }, + "provider": { + "description": "Provider is the provider of the resource.", + "type": "string" + }, + "resourceName": { + "description": "ResourceName is the name of the resource.", + "type": "string" + }, + "resourcePlane": { + "description": "ResourcePlane is the plane of the resource.", + "type": "string" + }, + "resourceType": { + "description": "ResourceType is the type of the resource.", + "type": "string" + }, + "stack": { + "description": "Stack is the stack associated with the resource.", + "allOf": [ + { + "$ref": "#/definitions/entity.Stack" + } + ] + }, + "status": { + "description": "Status is the status of the resource.", + "type": "string" + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the resource.", + "type": "string" + } + } + }, + "entity.ResourceGraph": { + "type": "object", + "properties": { + "relations": { + "type": "array", + "items": { + "$ref": "#/definitions/entity.ResourceRelation" + } + }, + "resources": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/entity.ResourceInfo" + } + }, + "workload": { + "type": "string" + } + } }, - "entity.Backend": { + "entity.ResourceInfo": { "type": "object", "properties": { - "backendConfig": { - "description": "// Type is the type of the backend.\nType string `yaml:\"type\" json:\"type\"`\nBackend is the configuration of the backend.", - "allOf": [ - { - "$ref": "#/definitions/v1.BackendConfig" - } - ] + "cloudResourceID": { + "description": "CloudResourceID is the id of the resource in the cloud.", + "type": "string" }, - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the backend.", + "iamResourceID": { + "description": "IAMResourceID is the id of the resource in IAM.", "type": "string" }, - "description": { - "description": "Description is a human-readable description of the backend.", + "resourceName": { + "description": "ResourceName is the name of the resource.", "type": "string" }, - "id": { - "description": "ID is the id of the backend.", - "type": "integer" + "resourcePlane": { + "description": "ResourcePlane is the plane of the resource.", + "type": "string" }, - "name": { - "description": "Name is the name of the backend.", + "resourceType": { + "description": "ResourceType is the type of the resource.", "type": "string" }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the backend.", + "status": { + "description": "Status is the status of the resource.", "type": "string" } } }, - "entity.Module": { + "entity.ResourceRelation": { "type": "object", "properties": { - "description": { - "description": "Description is a human-readable description of the module.", + "dependencyResource": { "type": "string" }, - "doc": { - "description": "Doc is the documentation URL of the module.", + "dependentResource": { + "type": "string" + } + } + }, + "entity.Run": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the run.", + "type": "string" + }, + "id": { + "description": "ID is the id of the run.", + "type": "integer" + }, + "logs": { + "description": "Logs is the logs of the run.", + "type": "string" + }, + "result": { + "description": "Result is the result of the run.", + "type": "string" + }, + "stack": { + "description": "Stack is the stack of the run.", "allOf": [ { - "$ref": "#/definitions/url.URL" + "$ref": "#/definitions/entity.Stack" } ] }, - "name": { - "description": "Name is the module name.", - "type": "string" + "status": { + "description": "Status is the status of the run.", + "allOf": [ + { + "$ref": "#/definitions/constant.RunStatus" + } + ] }, - "owners": { - "description": "Owners is a list of owners for the module.", - "type": "array", - "items": { - "type": "string" - } + "trace": { + "description": "Trace is the trace of the run.", + "type": "string" }, - "url": { - "description": "URL is the module oci artifact registry URL.", + "type": { + "description": "RunType is the type of the run provider.", "allOf": [ { - "$ref": "#/definitions/url.URL" + "$ref": "#/definitions/constant.RunType" } ] + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the run.", + "type": "string" + }, + "workspace": { + "description": "Workspace is the target workspace of the run.", + "type": "string" } } }, - "entity.Organization": { + "entity.SecretStore": { "type": "object", "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the organization.", + "provider": { + "type": "object", + "additionalProperties": {} + }, + "providerType": { + "type": "string" + } + } + }, + "entity.SecretValue": { + "type": "object", + "properties": { + "ref": { + "description": "Ref will only return with the update secret variable", "type": "string" }, - "description": { - "description": "Description is a human-readable description of the organization.", + "secretStore": { + "$ref": "#/definitions/entity.SecretStore" + }, + "value": { + "description": "Value to store in the secret store.", + "type": "string" + } + } + }, + "entity.Source": { + "type": "object", + "properties": { + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the source.", "type": "string" }, - "displayName": { - "description": "DisplayName is the human-readable display name.", + "description": { + "description": "Description is a human-readable description of the source.", "type": "string" }, "id": { - "description": "ID is the id of the organization.", + "description": "ID is the id of the source.", "type": "integer" }, "labels": { - "description": "Labels are custom labels associated with the organization.", + "description": "Labels are custom labels associated with the source.", "type": "array", "items": { "type": "string" } }, "name": { - "description": "Name is the name of the organization.", + "description": "Name is the name of the source.", "type": "string" }, "owners": { - "description": "Owners is a list of owners for the organization.", + "description": "Owners is a list of owners for the source.", "type": "array", "items": { "type": "string" } }, + "remote": { + "description": "Remote is the source URL, including scheme.", + "allOf": [ + { + "$ref": "#/definitions/url.URL" + } + ] + }, + "sourceProvider": { + "description": "SourceProvider is the type of the source provider.", + "allOf": [ + { + "$ref": "#/definitions/constant.SourceProviderType" + } + ] + }, "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the organization.", + "description": "UpdateTimestamp is the timestamp of the updated for the source.", "type": "string" } } }, - "entity.Project": { + "entity.Stack": { "type": "object", "properties": { "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the project.", + "description": "CreationTimestamp is the timestamp of the created for the stack.", "type": "string" }, "description": { - "description": "Description is a human-readable description of the project.", + "description": "Description is a human-readable description of the stack.", + "type": "string" + }, + "desiredVersion": { + "description": "Desired is the desired version of stack.", "type": "string" }, "displayName": { - "description": "DisplayName is the human-readable display name.", + "description": "DisplayName is the human-readable display nams.", "type": "string" }, "id": { - "description": "ID is the id of the project.", + "description": "ID is the id of the stack.", "type": "integer" }, "labels": { - "description": "Labels are custom labels associated with the project.", + "description": "Labels are custom labels associated with the stack.", "type": "array", "items": { "type": "string" } }, - "name": { - "description": "Name is the name of the project.", + "lastAppliedRevision": { + "description": "LastAppliedRevision is the spec ID of the last apply operation for the stack.", "type": "string" }, - "organization": { - "description": "Organization is the configuration source associated with the project.", - "allOf": [ - { - "$ref": "#/definitions/entity.Organization" - } - ] + "lastAppliedTimestamp": { + "description": "LastAppliedTimestamp is the timestamp of the last apply operation for the stack.", + "type": "string" + }, + "lastGeneratedRevision": { + "description": "LastGeneratedRevision is the spec ID of the last generate operation for the stack.", + "type": "string" + }, + "lastPreviewedRevision": { + "description": "LastPreviewedRevision is the spec ID of the last preview operation for the stack.", + "type": "string" + }, + "name": { + "description": "Name is the name of the stack.", + "type": "string" }, "owners": { - "description": "Owners is a list of owners for the project.", + "description": "Owners is a list of owners for the stack.", "type": "array", "items": { "type": "string" } }, "path": { - "description": "Path is the relative path of the project within the sources.", + "description": "Path is the relative path of the stack within the sourcs.", "type": "string" }, - "source": { - "description": "Source is the configuration source associated with the project.", + "project": { + "description": "Project is the project associated with the stack.", "allOf": [ { - "$ref": "#/definitions/entity.Source" + "$ref": "#/definitions/entity.Project" + } + ] + }, + "syncState": { + "description": "SyncState is the current state of the stack.", + "allOf": [ + { + "$ref": "#/definitions/constant.StackState" } ] }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the project.", + "type": { + "description": "Type is the type of the stack.", + "type": "string" + }, + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the stack.", + "type": "string" + } + } + }, + "entity.Variable": { + "type": "object", + "properties": { + "fqn": { + "description": "Fqn is the fully qualified name of the variable.", + "type": "string" + }, + "labels": { + "description": "Labels clarifies the scope of the variable.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "type": { + "description": "Type is the type of the variable.", + "type": "string" + }, + "value": { + "description": "Value is the value of the variable.", + "type": "string" + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", "type": "string" } } }, - "entity.Resource": { + "entity.VariableLabels": { "type": "object", "properties": { - "LastAppliedRevision": { - "description": "LastAppliedRevision is the revision of the last sync.", - "type": "string" - }, - "LastAppliedTimestamp": { - "description": "LastAppliedTimestamp is the timestamp of the last sync.", - "type": "string" - }, - "attributes": { - "description": "Attributes is the attributes of the resource.", - "type": "object", - "additionalProperties": true - }, - "cloudResourceID": { - "description": "CloudResourceID is the id of the resource in the cloud.", - "type": "string" + "labels": { + "description": "Labels is the list of variable labels, which should be sorted\nin ascending order of priority.", + "type": "array", + "items": { + "type": "string" + } }, - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the resource.", + "variableKey": { + "description": "VariableKey is the access path for the variable.", "type": "string" + } + } + }, + "entity.VariableLabelsListResult": { + "type": "object", + "properties": { + "total": { + "type": "integer" }, - "dependsOn": { - "description": "DependsOn is the depends on of the resource.", + "variableLabels": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/entity.VariableLabels" } + } + } + }, + "entity.Workspace": { + "type": "object", + "properties": { + "backend": { + "description": "Backend is the corresponding backend for this workspace.", + "allOf": [ + { + "$ref": "#/definitions/entity.Backend" + } + ] }, - "extensions": { - "description": "Extensions is the extensions of the resource.", - "type": "object", - "additionalProperties": true + "creationTimestamp": { + "description": "CreationTimestamp is the timestamp of the created for the workspace.", + "type": "string" }, - "iamResourceID": { - "description": "IAMResourceID is the id of the resource in IAM.", + "description": { + "description": "Description is a human-readable description of the workspace.", + "type": "string" + }, + "displayName": { + "description": "DisplayName is the human-readable display name.", "type": "string" }, "id": { - "description": "ID is the id of the resource.", + "description": "ID is the id of the workspace.", "type": "integer" }, - "kusionResourceID": { - "description": "KusionResourceID is the id of the resource in Kusion.", - "type": "string" - }, "labels": { - "description": "Labels are custom labels associated with the resource.", + "description": "Labels are custom labels associated with the workspace.", "type": "array", "items": { "type": "string" } }, + "name": { + "description": "Name is the name of the workspace.", + "type": "string" + }, "owners": { - "description": "Owners is a list of owners for the resource.", + "description": "Owners is a list of owners for the workspace.", "type": "array", "items": { "type": "string" } }, - "provider": { - "description": "Provider is the provider of the resource.", + "updateTimestamp": { + "description": "UpdateTimestamp is the timestamp of the updated for the workspace.", "type": "string" - }, - "resourceName": { - "description": "ResourceName is the name of the resource.", + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AWSProvider": { + "type": "object", + "properties": { + "profile": { + "description": "The profile to be used to interact with AWS Secrets Manager.\nIf not set, the default profile created with `aws configure` will be used.", "type": "string" }, - "resourcePlane": { - "description": "ResourcePlane is the plane of the resource.", + "region": { + "description": "AWS Region to be used to interact with AWS Secrets Manager.\nExamples are us-east-1, us-west-2, etc.", "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource.", + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AlicloudProvider": { + "type": "object", + "properties": { + "region": { + "description": "Alicloud Region to be used to interact with Alicloud Secrets Manager.\nExamples are cn-beijing, cn-shanghai, etc.", "type": "string" - }, - "stack": { - "description": "Stack is the stack associated with the resource.", + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureEnvironmentType": { + "type": "string", + "enum": [ + "PublicCloud", + "USGovernmentCloud", + "ChinaCloud", + "GermanCloud" + ], + "x-enum-varnames": [ + "AzureEnvironmentPublicCloud", + "AzureEnvironmentUSGovernmentCloud", + "AzureEnvironmentChinaCloud", + "AzureEnvironmentGermanCloud" + ] + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureKVProvider": { + "type": "object", + "properties": { + "environmentType": { + "description": "EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure.\nBy-default it points to the public cloud AAD endpoint, and the following endpoints are available:\nPublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\nRef: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152", "allOf": [ { - "$ref": "#/definitions/entity.Stack" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureEnvironmentType" } ] }, - "status": { - "description": "Status is the status of the resource.", + "tenantId": { + "description": "TenantID configures the Azure Tenant to send requests to.", "type": "string" }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the resource.", + "vaultUrl": { + "description": "Vault Url from which the secrets to be fetched from.", "type": "string" } } }, - "entity.ResourceGraph": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig": { "type": "object", "properties": { - "relations": { - "type": "array", - "items": { - "$ref": "#/definitions/entity.ResourceRelation" - } - }, - "resources": { + "configs": { + "description": "Configs contains config items of the backend, whose keys differ from different backend types.", "type": "object", - "additionalProperties": { - "$ref": "#/definitions/entity.ResourceInfo" - } + "additionalProperties": {} }, - "workload": { + "type": { + "description": "Type is the backend type, supports BackendTypeLocal, BackendTypeOss, BackendTypeS3.", "type": "string" } } }, - "entity.ResourceInfo": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Configs": { "type": "object", "properties": { - "cloudResourceID": { - "description": "CloudResourceID is the id of the resource in the cloud.", + "default": { + "description": "Default is default block of the module config.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig" + } + ] + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProvider": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProviderData" + } + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProviderData": { + "type": "object", + "properties": { + "key": { "type": "string" }, - "iamResourceID": { - "description": "IAMResourceID is the id of the resource in IAM.", + "value": { "type": "string" }, - "resourceName": { - "description": "ResourceName is the name of the resource.", - "type": "string" + "valueMap": { + "type": "object", + "additionalProperties": { + "type": "string" + } }, - "resourcePlane": { - "description": "ResourcePlane is the plane of the resource.", + "version": { "type": "string" + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig": { + "type": "object", + "additionalProperties": {} + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfig": { + "type": "object", + "properties": { + "configs": { + "description": "Configs contains all levels of module configs", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Configs" + } + ] }, - "resourceType": { - "description": "ResourceType is the type of the resource.", + "path": { + "description": "Path is the path of the module. It can be a local path or a remote URL", "type": "string" }, - "status": { - "description": "Status is the status of the resource.", + "version": { + "description": "Version is the version of the module.", "type": "string" } } }, - "entity.ResourceRelation": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfigs": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfig" + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModulePatcherConfig": { "type": "object", "properties": { - "dependencyResource": { - "type": "string" - }, - "dependentResource": { - "type": "string" + "projectSelector": { + "description": "ProjectSelector contains the selected projects.", + "type": "array", + "items": { + "type": "string" + } } } }, - "entity.Run": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.OnPremisesProvider": { "type": "object", "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the run.", - "type": "string" - }, - "id": { - "description": "ID is the id of the run.", - "type": "integer" - }, - "logs": { - "description": "Result RunResult `yaml:\"result\" json:\"result\"`\nLogs is the logs of the run.", - "type": "string" - }, - "result": { - "description": "Result is the result of the run.", - "type": "string" + "attributes": { + "description": "attributes of the provider", + "type": "object", + "additionalProperties": { + "type": "string" + } }, - "stack": { - "description": "Stack is the stack of the run.", + "name": { + "description": "platform name of the provider", + "type": "string" + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ProviderSpec": { + "type": "object", + "properties": { + "alicloud": { + "description": "Alicloud configures a store to retrieve secrets from Alicloud Secrets Manager.", "allOf": [ { - "$ref": "#/definitions/entity.Stack" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AlicloudProvider" } ] }, - "status": { - "description": "Status is the status of the run.", + "aws": { + "description": "AWS configures a store to retrieve secrets from AWS Secrets Manager.", "allOf": [ { - "$ref": "#/definitions/constant.RunStatus" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AWSProvider" } ] }, - "type": { - "description": "RunType is the type of the run provider.", + "azure": { + "description": "Azure configures a store to retrieve secrets from Azure KeyVault.", "allOf": [ { - "$ref": "#/definitions/constant.RunType" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureKVProvider" } ] }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the run.", - "type": "string" - }, - "workspace": { - "description": "Workspace is the target workspace of the run.", - "type": "string" - } - } - }, - "entity.Source": { - "type": "object", - "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the source.", - "type": "string" - }, - "description": { - "description": "Description is a human-readable description of the source.", - "type": "string" - }, - "id": { - "description": "ID is the id of the source.", - "type": "integer" - }, - "labels": { - "description": "Labels are custom labels associated with the source.", - "type": "array", - "items": { - "type": "string" - } - }, - "name": { - "description": "Name is the name of the source.", - "type": "string" - }, - "owners": { - "description": "Owners is a list of owners for the source.", - "type": "array", - "items": { - "type": "string" - } + "fake": { + "description": "Fake configures a store with static key/value pairs", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProvider" + } + ] }, - "remote": { - "description": "Remote is the source URL, including scheme.", + "onpremises": { + "description": "Onprem configures a store in on-premises environments", "allOf": [ { - "$ref": "#/definitions/url.URL" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.OnPremisesProvider" } ] }, - "sourceProvider": { - "description": "SourceProvider is the type of the source provider.", + "vault": { + "description": "Vault configures a store to retrieve secrets from HashiCorp Vault.", "allOf": [ { - "$ref": "#/definitions/constant.SourceProviderType" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultProvider" } ] }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the source.", - "type": "string" + "viettelcloud": { + "description": "ViettelCloud configures a store to retrieve secrets from ViettelCloud Secrets Manager.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ViettelCloudProvider" + } + ] } } }, - "entity.Stack": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Resource": { "type": "object", "properties": { - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the stack.", - "type": "string" - }, - "description": { - "description": "Description is a human-readable description of the stack.", - "type": "string" - }, - "desiredVersion": { - "description": "Desired is the desired version of stack.", - "type": "string" - }, - "displayName": { - "description": "DisplayName is the human-readable display nams.", - "type": "string" - }, - "id": { - "description": "ID is the id of the stack.", - "type": "integer" + "attributes": { + "description": "Attributes represents all specified attributes of this resource", + "type": "object", + "additionalProperties": true }, - "labels": { - "description": "Labels are custom labels associated with the stack.", + "dependsOn": { + "description": "DependsOn contains all resources this resource depends on", "type": "array", "items": { "type": "string" } }, - "lastAppliedRevision": { - "description": "LastAppliedRevision is the spec ID of the last apply operation for the stack.", - "type": "string" - }, - "lastAppliedTimestamp": { - "description": "LastAppliedTimestamp is the timestamp of the last apply operation for the stack.", - "type": "string" - }, - "lastGeneratedRevision": { - "description": "LastGeneratedRevision is the spec ID of the last generate operation for the stack.", - "type": "string" - }, - "lastPreviewedRevision": { - "description": "LastPreviewedRevision is the spec ID of the last preview operation for the stack.", - "type": "string" - }, - "name": { - "description": "Name is the name of the stack.", - "type": "string" - }, - "owners": { - "description": "Owners is a list of owners for the stack.", - "type": "array", - "items": { - "type": "string" - } + "extensions": { + "description": "Extensions specifies arbitrary metadata of this resource", + "type": "object", + "additionalProperties": true }, - "path": { - "description": "Path is the relative path of the stack within the sourcs.", + "id": { + "description": "ID is the unique key of this resource.\nApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources.\nproviderNamespace:providerName:resourceType:resourceName for Terraform resources", "type": "string" }, - "project": { - "description": "Project is the project associated with the stack.", - "allOf": [ - { - "$ref": "#/definitions/entity.Project" - } - ] - }, - "syncState": { - "description": "SyncState is the current state of the stack.", + "type": { + "description": "Type represents all Context we supported like Kubernetes and Terraform", "allOf": [ { - "$ref": "#/definitions/constant.StackState" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type" } ] - }, - "type": { - "description": "Type is the type of the stack.", - "type": "string" - }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the stack.", - "type": "string" } } }, - "entity.Workspace": { + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore": { "type": "object", "properties": { - "backend": { - "description": "Backend is the corresponding backend for this workspace.", + "provider": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ProviderSpec" + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Spec": { + "type": "object", + "properties": { + "context": { + "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", "allOf": [ { - "$ref": "#/definitions/entity.Backend" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig" } ] }, - "creationTimestamp": { - "description": "CreationTimestamp is the timestamp of the created for the workspace.", - "type": "string" + "resources": { + "description": "Resources is the list of Resource this Spec contains.", + "type": "array", + "items": { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Resource" + } }, - "description": { - "description": "Description is a human-readable description of the workspace.", + "secretStore": { + "description": "SecretSore represents a external secret store location for storing secrets.", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore" + } + ] + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type": { + "type": "string", + "enum": [ + "Kubernetes", + "Terraform" + ], + "x-enum-varnames": [ + "Kubernetes", + "Terraform" + ] + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultKVStoreVersion": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "x-enum-varnames": [ + "VaultKVStoreV1", + "VaultKVStoreV2" + ] + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultProvider": { + "type": "object", + "properties": { + "path": { + "description": "Path is the mount path of the Vault KV backend endpoint, e.g: \"secret\".", "type": "string" }, - "displayName": { - "description": "DisplayName is the human-readable display name.", + "server": { + "description": "Server is the target Vault server address to connect, e.g: \"https://vault.example.com:8200\".", "type": "string" }, - "id": { - "description": "ID is the id of the workspace.", - "type": "integer" - }, - "labels": { - "description": "Labels are custom labels associated with the workspace.", - "type": "array", - "items": { - "type": "string" - } - }, - "name": { - "description": "Name is the name of the workspace.", + "version": { + "description": "Version is the Vault KV secret engine version. Version can be either \"v1\" or\n\"v2\", defaults to \"v2\".", + "allOf": [ + { + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultKVStoreVersion" + } + ] + } + } + }, + "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ViettelCloudProvider": { + "type": "object", + "properties": { + "cmpURL": { + "description": "ViettelCloud CMP URL to be used to interact with ViettelCloud Secrets Manager.\nExamples are https://console.viettelcloud.vn/api/", "type": "string" }, - "owners": { - "description": "Owners is a list of owners for the workspace.", - "type": "array", - "items": { - "type": "string" - } - }, - "updateTimestamp": { - "description": "UpdateTimestamp is the timestamp of the updated for the workspace.", + "projectID": { + "description": "ProjectID to be used to interact with ViettelCloud Secrets Manager.", "type": "string" } } }, - "kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type": { - "type": "string", - "enum": [ - "Kubernetes", - "Terraform" - ], - "x-enum-varnames": [ - "Kubernetes", - "Terraform" - ] - }, "models.ActionType": { "type": "integer", "enum": [ @@ -3710,7 +4693,7 @@ "description": "BackendConfig is the configuration of the backend.", "allOf": [ { - "$ref": "#/definitions/v1.BackendConfig" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig" } ] }, @@ -3922,6 +4905,55 @@ } } }, + "request.CreateVariableLabelsRequest": { + "type": "object", + "required": [ + "labels", + "variableKey" + ], + "properties": { + "labels": { + "description": "Labels is the list of variable labels, which should be sorted\nin ascending order of priority.", + "type": "array", + "items": { + "type": "string" + } + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", + "type": "string" + } + } + }, + "request.CreateVariableSetRequest": { + "type": "object", + "required": [ + "type", + "value", + "variableKey" + ], + "properties": { + "labels": { + "description": "Labels clarifies the scope of the variable.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "type": { + "description": "Type is the type of the variable.", + "type": "string" + }, + "value": { + "description": "Value is the value of the variable.", + "type": "string" + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", + "type": "string" + } + } + }, "request.CreateWorkspaceRequest": { "type": "object", "required": [ @@ -3958,6 +4990,21 @@ } } }, + "request.ListVariableSetRequest": { + "type": "object", + "required": [ + "labels" + ], + "properties": { + "labels": { + "description": "Labels clarifies the scope of the variables.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, "request.StackImportRequest": { "type": "object", "properties": { @@ -3980,7 +5027,7 @@ "description": "BackendConfig is the configuration of the backend.", "allOf": [ { - "$ref": "#/definitions/v1.BackendConfig" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig" } ] }, @@ -4207,488 +5254,184 @@ }, "projectName": { "description": "ProjectName is the project name of the stack within the source.", - "type": "string" - }, - "type": { - "description": "Type is the type of the stack.", - "type": "string" - } - } - }, - "request.UpdateWorkspaceRequest": { - "type": "object", - "required": [ - "backendID", - "id", - "owners" - ], - "properties": { - "backendID": { - "description": "BackendID is the configuration backend id associated with the workspace.", - "type": "integer" - }, - "description": { - "description": "Description is a human-readable description of the workspace.", - "type": "string" - }, - "id": { - "description": "ID is the id of the workspace.", - "type": "integer" - }, - "labels": { - "description": "Labels are custom labels associated with the workspace.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "name": { - "description": "Name is the name of the workspace.", - "type": "string" - }, - "owners": { - "description": "Owners is a list of owners for the workspace.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "request.WorkspaceConfigs": { - "type": "object", - "properties": { - "context": { - "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", - "allOf": [ - { - "$ref": "#/definitions/v1.GenericConfig" - } - ] - }, - "modules": { - "description": "Modules are the configs of a set of modules.", - "allOf": [ - { - "$ref": "#/definitions/v1.ModuleConfigs" - } - ] - }, - "secretStore": { - "description": "SecretStore represents a secure external location for storing secrets.", - "allOf": [ - { - "$ref": "#/definitions/v1.SecretStore" - } - ] - } - } - }, - "url.URL": { - "type": "object", - "properties": { - "forceQuery": { - "description": "append a query ('?') even if RawQuery is empty", - "type": "boolean" - }, - "fragment": { - "description": "fragment for references, without '#'", - "type": "string" - }, - "host": { - "description": "host or host:port (see Hostname and Port methods)", - "type": "string" - }, - "omitHost": { - "description": "do not emit empty host (authority)", - "type": "boolean" - }, - "opaque": { - "description": "encoded opaque data", - "type": "string" - }, - "path": { - "description": "path (relative paths may omit leading slash)", - "type": "string" - }, - "rawFragment": { - "description": "encoded fragment hint (see EscapedFragment method)", - "type": "string" - }, - "rawPath": { - "description": "encoded path hint (see EscapedPath method)", - "type": "string" - }, - "rawQuery": { - "description": "encoded query values, without '?'", - "type": "string" - }, - "scheme": { - "type": "string" - }, - "user": { - "description": "username and password information", - "allOf": [ - { - "$ref": "#/definitions/url.Userinfo" - } - ] - } - } - }, - "url.Userinfo": { - "type": "object" - }, - "v1.AWSProvider": { - "type": "object", - "properties": { - "profile": { - "description": "The profile to be used to interact with AWS Secrets Manager.\nIf not set, the default profile created with `aws configure` will be used.", - "type": "string" - }, - "region": { - "description": "AWS Region to be used to interact with AWS Secrets Manager.\nExamples are us-east-1, us-west-2, etc.", - "type": "string" - } - } - }, - "v1.AlicloudProvider": { - "type": "object", - "properties": { - "region": { - "description": "Alicloud Region to be used to interact with Alicloud Secrets Manager.\nExamples are cn-beijing, cn-shanghai, etc.", - "type": "string" - } - } - }, - "v1.AzureEnvironmentType": { - "type": "string", - "enum": [ - "PublicCloud", - "USGovernmentCloud", - "ChinaCloud", - "GermanCloud" - ], - "x-enum-varnames": [ - "AzureEnvironmentPublicCloud", - "AzureEnvironmentUSGovernmentCloud", - "AzureEnvironmentChinaCloud", - "AzureEnvironmentGermanCloud" - ] - }, - "v1.AzureKVProvider": { - "type": "object", - "properties": { - "environmentType": { - "description": "EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure.\nBy-default it points to the public cloud AAD endpoint, and the following endpoints are available:\nPublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\nRef: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152", - "allOf": [ - { - "$ref": "#/definitions/v1.AzureEnvironmentType" - } - ] - }, - "tenantId": { - "description": "TenantID configures the Azure Tenant to send requests to.", - "type": "string" - }, - "vaultUrl": { - "description": "Vault Url from which the secrets to be fetched from.", - "type": "string" - } - } - }, - "v1.BackendConfig": { - "type": "object", - "properties": { - "configs": { - "description": "Configs contains config items of the backend, whose keys differ from different backend types.", - "type": "object", - "additionalProperties": {} + "type": "string" }, "type": { - "description": "Type is the backend type, supports BackendTypeLocal, BackendTypeOss, BackendTypeS3.", + "description": "Type is the type of the stack.", "type": "string" } } }, - "v1.Configs": { - "type": "object", - "properties": { - "default": { - "description": "Default is default block of the module config.", - "allOf": [ - { - "$ref": "#/definitions/v1.GenericConfig" - } - ] - } - } - }, - "v1.FakeProvider": { + "request.UpdateVariableLabelsRequest": { "type": "object", + "required": [ + "labels", + "variableKey" + ], "properties": { - "data": { + "labels": { + "description": "Labels is the list of variable labels, which should be sorted\nin ascending order of priority.", "type": "array", "items": { - "$ref": "#/definitions/v1.FakeProviderData" + "type": "string" } + }, + "variableKey": { + "description": "VariableKey is the access path for the variable.", + "type": "string" } } }, - "v1.FakeProviderData": { + "request.UpdateVariableRequest": { "type": "object", "properties": { + "isSecret": { + "type": "boolean" + }, "key": { + "description": "key is the unique index to use value in specific stack", "type": "string" }, - "value": { + "path": { + "description": "Path is the relative path of the stack within the source.", "type": "string" }, - "valueMap": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "project": { + "description": "Project is the project related to stack", + "type": "string" }, - "version": { + "secretValue": { + "$ref": "#/definitions/entity.SecretValue" + }, + "value": { + "description": "value is the plain value of no sensitive data", "type": "string" } } }, - "v1.GenericConfig": { - "type": "object", - "additionalProperties": {} - }, - "v1.ModuleConfig": { + "request.UpdateWorkspaceRequest": { "type": "object", + "required": [ + "backendID", + "id", + "owners" + ], "properties": { - "configs": { - "description": "Configs contains all levels of module configs", - "allOf": [ - { - "$ref": "#/definitions/v1.Configs" - } - ] + "backendID": { + "description": "BackendID is the configuration backend id associated with the workspace.", + "type": "integer" }, - "path": { - "description": "Path is the path of the module. It can be a local path or a remote URL", + "description": { + "description": "Description is a human-readable description of the workspace.", "type": "string" }, - "version": { - "description": "Version is the version of the module.", - "type": "string" - } - } - }, - "v1.ModuleConfigs": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1.ModuleConfig" - } - }, - "v1.ModulePatcherConfig": { - "type": "object", - "properties": { - "projectSelector": { - "description": "ProjectSelector contains the selected projects.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "v1.OnPremisesProvider": { - "type": "object", - "properties": { - "attributes": { - "description": "attributes of the provider", + "id": { + "description": "ID is the id of the workspace.", + "type": "integer" + }, + "labels": { + "description": "Labels are custom labels associated with the workspace.", "type": "object", "additionalProperties": { "type": "string" } }, "name": { - "description": "platform name of the provider", + "description": "Name is the name of the workspace.", "type": "string" + }, + "owners": { + "description": "Owners is a list of owners for the workspace.", + "type": "array", + "items": { + "type": "string" + } } } }, - "v1.ProviderSpec": { + "request.WorkspaceConfigs": { "type": "object", "properties": { - "alicloud": { - "description": "Alicloud configures a store to retrieve secrets from Alicloud Secrets Manager.", - "allOf": [ - { - "$ref": "#/definitions/v1.AlicloudProvider" - } - ] - }, - "aws": { - "description": "AWS configures a store to retrieve secrets from AWS Secrets Manager.", - "allOf": [ - { - "$ref": "#/definitions/v1.AWSProvider" - } - ] - }, - "azure": { - "description": "Azure configures a store to retrieve secrets from Azure KeyVault.", - "allOf": [ - { - "$ref": "#/definitions/v1.AzureKVProvider" - } - ] - }, - "fake": { - "description": "Fake configures a store with static key/value pairs", - "allOf": [ - { - "$ref": "#/definitions/v1.FakeProvider" - } - ] - }, - "onpremises": { - "description": "Onprem configures a store in on-premises environments", + "context": { + "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", "allOf": [ { - "$ref": "#/definitions/v1.OnPremisesProvider" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig" } ] }, - "vault": { - "description": "Vault configures a store to retrieve secrets from HashiCorp Vault.", + "modules": { + "description": "Modules are the configs of a set of modules.", "allOf": [ { - "$ref": "#/definitions/v1.VaultProvider" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfigs" } ] }, - "viettelcloud": { - "description": "ViettelCloud configures a store to retrieve secrets from ViettelCloud Secrets Manager.", + "secretStore": { + "description": "SecretStore represents a secure external location for storing secrets.", "allOf": [ { - "$ref": "#/definitions/v1.ViettelCloudProvider" + "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore" } ] } } }, - "v1.Resource": { + "url.URL": { "type": "object", "properties": { - "attributes": { - "description": "Attributes represents all specified attributes of this resource", - "type": "object", - "additionalProperties": true - }, - "dependsOn": { - "description": "DependsOn contains all resources this resource depends on", - "type": "array", - "items": { - "type": "string" - } + "forceQuery": { + "description": "append a query ('?') even if RawQuery is empty", + "type": "boolean" }, - "extensions": { - "description": "Extensions specifies arbitrary metadata of this resource", - "type": "object", - "additionalProperties": true + "fragment": { + "description": "fragment for references, without '#'", + "type": "string" }, - "id": { - "description": "ID is the unique key of this resource.\nApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources.\nproviderNamespace:providerName:resourceType:resourceName for Terraform resources", + "host": { + "description": "host or host:port (see Hostname and Port methods)", "type": "string" }, - "type": { - "description": "Type represents all Context we supported like Kubernetes and Terraform", - "allOf": [ - { - "$ref": "#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type" - } - ] - } - } - }, - "v1.SecretStore": { - "type": "object", - "properties": { - "provider": { - "$ref": "#/definitions/v1.ProviderSpec" - } - } - }, - "v1.Spec": { - "type": "object", - "properties": { - "context": { - "description": "Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc.", - "allOf": [ - { - "$ref": "#/definitions/v1.GenericConfig" - } - ] + "omitHost": { + "description": "do not emit empty host (authority)", + "type": "boolean" }, - "resources": { - "description": "Resources is the list of Resource this Spec contains.", - "type": "array", - "items": { - "$ref": "#/definitions/v1.Resource" - } + "opaque": { + "description": "encoded opaque data", + "type": "string" }, - "secretStore": { - "description": "SecretSore represents a external secret store location for storing secrets.", - "allOf": [ - { - "$ref": "#/definitions/v1.SecretStore" - } - ] - } - } - }, - "v1.VaultKVStoreVersion": { - "type": "string", - "enum": [ - "v1", - "v2" - ], - "x-enum-varnames": [ - "VaultKVStoreV1", - "VaultKVStoreV2" - ] - }, - "v1.VaultProvider": { - "type": "object", - "properties": { "path": { - "description": "Path is the mount path of the Vault KV backend endpoint, e.g: \"secret\".", + "description": "path (relative paths may omit leading slash)", "type": "string" }, - "server": { - "description": "Server is the target Vault server address to connect, e.g: \"https://vault.example.com:8200\".", + "rawFragment": { + "description": "encoded fragment hint (see EscapedFragment method)", "type": "string" }, - "version": { - "description": "Version is the Vault KV secret engine version. Version can be either \"v1\" or\n\"v2\", defaults to \"v2\".", + "rawPath": { + "description": "encoded path hint (see EscapedPath method)", + "type": "string" + }, + "rawQuery": { + "description": "encoded query values, without '?'", + "type": "string" + }, + "scheme": { + "type": "string" + }, + "user": { + "description": "username and password information", "allOf": [ { - "$ref": "#/definitions/v1.VaultKVStoreVersion" + "$ref": "#/definitions/url.Userinfo" } ] } } }, - "v1.ViettelCloudProvider": { - "type": "object", - "properties": { - "cmpURL": { - "description": "ViettelCloud CMP URL to be used to interact with ViettelCloud Secrets Manager.\nExamples are https://console.viettelcloud.vn/api/", - "type": "string" - }, - "projectID": { - "description": "ProjectID to be used to interact with ViettelCloud Secrets Manager.", - "type": "string" - } - } + "url.Userinfo": { + "type": "object" } } } \ No newline at end of file diff --git a/api/openapispec/swagger.yaml b/api/openapispec/swagger.yaml index b9b1d639..665279d1 100644 --- a/api/openapispec/swagger.yaml +++ b/api/openapispec/swagger.yaml @@ -81,7 +81,7 @@ definitions: properties: backendConfig: allOf: - - $ref: '#/definitions/v1.BackendConfig' + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig' description: |- // Type is the type of the backend. Type string `yaml:"type" json:"type"` @@ -317,9 +317,7 @@ definitions: description: ID is the id of the run. type: integer logs: - description: |- - Result RunResult `yaml:"result" json:"result"` - Logs is the logs of the run. + description: Logs is the logs of the run. type: string result: description: Result is the result of the run. @@ -332,6 +330,9 @@ definitions: allOf: - $ref: '#/definitions/constant.RunStatus' description: Status is the status of the run. + trace: + description: Trace is the trace of the run. + type: string type: allOf: - $ref: '#/definitions/constant.RunType' @@ -343,6 +344,25 @@ definitions: description: Workspace is the target workspace of the run. type: string type: object + entity.SecretStore: + properties: + provider: + additionalProperties: {} + type: object + providerType: + type: string + type: object + entity.SecretValue: + properties: + ref: + description: Ref will only return with the update secret variable + type: string + secretStore: + $ref: '#/definitions/entity.SecretStore' + value: + description: Value to store in the secret store. + type: string + type: object entity.Source: properties: creationTimestamp: @@ -443,6 +463,48 @@ definitions: description: UpdateTimestamp is the timestamp of the updated for the stack. type: string type: object + entity.Variable: + properties: + fqn: + description: Fqn is the fully qualified name of the variable. + type: string + labels: + additionalProperties: + type: string + description: Labels clarifies the scope of the variable. + type: object + type: + description: Type is the type of the variable. + type: string + value: + description: Value is the value of the variable. + type: string + variableKey: + description: VariableKey is the access path for the variable. + type: string + type: object + entity.VariableLabels: + properties: + labels: + description: |- + Labels is the list of variable labels, which should be sorted + in ascending order of priority. + items: + type: string + type: array + variableKey: + description: VariableKey is the access path for the variable. + type: string + type: object + entity.VariableLabelsListResult: + properties: + total: + type: integer + variableLabels: + items: + $ref: '#/definitions/entity.VariableLabels' + type: array + type: object entity.Workspace: properties: backend: @@ -478,6 +540,218 @@ definitions: description: UpdateTimestamp is the timestamp of the updated for the workspace. type: string type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AWSProvider: + properties: + profile: + description: |- + The profile to be used to interact with AWS Secrets Manager. + If not set, the default profile created with `aws configure` will be used. + type: string + region: + description: |- + AWS Region to be used to interact with AWS Secrets Manager. + Examples are us-east-1, us-west-2, etc. + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AlicloudProvider: + properties: + region: + description: |- + Alicloud Region to be used to interact with Alicloud Secrets Manager. + Examples are cn-beijing, cn-shanghai, etc. + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureEnvironmentType: + enum: + - PublicCloud + - USGovernmentCloud + - ChinaCloud + - GermanCloud + type: string + x-enum-varnames: + - AzureEnvironmentPublicCloud + - AzureEnvironmentUSGovernmentCloud + - AzureEnvironmentChinaCloud + - AzureEnvironmentGermanCloud + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureKVProvider: + properties: + environmentType: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureEnvironmentType' + description: |- + EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. + By-default it points to the public cloud AAD endpoint, and the following endpoints are available: + PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud + Ref: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 + tenantId: + description: TenantID configures the Azure Tenant to send requests to. + type: string + vaultUrl: + description: Vault Url from which the secrets to be fetched from. + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig: + properties: + configs: + additionalProperties: {} + description: Configs contains config items of the backend, whose keys differ + from different backend types. + type: object + type: + description: Type is the backend type, supports BackendTypeLocal, BackendTypeOss, + BackendTypeS3. + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Configs: + properties: + default: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig' + description: Default is default block of the module config. + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProvider: + properties: + data: + items: + $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProviderData' + type: array + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProviderData: + properties: + key: + type: string + value: + type: string + valueMap: + additionalProperties: + type: string + type: object + version: + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig: + additionalProperties: {} + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfig: + properties: + configs: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Configs' + description: Configs contains all levels of module configs + path: + description: Path is the path of the module. It can be a local path or a remote + URL + type: string + version: + description: Version is the version of the module. + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfigs: + additionalProperties: + $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfig' + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModulePatcherConfig: + properties: + projectSelector: + description: ProjectSelector contains the selected projects. + items: + type: string + type: array + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.OnPremisesProvider: + properties: + attributes: + additionalProperties: + type: string + description: attributes of the provider + type: object + name: + description: platform name of the provider + type: string + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ProviderSpec: + properties: + alicloud: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AlicloudProvider' + description: Alicloud configures a store to retrieve secrets from Alicloud + Secrets Manager. + aws: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AWSProvider' + description: AWS configures a store to retrieve secrets from AWS Secrets Manager. + azure: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.AzureKVProvider' + description: Azure configures a store to retrieve secrets from Azure KeyVault. + fake: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.FakeProvider' + description: Fake configures a store with static key/value pairs + onpremises: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.OnPremisesProvider' + description: Onprem configures a store in on-premises environments + vault: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultProvider' + description: Vault configures a store to retrieve secrets from HashiCorp Vault. + viettelcloud: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ViettelCloudProvider' + description: ViettelCloud configures a store to retrieve secrets from ViettelCloud + Secrets Manager. + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Resource: + properties: + attributes: + additionalProperties: true + description: Attributes represents all specified attributes of this resource + type: object + dependsOn: + description: DependsOn contains all resources this resource depends on + items: + type: string + type: array + extensions: + additionalProperties: true + description: Extensions specifies arbitrary metadata of this resource + type: object + id: + description: |- + ID is the unique key of this resource. + ApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources. + providerNamespace:providerName:resourceType:resourceName for Terraform resources + type: string + type: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type' + description: Type represents all Context we supported like Kubernetes and + Terraform + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore: + properties: + provider: + $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ProviderSpec' + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Spec: + properties: + context: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig' + description: Context contains workspace-level configurations, such as runtimes, + topologies, and metadata, etc. + resources: + description: Resources is the list of Resource this Spec contains. + items: + $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Resource' + type: array + secretStore: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore' + description: SecretSore represents a external secret store location for storing + secrets. + type: object kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type: enum: - Kubernetes @@ -486,6 +760,41 @@ definitions: x-enum-varnames: - Kubernetes - Terraform + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultKVStoreVersion: + enum: + - v1 + - v2 + type: string + x-enum-varnames: + - VaultKVStoreV1 + - VaultKVStoreV2 + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultProvider: + properties: + path: + description: 'Path is the mount path of the Vault KV backend endpoint, e.g: + "secret".' + type: string + server: + description: 'Server is the target Vault server address to connect, e.g: "https://vault.example.com:8200".' + type: string + version: + allOf: + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.VaultKVStoreVersion' + description: |- + Version is the Vault KV secret engine version. Version can be either "v1" or + "v2", defaults to "v2". + type: object + kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ViettelCloudProvider: + properties: + cmpURL: + description: |- + ViettelCloud CMP URL to be used to interact with ViettelCloud Secrets Manager. + Examples are https://console.viettelcloud.vn/api/ + type: string + projectID: + description: ProjectID to be used to interact with ViettelCloud Secrets Manager. + type: string + type: object models.ActionType: enum: - 0 @@ -535,7 +844,7 @@ definitions: properties: backendConfig: allOf: - - $ref: '#/definitions/v1.BackendConfig' + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig' description: BackendConfig is the configuration of the backend. description: description: Description is a human-readable description of the backend. @@ -689,14 +998,51 @@ definitions: required: - name type: object - request.CreateWorkspaceRequest: + request.CreateVariableLabelsRequest: properties: - backendID: - description: BackendID is the configuration backend id associated with the - workspace. - type: integer - description: - description: Description is a human-readable description of the workspace. + labels: + description: |- + Labels is the list of variable labels, which should be sorted + in ascending order of priority. + items: + type: string + type: array + variableKey: + description: VariableKey is the access path for the variable. + type: string + required: + - labels + - variableKey + type: object + request.CreateVariableSetRequest: + properties: + labels: + additionalProperties: + type: string + description: Labels clarifies the scope of the variable. + type: object + type: + description: Type is the type of the variable. + type: string + value: + description: Value is the value of the variable. + type: string + variableKey: + description: VariableKey is the access path for the variable. + type: string + required: + - type + - value + - variableKey + type: object + request.CreateWorkspaceRequest: + properties: + backendID: + description: BackendID is the configuration backend id associated with the + workspace. + type: integer + description: + description: Description is a human-readable description of the workspace. type: string labels: description: Labels are custom labels associated with the workspace. @@ -716,6 +1062,16 @@ definitions: - name - owners type: object + request.ListVariableSetRequest: + properties: + labels: + additionalProperties: + type: string + description: Labels clarifies the scope of the variables. + type: object + required: + - labels + type: object request.StackImportRequest: properties: importedResources: @@ -727,7 +1083,7 @@ definitions: properties: backendConfig: allOf: - - $ref: '#/definitions/v1.BackendConfig' + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.BackendConfig' description: BackendConfig is the configuration of the backend. description: description: Description is a human-readable description of the backend. @@ -900,6 +1256,41 @@ definitions: - id - name type: object + request.UpdateVariableLabelsRequest: + properties: + labels: + description: |- + Labels is the list of variable labels, which should be sorted + in ascending order of priority. + items: + type: string + type: array + variableKey: + description: VariableKey is the access path for the variable. + type: string + required: + - labels + - variableKey + type: object + request.UpdateVariableRequest: + properties: + isSecret: + type: boolean + key: + description: key is the unique index to use value in specific stack + type: string + path: + description: Path is the relative path of the stack within the source. + type: string + project: + description: Project is the project related to stack + type: string + secretValue: + $ref: '#/definitions/entity.SecretValue' + value: + description: value is the plain value of no sensitive data + type: string + type: object request.UpdateWorkspaceRequest: properties: backendID: @@ -934,16 +1325,16 @@ definitions: properties: context: allOf: - - $ref: '#/definitions/v1.GenericConfig' + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.GenericConfig' description: Context contains workspace-level configurations, such as runtimes, topologies, and metadata, etc. modules: allOf: - - $ref: '#/definitions/v1.ModuleConfigs' + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.ModuleConfigs' description: Modules are the configs of a set of modules. secretStore: allOf: - - $ref: '#/definitions/v1.SecretStore' + - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.SecretStore' description: SecretStore represents a secure external location for storing secrets. type: object @@ -985,253 +1376,6 @@ definitions: type: object url.Userinfo: type: object - v1.AWSProvider: - properties: - profile: - description: |- - The profile to be used to interact with AWS Secrets Manager. - If not set, the default profile created with `aws configure` will be used. - type: string - region: - description: |- - AWS Region to be used to interact with AWS Secrets Manager. - Examples are us-east-1, us-west-2, etc. - type: string - type: object - v1.AlicloudProvider: - properties: - region: - description: |- - Alicloud Region to be used to interact with Alicloud Secrets Manager. - Examples are cn-beijing, cn-shanghai, etc. - type: string - type: object - v1.AzureEnvironmentType: - enum: - - PublicCloud - - USGovernmentCloud - - ChinaCloud - - GermanCloud - type: string - x-enum-varnames: - - AzureEnvironmentPublicCloud - - AzureEnvironmentUSGovernmentCloud - - AzureEnvironmentChinaCloud - - AzureEnvironmentGermanCloud - v1.AzureKVProvider: - properties: - environmentType: - allOf: - - $ref: '#/definitions/v1.AzureEnvironmentType' - description: |- - EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. - By-default it points to the public cloud AAD endpoint, and the following endpoints are available: - PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud - Ref: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 - tenantId: - description: TenantID configures the Azure Tenant to send requests to. - type: string - vaultUrl: - description: Vault Url from which the secrets to be fetched from. - type: string - type: object - v1.BackendConfig: - properties: - configs: - additionalProperties: {} - description: Configs contains config items of the backend, whose keys differ - from different backend types. - type: object - type: - description: Type is the backend type, supports BackendTypeLocal, BackendTypeOss, - BackendTypeS3. - type: string - type: object - v1.Configs: - properties: - default: - allOf: - - $ref: '#/definitions/v1.GenericConfig' - description: Default is default block of the module config. - type: object - v1.FakeProvider: - properties: - data: - items: - $ref: '#/definitions/v1.FakeProviderData' - type: array - type: object - v1.FakeProviderData: - properties: - key: - type: string - value: - type: string - valueMap: - additionalProperties: - type: string - type: object - version: - type: string - type: object - v1.GenericConfig: - additionalProperties: {} - type: object - v1.ModuleConfig: - properties: - configs: - allOf: - - $ref: '#/definitions/v1.Configs' - description: Configs contains all levels of module configs - path: - description: Path is the path of the module. It can be a local path or a remote - URL - type: string - version: - description: Version is the version of the module. - type: string - type: object - v1.ModuleConfigs: - additionalProperties: - $ref: '#/definitions/v1.ModuleConfig' - type: object - v1.ModulePatcherConfig: - properties: - projectSelector: - description: ProjectSelector contains the selected projects. - items: - type: string - type: array - type: object - v1.OnPremisesProvider: - properties: - attributes: - additionalProperties: - type: string - description: attributes of the provider - type: object - name: - description: platform name of the provider - type: string - type: object - v1.ProviderSpec: - properties: - alicloud: - allOf: - - $ref: '#/definitions/v1.AlicloudProvider' - description: Alicloud configures a store to retrieve secrets from Alicloud - Secrets Manager. - aws: - allOf: - - $ref: '#/definitions/v1.AWSProvider' - description: AWS configures a store to retrieve secrets from AWS Secrets Manager. - azure: - allOf: - - $ref: '#/definitions/v1.AzureKVProvider' - description: Azure configures a store to retrieve secrets from Azure KeyVault. - fake: - allOf: - - $ref: '#/definitions/v1.FakeProvider' - description: Fake configures a store with static key/value pairs - onpremises: - allOf: - - $ref: '#/definitions/v1.OnPremisesProvider' - description: Onprem configures a store in on-premises environments - vault: - allOf: - - $ref: '#/definitions/v1.VaultProvider' - description: Vault configures a store to retrieve secrets from HashiCorp Vault. - viettelcloud: - allOf: - - $ref: '#/definitions/v1.ViettelCloudProvider' - description: ViettelCloud configures a store to retrieve secrets from ViettelCloud - Secrets Manager. - type: object - v1.Resource: - properties: - attributes: - additionalProperties: true - description: Attributes represents all specified attributes of this resource - type: object - dependsOn: - description: DependsOn contains all resources this resource depends on - items: - type: string - type: array - extensions: - additionalProperties: true - description: Extensions specifies arbitrary metadata of this resource - type: object - id: - description: |- - ID is the unique key of this resource. - ApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources. - providerNamespace:providerName:resourceType:resourceName for Terraform resources - type: string - type: - allOf: - - $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Type' - description: Type represents all Context we supported like Kubernetes and - Terraform - type: object - v1.SecretStore: - properties: - provider: - $ref: '#/definitions/v1.ProviderSpec' - type: object - v1.Spec: - properties: - context: - allOf: - - $ref: '#/definitions/v1.GenericConfig' - description: Context contains workspace-level configurations, such as runtimes, - topologies, and metadata, etc. - resources: - description: Resources is the list of Resource this Spec contains. - items: - $ref: '#/definitions/v1.Resource' - type: array - secretStore: - allOf: - - $ref: '#/definitions/v1.SecretStore' - description: SecretSore represents a external secret store location for storing - secrets. - type: object - v1.VaultKVStoreVersion: - enum: - - v1 - - v2 - type: string - x-enum-varnames: - - VaultKVStoreV1 - - VaultKVStoreV2 - v1.VaultProvider: - properties: - path: - description: 'Path is the mount path of the Vault KV backend endpoint, e.g: - "secret".' - type: string - server: - description: 'Server is the target Vault server address to connect, e.g: "https://vault.example.com:8200".' - type: string - version: - allOf: - - $ref: '#/definitions/v1.VaultKVStoreVersion' - description: |- - Version is the Vault KV secret engine version. Version can be either "v1" or - "v2", defaults to "v2". - type: object - v1.ViettelCloudProvider: - properties: - cmpURL: - description: |- - ViettelCloud CMP URL to be used to interact with ViettelCloud Secrets Manager. - Examples are https://console.viettelcloud.vn/api/ - type: string - projectID: - description: ProjectID to be used to interact with ViettelCloud Secrets Manager. - type: string - type: object info: contact: {} paths: @@ -2827,7 +2971,7 @@ paths: "200": description: Success schema: - $ref: '#/definitions/v1.Spec' + type: string "400": description: Bad Request schema: {} @@ -2876,7 +3020,7 @@ paths: "200": description: Success schema: - $ref: '#/definitions/v1.Spec' + $ref: '#/definitions/kusionstack_io_kusion_pkg_apis_api_kusion_io_v1.Spec' "400": description: Bad Request schema: {} @@ -2961,6 +3105,387 @@ paths: summary: Asynchronously preview stack tags: - stack + /api/v1/variable-labels: + get: + description: List variable labels + operationId: listVariableLabels + parameters: + - collectionFormat: csv + description: Variable labels to filter variables by. Default to all(empty) + labels. + in: query + items: + type: string + name: labels + type: array + - description: Page number of the paginated list results. Default to 1. + in: query + name: page + type: string + - description: Page size of the paginated list results. If not set, the result + won't be paginated. + in: query + name: pageSize + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + items: + $ref: '#/definitions/entity.VariableLabelsListResult' + type: array + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: List variable labels + tags: + - variable_labels + post: + consumes: + - application/json + description: Create a new set of variable labels + operationId: createVariableLabels + parameters: + - description: Created variable labels + in: body + name: variable_labels + required: true + schema: + $ref: '#/definitions/request.CreateVariableLabelsRequest' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.VariableLabels' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Create variable labels + tags: + - variable_labels + /api/v1/variable-labels/{key}: + delete: + description: Delete a specified variable with labels + operationId: deleteVariableLabels + parameters: + - description: Variable Key + in: path + name: key + required: true + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + type: string + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Delete variable labels + tags: + - variable_labels + get: + description: Get variable labels by variable key + operationId: getVariableLabels + parameters: + - description: Variable Key + in: path + name: key + required: true + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.VariableLabels' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Get variable labels + tags: + - variable_labels + put: + consumes: + - application/json + description: Update the specified variable labels + operationId: updateVariableLabels + parameters: + - description: Variable Key + in: path + name: key + required: true + type: string + - description: Updated Variable Labels + in: body + name: variable_labels + required: true + schema: + $ref: '#/definitions/request.UpdateVariableLabelsRequest' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.VariableLabels' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Update variable labels + tags: + - variable_labels + /api/v1/variables: + get: + description: List variables + operationId: listVariables + parameters: + - description: Variable labels to filter variables by. + in: body + name: variable + required: true + schema: + $ref: '#/definitions/request.ListVariableSetRequest' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.VariableLabelsListResult' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: List variables + tags: + - variable + post: + consumes: + - application/json + description: Create a new variable + operationId: createVariable + parameters: + - description: Created variable + in: body + name: variable + required: true + schema: + $ref: '#/definitions/request.CreateVariableSetRequest' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.Variable' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Create variable + tags: + - variable + /api/v1/variables/{fqn}: + delete: + description: Delete a specified variable with fqn + operationId: deleteVariable + parameters: + - description: Variable Fqn + in: path + name: fqn + required: true + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + type: string + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Delete variable + tags: + - variable + get: + description: Get variable by variable fqn + operationId: getVariable + parameters: + - description: Variable Fqn + in: path + name: fqn + required: true + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.Variable' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Get variable + tags: + - variable + put: + consumes: + - application/json + description: Update the specified variable + operationId: updateVariable + parameters: + - description: Variable Fqn + in: path + name: fqn + required: true + type: string + - description: Updated Variable + in: body + name: variable + required: true + schema: + $ref: '#/definitions/request.UpdateVariableRequest' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/entity.Variable' + "400": + description: Bad Request + schema: {} + "401": + description: Unauthorized + schema: {} + "404": + description: Not Found + schema: {} + "429": + description: Too Many Requests + schema: {} + "500": + description: Internal Server Error + schema: {} + summary: Update variable + tags: + - variable /api/v1/workspaces: get: description: List all workspaces diff --git a/pkg/domain/entity/variable.go b/pkg/domain/entity/variable.go new file mode 100644 index 00000000..3921c120 --- /dev/null +++ b/pkg/domain/entity/variable.go @@ -0,0 +1,58 @@ +package entity + +import "errors" + +const ( + PlainTextType string = "PlainText" + CipherTextType string = "CipherText" +) + +// Variable represents the specific configuration code variable, +// which usually includes the global configurations for Terraform providers like +// api host, ak and sk. +type Variable struct { + // VariableKey is the access path for the variable. + VariableKey string `yaml:"variableKey,omitempty" json:"variableKey,omitempty"` + // Value is the value of the variable. + Value string `yaml:"value,omitempty" json:"value,omitempty"` + // Type is the type of the variable. + Type string `yaml:"type,omitempty" json:"type,omitempty"` + // Labels clarifies the scope of the variable. + Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"` + // Fqn is the fully qualified name of the variable. + Fqn string `yaml:"fqn,omitempty" json:"fqn,omitempty"` +} + +// VariableFilter represents the filter conditions to list variables. +type VariableFilter struct { + Key string + Pagination *Pagination +} + +// VariableListResult represents the result of listing variables. +type VariableListResult struct { + Variables []*Variable + Total int +} + +// Validate checks if the variable is valid. +// It returns an error if the variable is not valid. +func (v *Variable) Validate() error { + if v == nil { + return errors.New("variable is nil") + } + + if v.VariableKey == "" { + return errors.New("empty variable key") + } + + if v.Type != PlainTextType && v.Type != CipherTextType { + return errors.New("invalid variable type") + } + + if v.Fqn == "" { + return errors.New("empty fqn") + } + + return nil +} diff --git a/pkg/domain/entity/variable_labels.go b/pkg/domain/entity/variable_labels.go new file mode 100644 index 00000000..a4e82fd3 --- /dev/null +++ b/pkg/domain/entity/variable_labels.go @@ -0,0 +1,43 @@ +package entity + +import "errors" + +// VariableLabels records the labels of the specific configuration code variable, +// and the labels are sorted in ascending order of priority. +type VariableLabels struct { + // VariableKey is the access path for the variable. + VariableKey string `yaml:"variableKey,omitempty" json:"variableKey,omitempty"` + // Labels is the list of variable labels, which should be sorted + // in ascending order of priority. + Labels []string `yaml:"labels,omitempty" json:"labels,omitempty"` +} + +// VariableLabelsFilter represents the filter conditions to list variable labels. +type VariableLabelsFilter struct { + Labels []string + Pagination *Pagination +} + +// VariableLabelsListResult represents the result of listing variable labels. +type VariableLabelsListResult struct { + VariableLabels []*VariableLabels + Total int +} + +// Validate checks if the variable labels are valid. +// It returns an error if the variable labels are not valid. +func (vl *VariableLabels) Validate() error { + if vl == nil { + return errors.New("nil variable labels") + } + + if vl.VariableKey == "" { + return errors.New("empty key for variable labels") + } + + if len(vl.Labels) == 0 { + return errors.New("empty variable labels") + } + + return nil +} diff --git a/pkg/domain/repository/repository.go b/pkg/domain/repository/repository.go index d94f4560..0142407c 100644 --- a/pkg/domain/repository/repository.go +++ b/pkg/domain/repository/repository.go @@ -152,3 +152,33 @@ type RunRepository interface { // List retrieves all existing run. List(ctx context.Context, filter *entity.RunFilter) (*entity.RunListResult, error) } + +// VariableLabelsRepository is an interface that defines the repository +// for variable labels. It follows the principles of domain-driven design (DDD). +type VariableLabelsRepository interface { + // Create creates a new set of variable labels. + Create(ctx context.Context, vl *entity.VariableLabels) error + // Delete deletes a set of variable labels by its key. + Delete(ctx context.Context, key string) error + // Update updates an existing set of variable labels. + Update(ctx context.Context, vl *entity.VariableLabels) error + // GetByKey retrieves a set of variable labels by its key. + GetByKey(ctx context.Context, key string) (*entity.VariableLabels, error) + // List retrieves all existing variable labels. + List(ctx context.Context, filter *entity.VariableLabelsFilter) (*entity.VariableLabelsListResult, error) +} + +// VariableRepository is an interface that defines the repository operations +// for variables. It follows the principles of domain-driven design (DDD). +type VariableRepository interface { + // Create creates a new variable. + Create(ctx context.Context, v *entity.Variable) error + // Delete deletes a variable by its fqn. + Delete(ctx context.Context, fqn string) error + // Update updates an existing variable. + Update(ctx context.Context, v *entity.Variable) error + // GetByFqn retrieves a variable by its fqn. + GetByFqn(ctx context.Context, fqn string) (*entity.Variable, error) + // List retrieves all existing variables. + List(ctx context.Context, filter *entity.VariableFilter) (*entity.VariableListResult, error) +} diff --git a/pkg/domain/request/variable_labels_request.go b/pkg/domain/request/variable_labels_request.go new file mode 100644 index 00000000..0c056197 --- /dev/null +++ b/pkg/domain/request/variable_labels_request.go @@ -0,0 +1,31 @@ +package request + +import "net/http" + +// CreateVariableLabelsRequest represents the create request structure +// for variable labels. +type CreateVariableLabelsRequest struct { + // VariableKey is the access path for the variable. + VariableKey string `json:"variableKey" binding:"required"` + // Labels is the list of variable labels, which should be sorted + // in ascending order of priority. + Labels []string `json:"labels" binding:"required"` +} + +// UpdateVariableLabelsRequest represents the update request structure +// for variable labels. +type UpdateVariableLabelsRequest struct { + // VariableKey is the access path for the variable. + VariableKey string `json:"variableKey" binding:"required"` + // Labels is the list of variable labels, which should be sorted + // in ascending order of priority. + Labels []string `json:"labels" binding:"required"` +} + +func (payload *CreateVariableLabelsRequest) Decode(r *http.Request) error { + return decode(r, payload) +} + +func (payload *UpdateVariableLabelsRequest) Decode(r *http.Request) error { + return decode(r, payload) +} diff --git a/pkg/domain/request/variable_request.go b/pkg/domain/request/variable_request.go new file mode 100644 index 00000000..9226ae07 --- /dev/null +++ b/pkg/domain/request/variable_request.go @@ -0,0 +1,50 @@ +package request + +import "net/http" + +// CreateVariableSetRequest represents the create request structure +// for a variable in the variable set. +type CreateVariableSetRequest struct { + // VariableKey is the access path for the variable. + VariableKey string `json:"variableKey" binding:"required"` + // Value is the value of the variable. + Value string `json:"value" binding:"required"` + // Type is the type of the variable. + Type string `json:"type" binding:"required"` + // Labels clarifies the scope of the variable. + Labels map[string]string `json:"labels,omitempty"` +} + +// UpdateVariableSetRequest represents the update request structure +// for a variable in the variable set. +type UpdateVariableSetRequest struct { + // VariableKey is the access path for the variable. + VariableKey string `json:"variableKey" binding:"required"` + // Value is the value of the variable. + Value string `json:"value" binding:"required"` + // Type is the type of the variable. + Type string `json:"type" binding:"required"` + // Labels clarifies the scope of the variable. + Labels map[string]string `json:"labels" binding:"required"` + // Fqn is the fully qualified name of the variable. + Fqn string `json:"fqn" binding:"required"` +} + +// ListVariableSetRequest represents the list request structure +// for variables matched to the labels in the variable set. +type ListVariableSetRequest struct { + // Labels clarifies the scope of the variables. + Labels map[string]string `json:"labels" binding:"required"` +} + +func (payload *CreateVariableSetRequest) Decode(r *http.Request) error { + return decode(r, payload) +} + +func (payload *UpdateVariableSetRequest) Decode(r *http.Request) error { + return decode(r, payload) +} + +func (payload *ListVariableSetRequest) Decode(r *http.Request) error { + return decode(r, payload) +} diff --git a/pkg/domain/response/variable.go b/pkg/domain/response/variable.go new file mode 100644 index 00000000..798ffa55 --- /dev/null +++ b/pkg/domain/response/variable.go @@ -0,0 +1,10 @@ +package response + +import "kusionstack.io/kusion/pkg/domain/entity" + +type PaginatedVariableResponse struct { + Variables []*entity.Variable `json:"variables"` + Total int `json:"total"` + CurrentPage int `json:"currentPage"` + PageSize int `json:"pageSize"` +} diff --git a/pkg/domain/response/variable_labels.go b/pkg/domain/response/variable_labels.go new file mode 100644 index 00000000..6c1a7cf7 --- /dev/null +++ b/pkg/domain/response/variable_labels.go @@ -0,0 +1,10 @@ +package response + +import "kusionstack.io/kusion/pkg/domain/entity" + +type PaginatedVariableLabelsResponse struct { + VariableLabels []*entity.VariableLabels `json:"variableLabels"` + Total int `json:"total"` + CurrentPage int `json:"currentPage"` + PageSize int `json:"pageSize"` +} diff --git a/pkg/infra/persistence/types.go b/pkg/infra/persistence/types.go index 356f45b1..49deb5dd 100644 --- a/pkg/infra/persistence/types.go +++ b/pkg/infra/persistence/types.go @@ -24,6 +24,8 @@ var ( ErrAppConfigModelNil = errors.New("appconfig model can't be nil") ErrFailedToGetModuleRemote = errors.New("failed to parse module remote") ErrResourceModelNil = errors.New("resource model can't be nil") + ErrVariableLabelsModelNil = errors.New("variable labels model can't be nil") + ErrVariableModelNil = errors.New("variable model can't be nil") ErrFailedToGetModuleDocRemote = errors.New("failed to parse module doc remote") ErrRunModelNil = errors.New("run model can't be nil") ErrFailedToGetRunType = errors.New("failed to parse run type") diff --git a/pkg/infra/persistence/util.go b/pkg/infra/persistence/util.go index 6683be0d..19a5543f 100644 --- a/pkg/infra/persistence/util.go +++ b/pkg/infra/persistence/util.go @@ -179,6 +179,34 @@ func GetRunQuery(filter *entity.RunFilter) (string, []interface{}) { return CombineQueryParts(pattern), args } +func GetVariableLabelsQuery(filter *entity.VariableLabelsFilter) (string, []interface{}) { + pattern := make([]string, 0) + args := make([]interface{}, 0) + + if len(filter.Labels) != 0 { + var labelsPattern []string + for _, label := range filter.Labels { + labelsPattern = append(labelsPattern, "labels LIKE ?") + args = append(args, "%"+label+"%") + } + pattern = append(pattern, "("+strings.Join(labelsPattern, " OR ")+")") + } + + return CombineQueryParts(pattern), args +} + +func GetVariableQuery(filter *entity.VariableFilter) (string, []interface{}) { + pattern := make([]string, 0) + args := make([]interface{}, 0) + + if filter.Key != "" { + pattern = append(pattern, "variable_key = ?") + args = append(args, fmt.Sprintf(filter.Key)) + } + + return CombineQueryParts(pattern), args +} + func CombineQueryParts(queryParts []string) string { queryString := "" if len(queryParts) > 0 { @@ -218,5 +246,11 @@ func AutoMigrate(db *gorm.DB) error { if err := db.AutoMigrate(&RunModel{}); err != nil { return err } + if err := db.AutoMigrate(&VariableLabelsModel{}); err != nil { + return err + } + if err := db.AutoMigrate(&VariableModel{}); err != nil { + return err + } return nil } diff --git a/pkg/infra/persistence/variable.go b/pkg/infra/persistence/variable.go new file mode 100644 index 00000000..4408fb77 --- /dev/null +++ b/pkg/infra/persistence/variable.go @@ -0,0 +1,134 @@ +//nolint:dupl +package persistence + +import ( + "context" + + "gorm.io/gorm" + "kusionstack.io/kusion/pkg/domain/entity" + "kusionstack.io/kusion/pkg/domain/repository" +) + +// The variableRepository type implements the repository.VariableRepository interface. +// If the variableRepository type does not implement all the methods of the interface, +// the compiler will produce an error. +var _ repository.VariableRepository = &variableRepository{} + +// variableRepository is a repository that stores variables in a gorm database. +type variableRepository struct { + // db is the underlying gorm database where variables are stored. + db *gorm.DB +} + +// NewVariableRepository creates a new variable repository. +func NewVariableRepository(db *gorm.DB) repository.VariableRepository { + return &variableRepository{db: db} +} + +// Create saves a variable to the repository. +func (v *variableRepository) Create(ctx context.Context, dataEntity *entity.Variable) error { + v.db.AutoMigrate(&VariableModel{}) + if err := dataEntity.Validate(); err != nil { + return err + } + + // Map the data from entity to DO. + var dataModel VariableModel + if err := dataModel.FromEntity(dataEntity); err != nil { + return err + } + + return v.db.Transaction(func(tx *gorm.DB) error { + // Create new record in the storage. + if err := tx.WithContext(ctx).Create(&dataModel).Error; err != nil { + return err + } + + // Map fresh record's data into Entity. + newEntity, err := dataModel.ToEntity() + if err != nil { + return err + } + *dataEntity = *newEntity + + return nil + }) +} + +// Delete removes a variable from the repository. +func (v *variableRepository) Delete(ctx context.Context, fqn string) error { + return v.db.Transaction(func(tx *gorm.DB) error { + var dataModel VariableModel + if err := tx.WithContext(ctx). + Where("fqn = ?", fqn).First(&dataModel).Error; err != nil { + return err + } + + return tx.WithContext(ctx).Unscoped().Delete(&dataModel).Error + }) +} + +// Update updates an existing variable in the repository. +func (v *variableRepository) Update(ctx context.Context, dataEntity *entity.Variable) error { + // Map the data from Entity to DO. + var dataModel VariableModel + if err := dataModel.FromEntity(dataEntity); err != nil { + return err + } + + if err := v.db.WithContext(ctx). + Where("fqn = ?", dataModel.Fqn).Updates(&dataModel).Error; err != nil { + return err + } + + return nil +} + +// GetByFqn retrieves a variable by its fqn. +func (v *variableRepository) GetByFqn(ctx context.Context, fqn string) (*entity.Variable, error) { + var dataModel VariableModel + if err := v.db.WithContext(ctx).Where("fqn = ?", fqn).First(&dataModel).Error; err != nil { + return nil, err + } + + return dataModel.ToEntity() +} + +// List retrieves all existing variables. +func (v *variableRepository) List(ctx context.Context, filter *entity.VariableFilter) (*entity.VariableListResult, error) { + var dataModel []VariableModel + variableEntityList := make([]*entity.Variable, 0) + pattern, args := GetVariableQuery(filter) + + var result *gorm.DB + if filter.Pagination.PageSize == 0 { + // Fetch data without pagination. + result = v.db.WithContext(ctx).Where(pattern, args...).Find(&dataModel) + } else { + // Fetch paginated data from result with offset and limit. + offset := (filter.Pagination.Page - 1) * filter.Pagination.PageSize + result = v.db.WithContext(ctx). + Where(pattern, args...).Offset(offset).Limit(filter.Pagination.PageSize).Find(&dataModel) + } + + if result.Error != nil { + return nil, result.Error + } + + for _, variable := range dataModel { + variableEntity, err := variable.ToEntity() + if err != nil { + return nil, err + } + variableEntityList = append(variableEntityList, variableEntity) + } + + // Get total rows. + var totalRows int64 + result.Model(dataModel).Count(&totalRows) + + return &entity.VariableListResult{ + Variables: variableEntityList, + Total: int(totalRows), + }, nil +} diff --git a/pkg/infra/persistence/variable_labels.go b/pkg/infra/persistence/variable_labels.go new file mode 100644 index 00000000..825798b2 --- /dev/null +++ b/pkg/infra/persistence/variable_labels.go @@ -0,0 +1,135 @@ +//nolint:dupl +package persistence + +import ( + "context" + + "gorm.io/gorm" + "kusionstack.io/kusion/pkg/domain/entity" + "kusionstack.io/kusion/pkg/domain/repository" +) + +// The variableLabelsRepository type implements the repository.VariableLabelsRepository interface. +// If the variableLabelsRepository type does not implement all the methods of the interface, +// the compiler will produce an error. +var _ repository.VariableLabelsRepository = &variableLabelsRepository{} + +// variableLabelsRepository is a repository that stores variable labels in a gorm database. +type variableLabelsRepository struct { + // db is the underlying gorm database where variable labels are stored. + db *gorm.DB +} + +// NewVariableLabelsRepository creates a new repository for variable labels. +func NewVariableLabelsRepository(db *gorm.DB) repository.VariableLabelsRepository { + return &variableLabelsRepository{db: db} +} + +// Create creates a new set of variable labels. +func (vl *variableLabelsRepository) Create(ctx context.Context, dataEntity *entity.VariableLabels) error { + vl.db.AutoMigrate(&VariableLabelsModel{}) + if err := dataEntity.Validate(); err != nil { + return err + } + + // Map the data from entity to DO. + var dataModel VariableLabelsModel + if err := dataModel.FromEntity(dataEntity); err != nil { + return err + } + + return vl.db.Transaction(func(tx *gorm.DB) error { + // Create new record in the storage. + if err := tx.WithContext(ctx).Create(&dataModel).Error; err != nil { + return err + } + + // Map fresh record's data into Entity. + newEntity, err := dataModel.ToEntity() + if err != nil { + return err + } + *dataEntity = *newEntity + + return nil + }) +} + +// Delete deletes a set of variable labels by its key. +func (vl *variableLabelsRepository) Delete(ctx context.Context, key string) error { + return vl.db.Transaction(func(tx *gorm.DB) error { + var dataModel VariableLabelsModel + if err := tx.WithContext(ctx). + Where("variable_key = ?", key).First(&dataModel).Error; err != nil { + return err + } + + return tx.WithContext(ctx).Unscoped().Delete(&dataModel).Error + }) +} + +// Update updates an existing set of variable labels. +func (vl *variableLabelsRepository) Update(ctx context.Context, dataEntity *entity.VariableLabels) error { + // Map the data from Entity to DO. + var dataModel VariableLabelsModel + if err := dataModel.FromEntity(dataEntity); err != nil { + return err + } + + if err := vl.db.WithContext(ctx). + Where("variable_key = ?", dataModel.VariableKey).Updates(&dataModel).Error; err != nil { + return err + } + + return nil +} + +// GetByKey retrieves a set of variable labels by its key. +func (vl *variableLabelsRepository) GetByKey(ctx context.Context, key string) (*entity.VariableLabels, error) { + var dataModel VariableLabelsModel + if err := vl.db.WithContext(ctx). + Where("variable_key = ?", key).First(&dataModel).Error; err != nil { + return nil, err + } + + return dataModel.ToEntity() +} + +// List retrieves all existing variable labels. +func (vl *variableLabelsRepository) List(ctx context.Context, filter *entity.VariableLabelsFilter) (*entity.VariableLabelsListResult, error) { + var dataModel []VariableLabelsModel + variableLabelsEntityList := make([]*entity.VariableLabels, 0) + pattern, args := GetVariableLabelsQuery(filter) + + var result *gorm.DB + if filter.Pagination.PageSize == 0 { + // Fetch data without pagination. + result = vl.db.WithContext(ctx).Where(pattern, args...).Find(&dataModel) + } else { + // Fetch paginated data from result with offset and limit. + offset := (filter.Pagination.Page - 1) * filter.Pagination.PageSize + result = vl.db.WithContext(ctx). + Where(pattern, args...).Offset(offset).Limit(filter.Pagination.PageSize).Find(&dataModel) + } + + if result.Error != nil { + return nil, result.Error + } + + for _, variableLabels := range dataModel { + variableLabelsEntity, err := variableLabels.ToEntity() + if err != nil { + return nil, err + } + variableLabelsEntityList = append(variableLabelsEntityList, variableLabelsEntity) + } + + // Get total rows. + var totalRows int64 + result.Model(dataModel).Count(&totalRows) + + return &entity.VariableLabelsListResult{ + VariableLabels: variableLabelsEntityList, + Total: int(totalRows), + }, nil +} diff --git a/pkg/infra/persistence/variable_labels_model.go b/pkg/infra/persistence/variable_labels_model.go new file mode 100644 index 00000000..dd651c54 --- /dev/null +++ b/pkg/infra/persistence/variable_labels_model.go @@ -0,0 +1,45 @@ +package persistence + +import ( + "gorm.io/gorm" + "kusionstack.io/kusion/pkg/domain/entity" +) + +// VariableLabelsModel is a DO used to map the entity to the database. +type VariableLabelsModel struct { + gorm.Model + // VariableKey is the access path for the variable. + VariableKey string `gorm:"index:unique_variable_labels,unique"` + // Labels is the list of variable labels, which should be sorted + // in ascending order of priority. + Labels MultiString +} + +// The TableName method returns the name of the database table that the struct is mapped to. +func (vl *VariableLabelsModel) TableName() string { + return "variable_labels" +} + +// ToEntity converts the DO to an entity. +func (vl *VariableLabelsModel) ToEntity() (*entity.VariableLabels, error) { + if vl == nil { + return nil, ErrVariableLabelsModelNil + } + + return &entity.VariableLabels{ + VariableKey: vl.VariableKey, + Labels: []string(vl.Labels), + }, nil +} + +// FromEntity converts an entity to a DO. +func (vl *VariableLabelsModel) FromEntity(e *entity.VariableLabels) error { + if vl == nil { + return ErrVariableLabelsModelNil + } + + vl.VariableKey = e.VariableKey + vl.Labels = MultiString(e.Labels) + + return nil +} diff --git a/pkg/infra/persistence/variable_model.go b/pkg/infra/persistence/variable_model.go new file mode 100644 index 00000000..aecf79b2 --- /dev/null +++ b/pkg/infra/persistence/variable_model.go @@ -0,0 +1,56 @@ +package persistence + +import ( + "gorm.io/gorm" + "kusionstack.io/kusion/pkg/domain/entity" +) + +// VariableModel is a DO used to map the entity to the database. +type VariableModel struct { + gorm.Model + // VariableKey is the access path for the variable. + VariableKey string + // Value is the value of the variable. + Value string + // Type is the type of the variable. + Type string + // Labels clarifies the scope of the variable. + Labels map[string]string `gorm:"serializer:json" json:"labels"` + // Fqn is the fully qualified name of the variable. + Fqn string `gorm:"index:unique_variable,unique"` +} + +// The TableName method returns the name of the database table that the struct is mapped to. +func (v *VariableModel) TableName() string { + return "variable" +} + +// ToEntity converts the DO to an entity. +func (v *VariableModel) ToEntity() (*entity.Variable, error) { + if v == nil { + return nil, ErrVariableModelNil + } + + return &entity.Variable{ + VariableKey: v.VariableKey, + Value: v.Value, + Type: v.Type, + Labels: v.Labels, + Fqn: v.Fqn, + }, nil +} + +// FromEntity converts an entity to a DO. +func (v *VariableModel) FromEntity(e *entity.Variable) error { + if v == nil { + return ErrVariableModelNil + } + + v.VariableKey = e.VariableKey + v.Value = e.Value + v.Type = e.Type + v.Labels = e.Labels + v.Fqn = e.Fqn + + return nil +} diff --git a/pkg/server/handler/module/handler.go b/pkg/server/handler/module/handler.go index 33776aff..757db403 100644 --- a/pkg/server/handler/module/handler.go +++ b/pkg/server/handler/module/handler.go @@ -90,7 +90,7 @@ func (h *Handler) DeleteModule() http.HandlerFunc { // @Failure 429 {object} error "Too Many Requests" // @Failure 404 {object} error "Not Found" // @Failure 500 {object} error "Internal Server Error" -// @Router /api/v1/modules/{name} [put] +// @Router /api/v1/modules/{name} [put] func (h *Handler) UpdateModule() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Getting stuff from context. @@ -126,7 +126,7 @@ func (h *Handler) UpdateModule() http.HandlerFunc { // @Failure 429 {object} error "Too Many Requests" // @Failure 404 {object} error "Not Found" // @Failure 500 {object} error "Internal Server Error" -// @Router /api/v1/modules/{name} [get] +// @Router /api/v1/modules/{name} [get] func (h *Handler) GetModule() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Getting stuff from context. diff --git a/pkg/server/handler/resource/handler.go b/pkg/server/handler/resource/handler.go index 050fb840..edb3463e 100644 --- a/pkg/server/handler/resource/handler.go +++ b/pkg/server/handler/resource/handler.go @@ -83,13 +83,13 @@ func (h *Handler) GetResource() http.HandlerFunc { // @Description Get resource graph by stack ID // @Tags resource // @Produce json -// @Param stack_id query uint true "Stack ID" -// @Success 200 {object} entity.ResourceGraph "Success" -// @Failure 400 {object} error "Bad Request" -// @Failure 401 {object} error "Unauthorized" -// @Failure 429 {object} error "Too Many Requests" -// @Failure 404 {object} error "Not Found" -// @Failure 500 {object} error "Internal Server Error" +// @Param stack_id query uint true "Stack ID" +// @Success 200 {object} entity.ResourceGraph "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" // @Router /api/v1/resources/graph [get] func (h *Handler) GetResourceGraph() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/server/handler/stack/execute.go b/pkg/server/handler/stack/execute.go index 3af7fb02..8a403e84 100644 --- a/pkg/server/handler/stack/execute.go +++ b/pkg/server/handler/stack/execute.go @@ -79,10 +79,10 @@ func (h *Handler) PreviewStack() http.HandlerFunc { // @Tags stack // @Produce json // @Param stack_id path int true "Stack ID" -// @Param workspace query string true "The target workspace to preview the spec in." +// @Param workspace query string true "The target workspace to preview the spec in." // @Param format query string false "The format to generate the spec in. Choices are: spec. Default to spec." // @Param force query bool false "Force the generate even when the stack is locked" -// @Success 200 {object} v1.Spec "Success" +// @Success 200 {object} string "Success" // @Failure 400 {object} error "Bad Request" // @Failure 401 {object} error "Unauthorized" // @Failure 429 {object} error "Too Many Requests" @@ -184,7 +184,7 @@ func (h *Handler) ApplyStack() http.HandlerFunc { // @Tags stack // @Produce json // @Param stack_id path int true "Stack ID" -// @Param workspace query string true "The target workspace to preview the spec in." +// @Param workspace query string true "The target workspace to preview the spec in." // @Param force query bool false "Force the destroy even when the stack is locked. May cause concurrency issues!!!" // @Param dryrun query bool false "Destroy in dry-run mode" // @Success 200 {object} string "Success" diff --git a/pkg/server/handler/stack/execute_async.go b/pkg/server/handler/stack/execute_async.go index 882f7e32..5aa7e9e4 100644 --- a/pkg/server/handler/stack/execute_async.go +++ b/pkg/server/handler/stack/execute_async.go @@ -234,16 +234,16 @@ func (h *Handler) ApplyStackAsync() http.HandlerFunc { // @Description Start a run and asynchronously generate stack spec by stack ID // @Tags stack // @Produce json -// @Param stack_id path int true "Stack ID" -// @Param workspace query string true "The target workspace to preview the spec in." -// @Param format query string false "The format to generate the spec in. Choices are: spec. Default to spec." -// @Param force query bool false "Force the generate even when the stack is locked" -// @Success 200 {object} v1.Spec "Success" -// @Failure 400 {object} error "Bad Request" -// @Failure 401 {object} error "Unauthorized" -// @Failure 429 {object} error "Too Many Requests" -// @Failure 404 {object} error "Not Found" -// @Failure 500 {object} error "Internal Server Error" +// @Param stack_id path int true "Stack ID" +// @Param workspace query string true "The target workspace to preview the spec in." +// @Param format query string false "The format to generate the spec in. Choices are: spec. Default to spec." +// @Param force query bool false "Force the generate even when the stack is locked" +// @Success 200 {object} apiv1.Spec "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" // @Router /api/v1/stacks/{stack_id}/generate/async [post] func (h *Handler) GenerateStackAsync() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -331,7 +331,7 @@ func (h *Handler) GenerateStackAsync() http.HandlerFunc { // @Tags stack // @Produce json // @Param stack_id path int true "Stack ID" -// @Param workspace query string true "The target workspace to preview the spec in." +// @Param workspace query string true "The target workspace to preview the spec in." // @Param force query bool false "Force the destroy even when the stack is locked. May cause concurrency issues!!!" // @Param dryrun query bool false "Destroy in dry-run mode" // @Success 200 {object} string "Success" diff --git a/pkg/server/handler/stack/handler.go b/pkg/server/handler/stack/handler.go index 6d909075..12e74193 100644 --- a/pkg/server/handler/stack/handler.go +++ b/pkg/server/handler/stack/handler.go @@ -164,17 +164,17 @@ func (h *Handler) GetStack() http.HandlerFunc { // @Description List all stacks // @Tags stack // @Produce json -// @Param projectID query uint false "ProjectID to filter stacks by. Default to all" -// @Param orgID query uint false "OrgID to filter stacks by. Default to all" -// @Param projectName query string false "ProjectName to filter stacks by. Default to all" -// @Param cloud query string false "Cloud to filter stacks by. Default to all" -// @Param env query string false "Environment to filter stacks by. Default to all" -// @Success 200 {object} []entity.Stack "Success" -// @Failure 400 {object} error "Bad Request" -// @Failure 401 {object} error "Unauthorized" -// @Failure 429 {object} error "Too Many Requests" -// @Failure 404 {object} error "Not Found" -// @Failure 500 {object} error "Internal Server Error" +// @Param projectID query uint false "ProjectID to filter stacks by. Default to all" +// @Param orgID query uint false "OrgID to filter stacks by. Default to all" +// @Param projectName query string false "ProjectName to filter stacks by. Default to all" +// @Param cloud query string false "Cloud to filter stacks by. Default to all" +// @Param env query string false "Environment to filter stacks by. Default to all" +// @Success 200 {object} []entity.Stack "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" // @Router /api/v1/stacks [get] func (h *Handler) ListStacks() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/server/handler/stack/run.go b/pkg/server/handler/stack/run.go index 92ae131d..e9aeb4e9 100644 --- a/pkg/server/handler/stack/run.go +++ b/pkg/server/handler/stack/run.go @@ -77,17 +77,17 @@ func (h *Handler) GetRunResult() http.HandlerFunc { // @Description List all runs // @Tags stack // @Produce json -// @Param projectID query uint false "ProjectID to filter runs by. Default to all" -// @Param orgID query uint false "OrgID to filter runs by. Default to all" -// @Param projectName query string false "ProjectName to filter runs by. Default to all" -// @Param cloud query string false "Cloud to filter runs by. Default to all" -// @Param env query string false "Environment to filter runs by. Default to all" -// @Success 200 {object} []entity.Stack "Success" -// @Failure 400 {object} error "Bad Request" -// @Failure 401 {object} error "Unauthorized" -// @Failure 429 {object} error "Too Many Requests" -// @Failure 404 {object} error "Not Found" -// @Failure 500 {object} error "Internal Server Error" +// @Param projectID query uint false "ProjectID to filter runs by. Default to all" +// @Param orgID query uint false "OrgID to filter runs by. Default to all" +// @Param projectName query string false "ProjectName to filter runs by. Default to all" +// @Param cloud query string false "Cloud to filter runs by. Default to all" +// @Param env query string false "Environment to filter runs by. Default to all" +// @Success 200 {object} []entity.Stack "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" // @Router /api/v1/runs [get] func (h *Handler) ListRuns() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/server/handler/variable/handler.go b/pkg/server/handler/variable/handler.go new file mode 100644 index 00000000..43ce3e11 --- /dev/null +++ b/pkg/server/handler/variable/handler.go @@ -0,0 +1,245 @@ +package variable + +import ( + "context" + "net/http" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/httplog/v2" + "github.com/go-chi/render" + "kusionstack.io/kusion/pkg/domain/entity" + "kusionstack.io/kusion/pkg/domain/request" + "kusionstack.io/kusion/pkg/server/handler" + "kusionstack.io/kusion/pkg/server/manager/variable" + logutil "kusionstack.io/kusion/pkg/server/util/logging" +) + +// @Id createVariable +// @Summary Create variable +// @Description Create a new variable +// @Tags variable +// @Accept json +// @Produce json +// @Param variable body request.CreateVariableSetRequest true "Created variable" +// @Success 200 {object} entity.Variable "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variables [post] +func (h *Handler) CreateVariable() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx := r.Context() + logger := logutil.GetLogger(ctx) + logger.Info("Creating variable...") + + // Decode the request body into the payload. + var requestPayload request.CreateVariableSetRequest + if err := requestPayload.Decode(r); err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + // Return the created entity. + createdEntity, err := h.variableManager.CreateVariable(ctx, requestPayload) + handler.HandleResult(w, r, ctx, err, createdEntity) + } +} + +// @Id deleteVariable +// @Summary Delete variable +// @Description Delete a specified variable with fqn +// @Tags variable +// @Produce json +// @Param fqn path string true "Variable Fqn" +// @Success 200 {object} string "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variables/{fqn} [delete] +func (h *Handler) DeleteVariable() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx, logger, params, err := requestHelper(r) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + logger.Info("Deleting variable...") + + err = h.variableManager.DeleteVariableByFqn(ctx, params.Fqn) + handler.HandleResult(w, r, ctx, err, "Deletion Success") + } +} + +// @Id updateVariable +// @Summary Update variable +// @Description Update the specified variable +// @Tags variable +// @Accept json +// @Produce json +// @Param fqn path string true "Variable Fqn" +// @Param variable body request.UpdateVariableRequest true "Updated Variable" +// @Success 200 {object} entity.Variable "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variables/{fqn} [put] +func (h *Handler) UpdateVariable() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx, logger, params, err := requestHelper(r) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + logger.Info("Updating variable set...") + + // Decode the request body into the payload. + var requestPayload request.UpdateVariableSetRequest + if err := requestPayload.Decode(r); err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + // Return the updated variable labels. + updatedEntity, err := h.variableManager.UpdateVariable(ctx, params.Fqn, requestPayload) + handler.HandleResult(w, r, ctx, err, updatedEntity) + } +} + +// @Id getVariable +// @Summary Get variable +// @Description Get variable by variable fqn +// @Tags variable +// @Produce json +// @Param fqn path string true "Variable Fqn" +// @Success 200 {object} entity.Variable "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variables/{fqn} [get] +func (h *Handler) GetVariable() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx, logger, params, err := requestHelper(r) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + logger.Info("Getting variable set...") + + existingEntity, err := h.variableManager.GetVariableByFqn(ctx, params.Fqn) + handler.HandleResult(w, r, ctx, err, existingEntity) + } +} + +// @Id listVariables +// @Summary List variables +// @Description List variables +// @Tags variable +// @Produce json +// @Param variable body request.ListVariableSetRequest true "Variable labels to filter variables by." +// @Success 200 {object} entity.VariableLabelsListResult "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variables [get] +func (h *Handler) ListVariables() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx := r.Context() + logger := logutil.GetLogger(ctx) + logger.Info("Listing variables with specified labels...") + + // Decode the request body into the payload. + var requestPayload request.ListVariableSetRequest + if err := requestPayload.Decode(r); err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + // First, get the variables in the scope of the specified labels. + var labelScope []string + for labelKey := range requestPayload.Labels { + labelScope = append(labelScope, labelKey) + } + + variableLabelsListResult, err := h.variableLabelsManager.ListVariableLabels(ctx, &entity.VariableLabelsFilter{ + Labels: labelScope, + Pagination: &entity.Pagination{ + // Here we don't need to get the paginated results. + PageSize: 0, + }, + }) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + // Second, get the corresponding variable records, and calculate the label score + // of the variable. + var variableRes []*entity.Variable + for _, variableLabel := range variableLabelsListResult.VariableLabels { + key := variableLabel.VariableKey + variableListResult, err := h.variableManager.ListVariable(ctx, &entity.VariableFilter{ + Key: key, + Pagination: &entity.Pagination{ + // Here we don't need to get the paginated results. + PageSize: 0, + }, + }) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + score := -1 + var tmpVariable *entity.Variable + for _, variable := range variableListResult.Variables { + currentScore := CalculateLabelMatchScore(variable, variableLabel, requestPayload.Labels) + if score < currentScore { + score = currentScore + tmpVariable = variable + } + } + + if score > 0 { + variableRes = append(variableRes, tmpVariable) + } + } + + // Finally, return the variables with the highest matching score. + variableListResult := &entity.VariableListResult{ + Variables: variableRes, + Total: len(variableRes), + } + handler.HandleResult(w, r, ctx, err, variableListResult) + } +} + +func requestHelper(r *http.Request) (context.Context, *httplog.Logger, *VariableParams, error) { + ctx := r.Context() + logger := logutil.GetLogger(ctx) + + variableFqn := chi.URLParam(r, "variableFqn") + if variableFqn == "" { + return nil, nil, nil, variable.ErrEmptyVariableFqn + } + + params := VariableParams{ + Fqn: variableFqn, + } + + return ctx, logger, ¶ms, nil +} diff --git a/pkg/server/handler/variable/types.go b/pkg/server/handler/variable/types.go new file mode 100644 index 00000000..3db49ebd --- /dev/null +++ b/pkg/server/handler/variable/types.go @@ -0,0 +1,25 @@ +package variable + +import ( + "kusionstack.io/kusion/pkg/server/manager/variable" + "kusionstack.io/kusion/pkg/server/manager/variablelabels" +) + +type Handler struct { + variableManager *variable.VariableManager + variableLabelsManager *variablelabels.VariableLabelsManager +} + +func NewHandler( + variableManager *variable.VariableManager, + variableLabelsManager *variablelabels.VariableLabelsManager, +) (*Handler, error) { + return &Handler{ + variableManager: variableManager, + variableLabelsManager: variableLabelsManager, + }, nil +} + +type VariableParams struct { + Fqn string +} diff --git a/pkg/server/handler/variable/util.go b/pkg/server/handler/variable/util.go new file mode 100644 index 00000000..d09c5521 --- /dev/null +++ b/pkg/server/handler/variable/util.go @@ -0,0 +1,23 @@ +package variable + +import "kusionstack.io/kusion/pkg/domain/entity" + +// CalculateLabelMatchScore returns the score of label matching. +func CalculateLabelMatchScore(variable *entity.Variable, variableLabels *entity.VariableLabels, matchedLabels map[string]string) int { + labelScoreMap := make(map[string]int, len(variableLabels.Labels)) + for i, labelKey := range variableLabels.Labels { + labelScoreMap[labelKey] = 1 << i + } + + score := 0 + for labelKey, labelValue := range variable.Labels { + if matchedValue, ok := matchedLabels[labelKey]; ok && matchedValue != labelValue { + // Directly return 0 if any of the labels not matched. + return 0 + } + + score += labelScoreMap[labelKey] + } + + return score +} diff --git a/pkg/server/handler/variablelabels/handler.go b/pkg/server/handler/variablelabels/handler.go new file mode 100644 index 00000000..d102566a --- /dev/null +++ b/pkg/server/handler/variablelabels/handler.go @@ -0,0 +1,214 @@ +package variablelabels + +import ( + "context" + "net/http" + "strconv" + "strings" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/httplog/v2" + "github.com/go-chi/render" + "kusionstack.io/kusion/pkg/domain/constant" + "kusionstack.io/kusion/pkg/domain/entity" + "kusionstack.io/kusion/pkg/domain/request" + "kusionstack.io/kusion/pkg/server/handler" + variablelabelsmanager "kusionstack.io/kusion/pkg/server/manager/variablelabels" + logutil "kusionstack.io/kusion/pkg/server/util/logging" +) + +// @Id createVariableLabels +// @Summary Create variable labels +// @Description Create a new set of variable labels +// @Tags variable_labels +// @Accept json +// @Produce json +// @Param variable_labels body request.CreateVariableLabelsRequest true "Created variable labels" +// @Success 200 {object} entity.VariableLabels "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variable-labels [post] +func (h *Handler) CreateVariableLabels() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx := r.Context() + logger := logutil.GetLogger(ctx) + logger.Info("Creating variable with labels...") + + // Decode the request body into the payload. + var requestPayload request.CreateVariableLabelsRequest + if err := requestPayload.Decode(r); err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + // Return the created entity. + createdEntity, err := h.variableLabelsManager.CreateVariableLabels(ctx, requestPayload) + handler.HandleResult(w, r, ctx, err, createdEntity) + } +} + +// @Id deleteVariableLabels +// @Summary Delete variable labels +// @Description Delete a specified variable with labels +// @Tags variable_labels +// @Produce json +// @Param key path string true "Variable Key" +// @Success 200 {object} string "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variable-labels/{key} [delete] +func (h *Handler) DeleteVariableLabels() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx, logger, params, err := requestHelper(r) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + logger.Info("Deleting variable labels...") + + err = h.variableLabelsManager.DeleteVariableLabelsByKey(ctx, params.Key) + handler.HandleResult(w, r, ctx, err, "Deletion Success") + } +} + +// @Id updateVariableLabels +// @Summary Update variable labels +// @Description Update the specified variable labels +// @Tags variable_labels +// @Accept json +// @Produce json +// @Param key path string true "Variable Key" +// @Param variable_labels body request.UpdateVariableLabelsRequest true "Updated Variable Labels" +// @Success 200 {object} entity.VariableLabels "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variable-labels/{key} [put] +func (h *Handler) UpdateVariableLabels() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx, logger, params, err := requestHelper(r) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + logger.Info("Updating variable labels...") + + // Decode the request body into the payload. + var requestPayload request.UpdateVariableLabelsRequest + if err := requestPayload.Decode(r); err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + + // Return the updated variable labels. + updatedEntity, err := h.variableLabelsManager.UpdateVariableLabels(ctx, params.Key, requestPayload) + handler.HandleResult(w, r, ctx, err, updatedEntity) + } +} + +// @Id getVariableLabels +// @Summary Get variable labels +// @Description Get variable labels by variable key +// @Tags variable_labels +// @Produce json +// @Param key path string true "Variable Key" +// @Success 200 {object} entity.VariableLabels "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variable-labels/{key} [get] +func (h *Handler) GetVariableLabels() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx, logger, params, err := requestHelper(r) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + logger.Info("Getting variable labels...") + + existingEntity, err := h.variableLabelsManager.GetVariableLabelsByKey(ctx, params.Key) + handler.HandleResult(w, r, ctx, err, existingEntity) + } +} + +// @Id listVariableLabels +// @Summary List variable labels +// @Description List variable labels +// @Tags variable_labels +// @Produce json +// @Param labels query []string false "Variable labels to filter variables by. Default to all(empty) labels." +// @Param page query string false "Page number of the paginated list results. Default to 1." +// @Param pageSize query string false "Page size of the paginated list results. If not set, the result won't be paginated." +// @Success 200 {object} []entity.VariableLabelsListResult "Success" +// @Failure 400 {object} error "Bad Request" +// @Failure 401 {object} error "Unauthorized" +// @Failure 429 {object} error "Too Many Requests" +// @Failure 404 {object} error "Not Found" +// @Failure 500 {object} error "Internal Server Error" +// @Router /api/v1/variable-labels [get] +func (h *Handler) ListVariableLabels() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Getting stuff from context. + ctx := r.Context() + logger := logutil.GetLogger(ctx) + logger.Info("Listing variable labels...") + + query := r.URL.Query() + labels := strings.Split(query.Get("labels"), ",") + page, _ := strconv.Atoi(query.Get("page")) + if page <= 0 { + page = constant.RunPageDefault + } + pageSize, _ := strconv.Atoi(query.Get("pageSize")) + if pageSize <= 0 { + // Set `pageSize` to 0 will get an un-paginated list result here. + pageSize = 0 + } + + filter := &entity.VariableLabelsFilter{ + Labels: labels, + Pagination: &entity.Pagination{ + Page: page, + PageSize: pageSize, + }, + } + + // List the variable labels. + variableLabelsListResult, err := h.variableLabelsManager.ListVariableLabels(ctx, filter) + if err != nil { + render.Render(w, r, handler.FailureResponse(ctx, err)) + return + } + handler.HandleResult(w, r, ctx, err, variableLabelsListResult) + } +} + +func requestHelper(r *http.Request) (context.Context, *httplog.Logger, *VariableLabelsParams, error) { + ctx := r.Context() + logger := logutil.GetLogger(ctx) + + variableKey := chi.URLParam(r, "variableKey") + if variableKey == "" { + return nil, nil, nil, variablelabelsmanager.ErrEmptyVariableKey + } + + params := VariableLabelsParams{ + Key: variableKey, + } + + return ctx, logger, ¶ms, nil +} diff --git a/pkg/server/handler/variablelabels/types.go b/pkg/server/handler/variablelabels/types.go new file mode 100644 index 00000000..5d33f2c8 --- /dev/null +++ b/pkg/server/handler/variablelabels/types.go @@ -0,0 +1,21 @@ +package variablelabels + +import ( + "kusionstack.io/kusion/pkg/server/manager/variablelabels" +) + +type Handler struct { + variableLabelsManager *variablelabels.VariableLabelsManager +} + +func NewHandler( + variableLabelsManager *variablelabels.VariableLabelsManager, +) (*Handler, error) { + return &Handler{ + variableLabelsManager: variableLabelsManager, + }, nil +} + +type VariableLabelsParams struct { + Key string +} diff --git a/pkg/server/handler/workspace/configs.go b/pkg/server/handler/workspace/configs.go index 40b442c0..3983b08a 100644 --- a/pkg/server/handler/workspace/configs.go +++ b/pkg/server/handler/workspace/configs.go @@ -116,7 +116,7 @@ func (h *Handler) UpdateWorkspaceConfigs() http.HandlerFunc { // @Failure 429 {object} error "Too Many Requests" // @Failure 404 {object} error "Not Found" // @Failure 500 {object} error "Internal Server Error" -// @Router /api/v1/workspaces/{id}/configs/mod-deps [post] +// @Router /api/v1/workspaces/{id}/configs/mod-deps [post] func (h *Handler) CreateWorkspaceModDeps() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Getting stuff from context. diff --git a/pkg/server/manager/variable/types.go b/pkg/server/manager/variable/types.go new file mode 100644 index 00000000..5b965754 --- /dev/null +++ b/pkg/server/manager/variable/types.go @@ -0,0 +1,29 @@ +package variable + +import ( + "errors" + + "kusionstack.io/kusion/pkg/domain/repository" +) + +var ( + ErrGettingNonExistingVariable = errors.New("the variable does not exist") + ErrUpdatingNonExistingVariable = errors.New("the variable to update does not exist") + ErrEmptyVariableKey = errors.New("the variable key should not be empty") + ErrEmptyVariableFqn = errors.New("the variable fqn should not be empty") +) + +type VariableManager struct { + variableLabelsRepo repository.VariableLabelsRepository + variableRepo repository.VariableRepository +} + +func NewVariableManager( + variableRepo repository.VariableRepository, + variableLabelsRepo repository.VariableLabelsRepository, +) *VariableManager { + return &VariableManager{ + variableRepo: variableRepo, + variableLabelsRepo: variableLabelsRepo, + } +} diff --git a/pkg/server/manager/variable/variable_manager.go b/pkg/server/manager/variable/variable_manager.go new file mode 100644 index 00000000..1a7c9661 --- /dev/null +++ b/pkg/server/manager/variable/variable_manager.go @@ -0,0 +1,131 @@ +package variable + +import ( + "context" + "errors" + "strings" + + "github.com/jinzhu/copier" + "gorm.io/gorm" + "kusionstack.io/kusion/pkg/domain/entity" + "kusionstack.io/kusion/pkg/domain/request" +) + +func (v *VariableManager) CreateVariable(ctx context.Context, + requestPayload request.CreateVariableSetRequest, +) (*entity.Variable, error) { + // Convert request payload to the domain model. + var createdEntity entity.Variable + if err := copier.Copy(&createdEntity, &requestPayload); err != nil { + return nil, err + } + + if createdEntity.VariableKey == "" { + return nil, ErrEmptyVariableKey + } + + // Compute the fqn for the created entity. + variableLabelsEntity, err := v.variableLabelsRepo.GetByKey(ctx, createdEntity.VariableKey) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrGettingNonExistingVariable + } + + return nil, err + } + createdEntity.Fqn = computeFqn(&createdEntity, variableLabelsEntity) + + // Create variable with repository. + if err := v.variableRepo.Create(ctx, &createdEntity); err != nil { + return nil, err + } + + return &createdEntity, nil +} + +func (v *VariableManager) DeleteVariableByFqn(ctx context.Context, fqn string) error { + if err := v.variableRepo.Delete(ctx, fqn); err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrGettingNonExistingVariable + } + return err + } + + return nil +} + +func (v *VariableManager) UpdateVariable(ctx context.Context, + fqn string, requestPayload request.UpdateVariableSetRequest, +) (*entity.Variable, error) { + // Convert request payload to domain model. + var requestEntity entity.Variable + if err := copier.Copy(&requestEntity, &requestPayload); err != nil { + return nil, err + } + + if fqn == "" || requestEntity.Fqn == "" { + return nil, ErrEmptyVariableFqn + } + + // Get the existing variable by fqn. + updatedEntity, err := v.variableRepo.GetByFqn(ctx, fqn) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrUpdatingNonExistingVariable + } + + return nil, err + } + + // Overwrite non-zero values in request entity to existing entity. + copier.CopyWithOption(updatedEntity, requestEntity, copier.Option{ + IgnoreEmpty: true, + }) + + // Update variable with repository. + if err = v.variableRepo.Update(ctx, updatedEntity); err != nil { + return nil, err + } + + return updatedEntity, nil +} + +func (v *VariableManager) GetVariableByFqn(ctx context.Context, fqn string) (*entity.Variable, error) { + existingEntity, err := v.variableRepo.GetByFqn(ctx, fqn) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrGettingNonExistingVariable + } + + return nil, err + } + + return existingEntity, nil +} + +func (v *VariableManager) ListVariable(ctx context.Context, filter *entity.VariableFilter) (*entity.VariableListResult, error) { + variableListResult, err := v.variableRepo.List(ctx, filter) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrGettingNonExistingVariable + } + + return nil, err + } + + return variableListResult, nil +} + +// computeFqn returns the fqn for a variable. +// NOTE: the calculation rule for fqn is that the lowercase `Key` concatenated with +// the `Labels` in order of priority from low to high. +func computeFqn(variableEntity *entity.Variable, variableLabelsEntity *entity.VariableLabels) string { + fqnStrList := make([]string, len(variableLabelsEntity.Labels)+1) + fqnStrList[0] = variableEntity.VariableKey + + for i, labelKey := range variableLabelsEntity.Labels { + fqnStrList[i+1] = variableEntity.Labels[labelKey] + } + + return strings.Join(fqnStrList, ":") +} diff --git a/pkg/server/manager/variablelabels/types.go b/pkg/server/manager/variablelabels/types.go new file mode 100644 index 00000000..f258d02a --- /dev/null +++ b/pkg/server/manager/variablelabels/types.go @@ -0,0 +1,26 @@ +package variablelabels + +import ( + "errors" + + "kusionstack.io/kusion/pkg/domain/repository" +) + +var ( + ErrGettingNonExistingVariable = errors.New("the variable does not exist") + ErrUpdatingNonExistingVariable = errors.New("the variable to update does not exist") + ErrEmptyVariableKey = errors.New("the variable key should not be empty") + ErrEmptyVariableLabels = errors.New("the variable labels should not be empty") +) + +type VariableLabelsManager struct { + variableLabelsRepo repository.VariableLabelsRepository +} + +func NewVariableLabelsManager( + variableLabelsRepo repository.VariableLabelsRepository, +) *VariableLabelsManager { + return &VariableLabelsManager{ + variableLabelsRepo: variableLabelsRepo, + } +} diff --git a/pkg/server/manager/variablelabels/variable_labels_manager.go b/pkg/server/manager/variablelabels/variable_labels_manager.go new file mode 100644 index 00000000..66501683 --- /dev/null +++ b/pkg/server/manager/variablelabels/variable_labels_manager.go @@ -0,0 +1,115 @@ +package variablelabels + +import ( + "context" + "errors" + + "github.com/jinzhu/copier" + "gorm.io/gorm" + "kusionstack.io/kusion/pkg/domain/entity" + "kusionstack.io/kusion/pkg/domain/request" +) + +func (vl *VariableLabelsManager) CreateVariableLabels(ctx context.Context, + requestPayload request.CreateVariableLabelsRequest, +) (*entity.VariableLabels, error) { + // Convert request payload to the domain model. + var createdEntity entity.VariableLabels + if err := copier.Copy(&createdEntity, &requestPayload); err != nil { + return nil, err + } + + if createdEntity.VariableKey == "" { + return nil, ErrEmptyVariableKey + } + if len(createdEntity.Labels) == 0 { + return nil, ErrEmptyVariableLabels + } + + // Create variable labels with repository. + if err := vl.variableLabelsRepo.Create(ctx, &createdEntity); err != nil { + return nil, err + } + + return &createdEntity, nil +} + +func (vl *VariableLabelsManager) DeleteVariableLabelsByKey(ctx context.Context, key string) error { + if err := vl.variableLabelsRepo.Delete(ctx, key); err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrGettingNonExistingVariable + } + return err + } + + return nil +} + +func (vl *VariableLabelsManager) UpdateVariableLabels(ctx context.Context, + key string, requestPayload request.UpdateVariableLabelsRequest, +) (*entity.VariableLabels, error) { + // Convert request payload to domain model. + var requestEntity entity.VariableLabels + if err := copier.Copy(&requestEntity, &requestPayload); err != nil { + return nil, err + } + + if key == "" || requestEntity.VariableKey == "" { + return nil, ErrEmptyVariableKey + } + if len(requestEntity.Labels) == 0 { + return nil, ErrEmptyVariableLabels + } + + // Get the existing variable labels by key. + updatedEntity, err := vl.variableLabelsRepo.GetByKey(ctx, key) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrUpdatingNonExistingVariable + } + + return nil, err + } + + // Overwrite non-zero values in request entity to existing entity. + copier.CopyWithOption(updatedEntity, requestEntity, copier.Option{ + IgnoreEmpty: true, + }) + + // Update variable labels with repository. + if err = vl.variableLabelsRepo.Update(ctx, updatedEntity); err != nil { + return nil, err + } + + return updatedEntity, nil +} + +func (vl *VariableLabelsManager) GetVariableLabelsByKey(ctx context.Context, + key string, +) (*entity.VariableLabels, error) { + existingEntity, err := vl.variableLabelsRepo.GetByKey(ctx, key) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrGettingNonExistingVariable + } + + return nil, err + } + + return existingEntity, nil +} + +func (vl *VariableLabelsManager) ListVariableLabels(ctx context.Context, + filter *entity.VariableLabelsFilter, +) (*entity.VariableLabelsListResult, error) { + variableLabelsListResult, err := vl.variableLabelsRepo.List(ctx, filter) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrGettingNonExistingVariable + } + + return nil, err + } + + return variableLabelsListResult, nil +} diff --git a/pkg/server/route/route.go b/pkg/server/route/route.go index 2ccc45a1..4b8fe8be 100644 --- a/pkg/server/route/route.go +++ b/pkg/server/route/route.go @@ -21,6 +21,8 @@ import ( "kusionstack.io/kusion/pkg/server/handler/resource" "kusionstack.io/kusion/pkg/server/handler/source" "kusionstack.io/kusion/pkg/server/handler/stack" + "kusionstack.io/kusion/pkg/server/handler/variable" + "kusionstack.io/kusion/pkg/server/handler/variablelabels" "kusionstack.io/kusion/pkg/server/handler/workspace" backendmanager "kusionstack.io/kusion/pkg/server/manager/backend" modulemanager "kusionstack.io/kusion/pkg/server/manager/module" @@ -29,6 +31,8 @@ import ( resourcemanager "kusionstack.io/kusion/pkg/server/manager/resource" sourcemanager "kusionstack.io/kusion/pkg/server/manager/source" stackmanager "kusionstack.io/kusion/pkg/server/manager/stack" + variablemanager "kusionstack.io/kusion/pkg/server/manager/variable" + variablelabelsmanager "kusionstack.io/kusion/pkg/server/manager/variablelabels" workspacemanager "kusionstack.io/kusion/pkg/server/manager/workspace" appmiddleware "kusionstack.io/kusion/pkg/server/middleware" authutil "kusionstack.io/kusion/pkg/server/util/auth" @@ -133,6 +137,8 @@ func setupRestAPIV1( resourceRepo := persistence.NewResourceRepository(config.DB) moduleRepo := persistence.NewModuleRepository(config.DB) runRepo := persistence.NewRunRepository(config.DB) + variableLabelsRepo := persistence.NewVariableLabelsRepository(config.DB) + variableRepo := persistence.NewVariableRepository(config.DB) stackManager := stackmanager.NewStackManager(stackRepo, projectRepo, workspaceRepo, resourceRepo, runRepo, config.DefaultBackend, config.MaxConcurrent) sourceManager := sourcemanager.NewSourceManager(sourceRepo) @@ -142,46 +148,58 @@ func setupRestAPIV1( projectManager := projectmanager.NewProjectManager(projectRepo, organizationRepo, sourceRepo, config.DefaultSource) resourceManager := resourcemanager.NewResourceManager(resourceRepo) moduleManager := modulemanager.NewModuleManager(moduleRepo, workspaceRepo, backendRepo) + variableLabelsManager := variablelabelsmanager.NewVariableLabelsManager(variableLabelsRepo) + variableManager := variablemanager.NewVariableManager(variableRepo, variableLabelsRepo) // Set up the handlers for the resources. sourceHandler, err := source.NewHandler(sourceManager) if err != nil { - logger.Error(err.Error(), "Error creating source handler...", "error", err) + logger.Error("Error creating source handler...", "error", err.Error()) return } orgHandler, err := organization.NewHandler(organizationManager) if err != nil { - logger.Error(err.Error(), "Error creating org handler...", "error", err) + logger.Error("Error creating org handler...", "error", err.Error()) return } projectHandler, err := project.NewHandler(projectManager) if err != nil { - logger.Error(err.Error(), "Error creating project handler...", "error", err) + logger.Error("Error creating project handler...", "error", err.Error()) return } stackHandler, err := stack.NewHandler(stackManager, config.MaxAsyncConcurrent, config.MaxAsyncBuffer) if err != nil { - logger.Error(err.Error(), "Error creating stack handler...", "error", err) + logger.Error("Error creating stack handler...", "error", err.Error()) return } workspaceHandler, err := workspace.NewHandler(workspaceManager) if err != nil { - logger.Error(err.Error(), "Error creating workspace handler...", "error", err) + logger.Error("Error creating workspace handler...", "error", err.Error()) return } backendHandler, err := backend.NewHandler(backendManager) if err != nil { - logger.Error(err.Error(), "Error creating backend handler...", "error", err) + logger.Error("Error creating backend handler...", "error", err.Error()) return } resourceHandler, err := resource.NewHandler(resourceManager) if err != nil { - logger.Error(err.Error(), "Error creating resource handler...", "error", err) + logger.Error("Error creating resource handler...", "error", err.Error()) return } moduleHandler, err := module.NewHandler(moduleManager) if err != nil { - logger.Error(err.Error(), "Error creating module handler", "error", err) + logger.Error("Error creating module handler", "error", err.Error()) + return + } + variableLabelsHandler, err := variablelabels.NewHandler(variableLabelsManager) + if err != nil { + logger.Error("Error creating variablelabels handler", "error", err.Error()) + return + } + variableHandler, err := variable.NewHandler(variableManager, variableLabelsManager) + if err != nil { + logger.Error("Error creating variable handler", "error", err.Error()) return } @@ -291,4 +309,22 @@ func setupRestAPIV1( r.Get("/", moduleHandler.GetModule()) }) }) + r.Route("/variable-labels", func(r chi.Router) { + r.Post("/", variableLabelsHandler.CreateVariableLabels()) + r.Get("/", variableLabelsHandler.ListVariableLabels()) + r.Route("/{variableKey}", func(r chi.Router) { + r.Delete("/", variableLabelsHandler.DeleteVariableLabels()) + r.Put("/", variableLabelsHandler.UpdateVariableLabels()) + r.Get("/", variableLabelsHandler.GetVariableLabels()) + }) + }) + r.Route("/variables", func(r chi.Router) { + r.Post("/", variableHandler.CreateVariable()) + r.Get("/", variableHandler.ListVariables()) + r.Route("/{variableFqn}", func(r chi.Router) { + r.Delete("/", variableHandler.DeleteVariable()) + r.Put("/", variableHandler.UpdateVariable()) + r.Get("/", variableHandler.GetVariable()) + }) + }) }