diff --git a/.dockerignore b/.dockerignore index 506092390..8effd60d7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ -tmp/ -.github +# exclude all files and folders except bin folder +** +!bin diff --git a/OWNERS b/OWNERS index 25959ae23..a3883b4af 100644 --- a/OWNERS +++ b/OWNERS @@ -19,3 +19,4 @@ reviewers: - zheng1 - soulseen - shaowenchen + - stoneshi-yunify diff --git a/README.md b/README.md index fc46e1962..400ada011 100644 --- a/README.md +++ b/README.md @@ -91,11 +91,11 @@ KubeSphere can run anywhere from on-premise datacenter to any cloud to edge. In ### Installing on Linux -- [Installing KubeSphere on Azure VM](https://https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/install-ks-on-azure-vms/) -- [Installing KubeSphere on VMware vSphere](https://https://v3-0.docs.kubesphere.io/docs/installing-on-linux/on-premises/install-kubesphere-on-vmware-vsphere/) -- [Installing KubeSphere on QingCloud Instance](https://https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/kubesphere-on-qingcloud-instance/) -- [Installing on Alibaba Cloud ECS](https://https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/install-kubesphere-on-ali-ecs/) -- [Installing on Huaweicloud VM](https://https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/install-ks-on-huaweicloud-ecs/) +- [Installing KubeSphere on Azure VM](https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/install-ks-on-azure-vms/) +- [Installing KubeSphere on VMware vSphere](https://v3-0.docs.kubesphere.io/docs/installing-on-linux/on-premises/install-kubesphere-on-vmware-vsphere/) +- [Installing KubeSphere on QingCloud Instance](https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/kubesphere-on-qingcloud-instance/) +- [Installing on Alibaba Cloud ECS](https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/install-kubesphere-on-ali-ecs/) +- [Installing on Huaweicloud VM](https://v3-0.docs.kubesphere.io/docs/installing-on-linux/public-cloud/install-ks-on-huaweicloud-ecs/) ## Contributing, Support, Discussion, and Community diff --git a/api/ks-openapi-spec/swagger.json b/api/ks-openapi-spec/swagger.json index d1088f269..f35f940be 100644 --- a/api/ks-openapi-spec/swagger.json +++ b/api/ks-openapi-spec/swagger.json @@ -15,49 +15,83 @@ "version": "v0.0.0", "x-taggroups": [ { - "name": "IAM", + "name": "Authentication", "tags": [ - "Identity Management", - "Access Management" + "Authentication" + ] + }, + { + "name": "Identity Management", + "tags": [ + "User" + ] + }, + { + "name": "Access Management", + "tags": [ + "Cluster Member", + "Workspace Member", + "DevOps Project Member", + "Namespace Member", + "Global Role", + "Cluster Role", + "Workspace Role", + "DevOps Project Role", + "Namespace Role" + ] + }, + { + "name": "Multi-tenancy", + "tags": [ + "Workspace", + "Namespace", + "User's Resources" + ] + }, + { + "name": "Multi-cluster", + "tags": [ + "Multi-cluster" ] }, { "name": "Resources", "tags": [ "Cluster Resources", - "Namespace Resources", - "User Resources" + "Namespace Resources" ] }, { - "name": "Monitoring", + "name": "App Store", "tags": [ - "Component Status" - ] - }, - { - "name": "Tenant", - "tags": [ - "Tenant Resources" + "App Instance", + "App Template", + "Category", + "Attachment", + "Repository", + "App Management" ] }, { "name": "Other", "tags": [ - "Verification", - "Docker Registry" + "Docker Registry", + "Git", + "Toolbox", + "Terminal" ] }, { "name": "DevOps", "tags": [ "DevOps Project", - "DevOps Project Credential", + "DevOps Credential", "DevOps Pipeline", "DevOps Project Member", "DevOps Webhook", "DevOps Jenkinsfile", - "DevOps Scm" + "DevOps Scm", + "Jenkins" ] }, { @@ -70,7 +104,8 @@ "Pod Metrics", "Container Metrics", "Workspace Metrics", - "Component Metrics" + "Component Metrics", + "Component Status" ] }, { @@ -78,10 +113,78 @@ "tags": [ "Log Query" ] + }, + { + "name": "Events", + "tags": [ + "Events Query" + ] + }, + { + "name": "Auditing", + "tags": [ + "Auditing Query" + ] + }, + { + "name": "Network", + "tags": [ + "Network Topology" + ] } ] }, "paths": { + "/kapis/cluster.kubesphere.io/v1alpha1/clusters/validation": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Multi-cluster" + ], + "operationId": "validateCluster", + "parameters": [ + { + "description": "cluster specification", + "name": "cluster", + "in": "body", + "required": true + } + ], + "responses": { + "200": { + "description": "ok" + } + } + } + }, + "/kapis/cluster.kubesphere.io/v1alpha1/clusters/{cluster}/agent/deployment": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Multi-cluster" + ], + "summary": "Return deployment yaml for cluster agent.", + "operationId": "generateAgentDeployment", + "parameters": [ + { + "type": "string", + "description": "Name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok" + } + } + } + }, "/kapis/devops.kubesphere.io/v1alpha2/crumbissuer": { "get": { "produces": [ @@ -98,12 +201,6 @@ "schema": { "$ref": "#/definitions/devops.Crumb" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.Crumb" - } } } } @@ -142,12 +239,6 @@ "schema": { "$ref": "#/definitions/devops.CheckCronRes" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.CheckCronRes" - } } } } @@ -158,7 +249,7 @@ "application/json" ], "tags": [ - "DevOps Project Credential" + "DevOps Credential" ], "summary": "Get the specified credential usage of the DevOps project", "operationId": "GetProjectCredentialUsage", @@ -184,12 +275,6 @@ "schema": { "$ref": "#/definitions/devops.Credential" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.Credential" - } } } } @@ -226,12 +311,6 @@ "schema": { "$ref": "#/definitions/devops.Pipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.Pipeline" - } } } } @@ -294,15 +373,6 @@ "$ref": "#/definitions/devops.PipelineBranch" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.PipelineBranch" - } - } } } } @@ -346,12 +416,6 @@ "schema": { "$ref": "#/definitions/devops.BranchPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.BranchPipeline" - } } } } @@ -403,12 +467,6 @@ "schema": { "$ref": "#/definitions/devops.RunPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.RunPipeline" - } } } } @@ -459,12 +517,6 @@ "schema": { "$ref": "#/definitions/devops.PipelineRun" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.PipelineRun" - } } } } @@ -532,15 +584,6 @@ "$ref": "#/definitions/devops.Artifacts" } } - }, - "default": { - "description": "The filed of \"Url\" in response can download artifacts", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.Artifacts" - } - } } } } @@ -657,15 +700,6 @@ "$ref": "#/definitions/devops.BranchPipelineRunNodes" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.BranchPipelineRunNodes" - } - } } } } @@ -726,15 +760,6 @@ "$ref": "#/definitions/devops.NodeSteps" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.NodeSteps" - } - } } } } @@ -926,15 +951,6 @@ "$ref": "#/definitions/devops.NodesDetail" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.NodesDetail" - } - } } } } @@ -985,12 +1001,6 @@ "schema": { "$ref": "#/definitions/devops.ReplayPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.ReplayPipeline" - } } } } @@ -1057,12 +1067,6 @@ "schema": { "$ref": "#/definitions/devops.StopPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.StopPipeline" - } } } } @@ -1113,12 +1117,6 @@ "schema": { "$ref": "#/definitions/devops.CheckScript" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.CheckScript" - } } } } @@ -1209,12 +1207,6 @@ "schema": { "$ref": "#/definitions/devops.PipelineRunList" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.PipelineRunList" - } } } }, @@ -1257,12 +1249,6 @@ "schema": { "$ref": "#/definitions/devops.RunPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.RunPipeline" - } } } } @@ -1306,12 +1292,6 @@ "schema": { "$ref": "#/definitions/devops.PipelineRun" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.PipelineRun" - } } } } @@ -1372,15 +1352,6 @@ "$ref": "#/definitions/devops.Artifacts" } } - }, - "default": { - "description": "The filed of \"Url\" in response can download artifacts", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.Artifacts" - } - } } } } @@ -1475,15 +1446,6 @@ "$ref": "#/definitions/devops.PipelineRunNodes" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.PipelineRunNodes" - } - } } } } @@ -1537,15 +1499,6 @@ "$ref": "#/definitions/devops.NodeSteps" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.NodeSteps" - } - } } } } @@ -1716,15 +1669,6 @@ "$ref": "#/definitions/devops.NodesDetail" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.NodesDetail" - } - } } } } @@ -1768,12 +1712,6 @@ "schema": { "$ref": "#/definitions/devops.ReplayPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.ReplayPipeline" - } } } } @@ -1833,12 +1771,6 @@ "schema": { "$ref": "#/definitions/devops.StopPipeline" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.StopPipeline" - } } } } @@ -1888,10 +1820,13 @@ "produces": [ "application/json" ], + "tags": [ + "Jenkins" + ], "operationId": "func1", "parameters": [ { - "pattern": "[*]", + "pattern": "*", "type": "string", "description": "Path stands for any suffix path.", "name": "path", @@ -1902,9 +1837,6 @@ "responses": { "200": { "description": "ok" - }, - "default": { - "description": "ok" } } } @@ -1945,15 +1877,6 @@ "$ref": "#/definitions/devops.SCMOrg" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.SCMOrg" - } - } } } } @@ -2014,12 +1937,6 @@ "schema": { "$ref": "#/definitions/devops.OrgRepo" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.OrgRepo" - } } } } @@ -2052,15 +1969,6 @@ "$ref": "#/definitions/devops.SCMServer" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/devops.SCMServer" - } - } } } }, @@ -2096,12 +2004,6 @@ "schema": { "$ref": "#/definitions/devops.SCMServer" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.SCMServer" - } } } } @@ -2131,12 +2033,6 @@ "schema": { "$ref": "#/definitions/devops.Validates" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.Validates" - } } } } @@ -2188,12 +2084,6 @@ "schema": { "$ref": "#/definitions/devops.PipelineList" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.PipelineList" - } } } } @@ -2228,12 +2118,6 @@ "schema": { "$ref": "#/definitions/devops.ResJenkinsfile" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.ResJenkinsfile" - } } } } @@ -2268,12 +2152,6 @@ "schema": { "$ref": "#/definitions/devops.ResJson" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/devops.ResJson" - } } } } @@ -2412,12 +2290,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -2448,15 +2320,6 @@ "$ref": "#/definitions/v1alpha3.Pipeline" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.Pipeline" - } - } } } } @@ -2496,15 +2359,6 @@ "$ref": "#/definitions/v1.Secret" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1.Secret" - } - } } } }, @@ -2542,15 +2396,6 @@ "$ref": "#/definitions/v1.Secret" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1.Secret" - } - } } } }, @@ -2588,15 +2433,6 @@ "$ref": "#/definitions/v1.Secret" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1.Secret" - } - } } } } @@ -2634,12 +2470,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -2670,15 +2500,6 @@ "$ref": "#/definitions/v1alpha3.Pipeline" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.Pipeline" - } - } } } } @@ -2718,15 +2539,6 @@ "$ref": "#/definitions/v1alpha3.Pipeline" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.Pipeline" - } - } } } }, @@ -2764,15 +2576,6 @@ "$ref": "#/definitions/v1alpha3.Pipeline" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.Pipeline" - } - } } } }, @@ -2810,15 +2613,6 @@ "$ref": "#/definitions/v1alpha3.Pipeline" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.Pipeline" - } - } } } } @@ -2856,12 +2650,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -2892,15 +2680,6 @@ "$ref": "#/definitions/v1alpha3.DevOpsProject" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.DevOpsProject" - } - } } } } @@ -2940,15 +2719,6 @@ "$ref": "#/definitions/v1alpha3.DevOpsProject" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.DevOpsProject" - } - } } } }, @@ -2986,15 +2756,6 @@ "$ref": "#/definitions/v1alpha3.DevOpsProject" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.DevOpsProject" - } - } } } }, @@ -3032,15 +2793,6 @@ "$ref": "#/definitions/v1alpha3.DevOpsProject" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha3.DevOpsProject" - } - } } } } @@ -3051,7 +2803,7 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Member" ], "summary": "List all members in cluster.", "operationId": "ListClusterMembers", @@ -3061,12 +2813,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -3075,9 +2821,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Member" ], - "summary": "Add user to current cluster.", + "summary": "Add members to current cluster in bulk.", "operationId": "CreateClusterMembers", "parameters": [ { @@ -3101,15 +2847,6 @@ "$ref": "#/definitions/v1alpha2.Member" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha2.Member" - } - } } } } @@ -3120,9 +2857,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Member" ], - "summary": "Retrieve member details in cluster.", + "summary": "Retrieve the cluster role of the specified member.", "operationId": "DescribeClusterMember", "parameters": [ { @@ -3139,12 +2876,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } }, @@ -3153,9 +2884,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Member" ], - "summary": "Update cluster member role bind.", + "summary": "Update the cluster role bind of the member.", "operationId": "UpdateClusterMember", "parameters": [ { @@ -3180,12 +2911,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.Member" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.Member" - } } } }, @@ -3194,9 +2919,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Member" ], - "summary": "Delete member in cluster scope.", + "summary": "Delete a member from current cluster.", "operationId": "RemoveClusterMember", "parameters": [ { @@ -3213,12 +2938,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -3229,7 +2948,7 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], "summary": "Retrieve user's role templates in cluster.", "operationId": "RetrieveMemberRoleTemplates", @@ -3248,12 +2967,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -3264,7 +2977,7 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], "summary": "List all cluster roles.", "operationId": "ListClusterRoles", @@ -3274,12 +2987,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -3288,9 +2995,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], - "summary": "Create cluster role. Automatically aggregate policy rules according to annotation.", + "summary": "Create cluster role.", "operationId": "CreateClusterRole", "parameters": [ { @@ -3308,12 +3015,6 @@ "schema": { "$ref": "#/definitions/v1.ClusterRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.ClusterRole" - } } } } @@ -3324,7 +3025,7 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], "summary": "Retrieve cluster role details.", "operationId": "DescribeClusterRole", @@ -3343,12 +3044,6 @@ "schema": { "$ref": "#/definitions/v1.ClusterRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.ClusterRole" - } } } }, @@ -3357,9 +3052,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], - "summary": "Update cluster role. Automatically aggregate policy rules according to annotation.", + "summary": "Update cluster role.", "operationId": "UpdateClusterRole", "parameters": [ { @@ -3384,12 +3079,6 @@ "schema": { "$ref": "#/definitions/v1.ClusterRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.ClusterRole" - } } } }, @@ -3398,7 +3087,7 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], "summary": "Delete cluster role.", "operationId": "DeleteClusterRole", @@ -3417,12 +3106,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -3431,9 +3114,9 @@ "application/json" ], "tags": [ - "Access Management" + "Cluster Role" ], - "summary": "Patch cluster role. Automatically aggregate policy rules according to annotation.", + "summary": "Patch cluster role.", "operationId": "PatchClusterRole", "parameters": [ { @@ -3458,12 +3141,6 @@ "schema": { "$ref": "#/definitions/v1.ClusterRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.ClusterRole" - } } } } @@ -3474,7 +3151,7 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Member" ], "summary": "List all members in the specified devops project.", "operationId": "ListNamespaceMembers", @@ -3493,12 +3170,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -3507,9 +3178,9 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Member" ], - "summary": "Batch add devops project members.", + "summary": "Add members to the DevOps project in bulk.", "operationId": "CreateNamespaceMembers", "parameters": [ { @@ -3540,15 +3211,6 @@ "$ref": "#/definitions/v1alpha2.Member" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha2.Member" - } - } } } } @@ -3559,7 +3221,7 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Member" ], "summary": "Retrieve devops project member details.", "operationId": "DescribeNamespaceMember", @@ -3585,12 +3247,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } }, @@ -3599,9 +3255,9 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Member" ], - "summary": "Update member in devops project.", + "summary": "Update the role bind of the member.", "operationId": "UpdateNamespaceMember", "parameters": [ { @@ -3633,12 +3289,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.Member" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.Member" - } } } }, @@ -3647,9 +3297,9 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Member" ], - "summary": "Remove member in namespace.", + "summary": "Delete a member from the DevOps project.", "operationId": "RemoveNamespaceMember", "parameters": [ { @@ -3673,12 +3323,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -3689,7 +3333,7 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], "summary": "Retrieve member's role templates in devops project.", "operationId": "RetrieveMemberRoleTemplates", @@ -3715,12 +3359,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -3731,7 +3369,7 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], "summary": "List all roles in the specified devops project.", "operationId": "ListRoles", @@ -3750,12 +3388,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -3764,9 +3396,9 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], - "summary": "Create role in the specified devops project. Automatically aggregate policy rules according to annotation.", + "summary": "Create role in the specified devops project.", "operationId": "CreateNamespaceRole", "parameters": [ { @@ -3791,12 +3423,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } } @@ -3807,7 +3433,7 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], "summary": "Retrieve devops project role details.", "operationId": "DescribeNamespaceRole", @@ -3833,12 +3459,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } }, @@ -3847,9 +3467,9 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], - "summary": "Update devops project role. Automatically aggregate policy rules according to annotation.", + "summary": "Update devops project role.", "operationId": "UpdateNamespaceRole", "parameters": [ { @@ -3881,12 +3501,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } }, @@ -3895,7 +3509,7 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], "summary": "Delete role in the specified devops project.", "operationId": "DeleteNamespaceRole", @@ -3921,12 +3535,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -3935,9 +3543,9 @@ "application/json" ], "tags": [ - "Access Management" + "DevOps Project Role" ], - "summary": "Patch devops project role. Automatically aggregate policy rules according to annotation.", + "summary": "Patch devops project role.", "operationId": "PatchNamespaceRole", "parameters": [ { @@ -3969,12 +3577,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } } @@ -3985,7 +3587,7 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], "summary": "List all global roles.", "operationId": "ListGlobalRoles", @@ -3995,12 +3597,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -4009,9 +3605,9 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], - "summary": "Create global role. Automatically aggregate policy rules according to annotation.", + "summary": "Create global role.", "operationId": "CreateGlobalRole", "parameters": [ { @@ -4029,12 +3625,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.GlobalRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.GlobalRole" - } } } } @@ -4045,7 +3635,7 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], "summary": "Retrieve global role details.", "operationId": "DescribeGlobalRole", @@ -4064,12 +3654,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.GlobalRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.GlobalRole" - } } } }, @@ -4078,9 +3662,9 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], - "summary": "Update global role. Automatically aggregate policy rules according to annotation.", + "summary": "Update global role.", "operationId": "UpdateGlobalRole", "parameters": [ { @@ -4105,12 +3689,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.GlobalRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.GlobalRole" - } } } }, @@ -4119,7 +3697,7 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], "summary": "Delete global role.", "operationId": "DeleteGlobalRole", @@ -4138,12 +3716,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -4152,9 +3724,9 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], - "summary": "Patch global role. Automatically aggregate policy rules according to annotation.", + "summary": "Patch global role.", "operationId": "PatchGlobalRole", "parameters": [ { @@ -4179,11 +3751,39 @@ "schema": { "$ref": "#/definitions/v1alpha2.GlobalRole" } - }, - "default": { + } + } + } + }, + "/kapis/iam.kubesphere.io/v1alpha2/login": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "KubeSphere APIs support token-based authentication via the Authtoken request header. The POST Login API is used to retrieve the authentication token. After the authentication token is obtained, it must be inserted into the Authtoken header for all requests.", + "operationId": "Login", + "deprecated": true, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/auth.LoginRequest" + } + } + ], + "responses": { + "200": { "description": "ok", "schema": { - "$ref": "#/definitions/v1alpha2.GlobalRole" + "$ref": "#/definitions/oauth.Token" } } } @@ -4195,7 +3795,7 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Member" ], "summary": "List all members in the specified namespace.", "operationId": "ListNamespaceMembers", @@ -4214,12 +3814,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -4228,9 +3822,9 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Member" ], - "summary": "Batch add namespace members.", + "summary": "Add members to the namespace in bulk.", "operationId": "CreateNamespaceMembers", "parameters": [ { @@ -4261,15 +3855,6 @@ "$ref": "#/definitions/v1alpha2.Member" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha2.Member" - } - } } } } @@ -4280,9 +3865,9 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Member" ], - "summary": "Retrieve namespace member details.", + "summary": "Retrieve the role of the specified member.", "operationId": "DescribeNamespaceMember", "parameters": [ { @@ -4306,12 +3891,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } }, @@ -4320,9 +3899,9 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Member" ], - "summary": "Update member in namespace.", + "summary": "Update the role bind of the member.", "operationId": "UpdateNamespaceMember", "parameters": [ { @@ -4354,12 +3933,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.Member" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.Member" - } } } }, @@ -4368,9 +3941,9 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Member" ], - "summary": "Delete member in namespace scope.", + "summary": "Delete a member from the namespace.", "operationId": "RemoveNamespaceMember", "parameters": [ { @@ -4394,12 +3967,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -4410,7 +3977,7 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], "summary": "Retrieve member's role templates in namespace.", "operationId": "RetrieveMemberRoleTemplates", @@ -4436,12 +4003,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -4452,7 +4013,7 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], "summary": "List all roles in the specified namespace.", "operationId": "ListRoles", @@ -4471,12 +4032,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -4485,9 +4040,9 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], - "summary": "Create role in the specified namespace. Automatically aggregate policy rules according to annotation.", + "summary": "Create role in the specified namespace.", "operationId": "CreateNamespaceRole", "parameters": [ { @@ -4512,12 +4067,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } } @@ -4528,7 +4077,7 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], "summary": "Retrieve role details.", "operationId": "DescribeNamespaceRole", @@ -4554,12 +4103,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } }, @@ -4568,9 +4111,9 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], - "summary": "Update namespace role. Automatically aggregate policy rules according to annotation.", + "summary": "Update namespace role.", "operationId": "UpdateNamespaceRole", "parameters": [ { @@ -4602,12 +4145,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } }, @@ -4616,7 +4153,7 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], "summary": "Delete role in the specified namespace.", "operationId": "DeleteNamespaceRole", @@ -4642,12 +4179,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -4656,7 +4187,7 @@ "application/json" ], "tags": [ - "Access Management" + "Namespace Role" ], "summary": "Patch namespace role.", "operationId": "PatchNamespaceRole", @@ -4690,12 +4221,6 @@ "schema": { "$ref": "#/definitions/v1.Role" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Role" - } } } } @@ -4706,9 +4231,9 @@ "application/json" ], "tags": [ - "Access Management" + "User" ], - "summary": "List all users in global scope.", + "summary": "List all users.", "operationId": "ListUsers", "responses": { "200": { @@ -4716,12 +4241,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -4730,9 +4249,9 @@ "application/json" ], "tags": [ - "Access Management" + "User" ], - "summary": "Create user in global scope.", + "summary": "Create a global user account.", "operationId": "CreateUser", "parameters": [ { @@ -4750,12 +4269,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } } @@ -4766,7 +4279,7 @@ "application/json" ], "tags": [ - "Access Management" + "User" ], "summary": "Retrieve user details.", "operationId": "DescribeUser", @@ -4785,12 +4298,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } }, @@ -4799,9 +4306,9 @@ "application/json" ], "tags": [ - "Access Management" + "User" ], - "summary": "Update user info.", + "summary": "Update user profile.", "operationId": "UpdateUser", "parameters": [ { @@ -4826,12 +4333,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } }, @@ -4840,9 +4341,9 @@ "application/json" ], "tags": [ - "Access Management" + "User" ], - "summary": "Delete user.", + "summary": "Delete the specified user.", "operationId": "DeleteUser", "parameters": [ { @@ -4859,12 +4360,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -4875,7 +4370,7 @@ "application/json" ], "tags": [ - "Access Management" + "Global Role" ], "summary": "Retrieve user's global role templates.", "operationId": "RetrieveMemberRoleTemplates", @@ -4894,12 +4389,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -4910,9 +4399,9 @@ "application/json" ], "tags": [ - "Access Management" + "User's Resources" ], - "summary": "List user's login records.", + "summary": "List login records of the specified user.", "operationId": "ListUserLoginRecords", "parameters": [ { @@ -4929,12 +4418,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -4945,9 +4428,9 @@ "application/json" ], "tags": [ - "Access Management" + "User" ], - "summary": "Modify user's password.", + "summary": "Reset password of the specified user.", "operationId": "ModifyPassword", "parameters": [ { @@ -4972,12 +4455,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -4988,7 +4465,7 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Member" ], "summary": "List all members in the specified workspace.", "operationId": "ListWorkspaceMembers", @@ -5007,12 +4484,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -5021,9 +4492,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Member" ], - "summary": "Batch add workspace members.", + "summary": "Add members to current cluster in bulk.", "operationId": "CreateWorkspaceMembers", "parameters": [ { @@ -5054,15 +4525,6 @@ "$ref": "#/definitions/v1alpha2.Member" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha2.Member" - } - } } } } @@ -5073,9 +4535,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Member" ], - "summary": "Retrieve workspace member details.", + "summary": "Retrieve the workspace role of the specified member.", "operationId": "DescribeWorkspaceMember", "parameters": [ { @@ -5099,12 +4561,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.User" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.User" - } } } }, @@ -5113,9 +4569,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Member" ], - "summary": "Update member in workspace.", + "summary": "Update the workspace role bind of the member.", "operationId": "UpdateWorkspaceMember", "parameters": [ { @@ -5147,12 +4603,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.Member" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.Member" - } } } }, @@ -5161,9 +4611,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Member" ], - "summary": "Delete member in workspace scope.", + "summary": "Delete a member from the workspace.", "operationId": "RemoveWorkspaceMember", "parameters": [ { @@ -5187,12 +4637,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -5203,7 +4647,7 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], "summary": "Retrieve member's role templates in workspace.", "operationId": "RetrieveMemberRoleTemplates", @@ -5229,12 +4673,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -5245,7 +4683,7 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], "summary": "List all workspace roles.", "operationId": "ListWorkspaceRoles", @@ -5264,12 +4702,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -5278,9 +4710,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], - "summary": "Create workspace role. Automatically aggregate policy rules according to annotation.", + "summary": "Create workspace role.", "operationId": "CreateWorkspaceRole", "parameters": [ { @@ -5305,12 +4737,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceRole" - } } } } @@ -5321,7 +4747,7 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], "summary": "Retrieve workspace role details.", "operationId": "DescribeWorkspaceRole", @@ -5347,12 +4773,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceRole" - } } } }, @@ -5361,9 +4781,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], - "summary": "Update workspace role. Automatically aggregate policy rules according to annotation.", + "summary": "Update workspace role.", "operationId": "UpdateWorkspaceRole", "parameters": [ { @@ -5395,12 +4815,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceRole" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceRole" - } } } }, @@ -5409,7 +4823,7 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], "summary": "Delete workspace role.", "operationId": "DeleteWorkspaceRole", @@ -5435,12 +4849,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -5449,9 +4857,9 @@ "application/json" ], "tags": [ - "Access Management" + "Workspace Role" ], - "summary": "Patch workspace role. Automatically aggregate policy rules according to annotation.", + "summary": "Patch workspace role.", "operationId": "PatchWorkspaceRole", "parameters": [ { @@ -5483,12 +4891,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -5542,12 +4944,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -5608,12 +5004,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -5634,12 +5024,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -5725,12 +5109,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -5791,12 +5169,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -5889,12 +5261,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -5962,12 +5328,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6060,12 +5420,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6133,12 +5487,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6238,12 +5586,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6318,12 +5660,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6374,12 +5710,6 @@ "schema": { "$ref": "#/definitions/monitoring.MetricLabelSet" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.MetricLabelSet" - } } } } @@ -6409,12 +5739,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metadata" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metadata" - } } } } @@ -6475,12 +5799,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metric" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metric" - } } } } @@ -6573,12 +5891,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6678,12 +5990,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6790,12 +6096,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6881,12 +6181,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -6947,12 +6241,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7045,12 +6333,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7118,12 +6400,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7216,12 +6492,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7307,12 +6577,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7379,12 +6643,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7477,12 +6735,6 @@ "schema": { "$ref": "#/definitions/monitoring.Metrics" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/monitoring.Metrics" - } } } } @@ -7512,12 +6764,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.TopologyResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.TopologyResponse" - } } } } @@ -7554,11 +6800,2299 @@ "schema": { "$ref": "#/definitions/v1alpha2.NodeResponse" } + } + } + } + }, + "/kapis/openpitrix.io/v1/applications": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "List all applications", + "operationId": "ListApplications", + "parameters": [ + { + "type": "string", + "format": "key=value,key~value", + "description": "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" }, - "default": { + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + } + ], + "responses": { + "200": { "description": "ok", "schema": { - "$ref": "#/definitions/v1alpha2.NodeResponse" + "$ref": "#/definitions/models.PageableResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "List app templates", + "operationId": "ListApps", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Create a new app template", + "operationId": "CreateApp", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppRequest" + } + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Describe the specified app template", + "operationId": "DescribeApp", + "parameters": [ + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersion" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Delete the specified app template", + "operationId": "DeleteApp", + "parameters": [ + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Patch the specified app template", + "operationId": "ModifyApp", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyAppVersionRequest" + } + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/action": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Perform recover or suspend operation on app", + "operationId": "DoAppAction", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/audits": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "List audits information of the specific app template", + "operationId": "ListAppVersionAudits", + "parameters": [ + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersionAudit" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/versions": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Get active versions of app, can filter with these fields(version_id, app_id, name, owner, description, package_name, status, type), default return all active app versions", + "operationId": "ListAppVersions", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Create a new app template version", + "operationId": "CreateAppVersion", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppVersionRequest" + } + }, + { + "type": "string", + "description": "Validate format of package(pack by op tool)", + "name": "validate", + "in": "query" + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppVersionResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/versions/{version}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Describe the specified app template version", + "operationId": "DescribeAppVersion", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersion" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Delete the specified app template version", + "operationId": "DeleteAppVersion", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Patch the specified app template version", + "operationId": "ModifyAppVersion", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyAppVersionRequest" + } + }, + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/versions/{version}/action": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Perform submit or other operations on app", + "operationId": "DoAppVersionAction", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/versions/{version}/audits": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "List audits information of version-specific app template", + "operationId": "ListAppVersionAudits", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersionAudit" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/versions/{version}/files": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Get app template package files", + "operationId": "GetAppVersionFiles", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.GetAppVersionPackageFilesResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/apps/{app}/versions/{version}/package": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Get packages of version-specific app", + "operationId": "GetAppVersionPackage", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.GetAppVersionPackageResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/attachments/{attachment}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Attachment" + ], + "summary": "Get attachment by attachment id", + "operationId": "DescribeAttachment", + "parameters": [ + { + "type": "string", + "description": "attachment id", + "name": "attachment", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.Attachment" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/categories": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Category" + ], + "summary": "List categories", + "operationId": "ListCategories", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Category" + ], + "summary": "Create app template category", + "operationId": "CreateCategory", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateCategoryRequest" + } + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateCategoryResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/categories/{category}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Category" + ], + "summary": "Describe the specified category", + "operationId": "DescribeCategory", + "parameters": [ + { + "type": "string", + "description": "category id", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.Category" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Category" + ], + "summary": "Delete the specified category", + "operationId": "DeleteCategory", + "parameters": [ + { + "type": "string", + "description": "category id", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Category" + ], + "summary": "Patch the specified category", + "operationId": "ModifyCategory", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyCategoryRequest" + } + }, + { + "type": "string", + "description": "category id", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/repos": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "List repositories in the specified workspace", + "operationId": "ListRepos", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Create repository in the specified workspace, repository used to store package of app", + "operationId": "CreateRepo", + "parameters": [ + { + "type": "string", + "description": "Validate repository", + "name": "validate", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateRepoRequest" + } + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateRepoResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/repos/{repo}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Describe the specified repository in the specified workspace", + "operationId": "DescribeRepo", + "parameters": [ + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.Repo" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Delete the specified repository in the specified workspace", + "operationId": "DeleteRepo", + "parameters": [ + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Patch the specified repository in the specified workspace", + "operationId": "ModifyRepo", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyRepoRequest" + } + }, + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/repos/{repo}/action": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Start index repository event", + "operationId": "DoRepoAction", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.RepoActionRequest" + } + }, + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/repos/{repo}/events": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Get repository events", + "operationId": "ListRepoEvents", + "parameters": [ + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/reviews": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Get reviews of version-specific app", + "operationId": "ListReviews", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersionReview" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "List app templates in the specified workspace.", + "operationId": "ListApps", + "parameters": [ + { + "type": "string", + "description": "workspace name", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Create a new app template", + "operationId": "CreateApp", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppRequest" + } + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps/{app}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Describe the specified app template", + "operationId": "DescribeApp", + "parameters": [ + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersion" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Delete the specified app template", + "operationId": "DeleteApp", + "parameters": [ + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Patch the specified app template", + "operationId": "ModifyApp", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyAppVersionRequest" + } + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps/{app}/action": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Perform recover or suspend operation on app", + "operationId": "DoAppAction", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps/{app}/versions": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Get active versions of app, can filter with these fields(version_id, app_id, name, owner, description, package_name, status, type), default return all active app versions", + "operationId": "ListAppVersions", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Create a new app template version", + "operationId": "CreateAppVersion", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppVersionRequest" + } + }, + { + "type": "string", + "description": "Validate format of package(pack by op tool)", + "name": "validate", + "in": "query" + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateAppVersionResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps/{app}/versions/{version}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Describe the specified app template version", + "operationId": "DescribeAppVersion", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersion" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Delete the specified app template version", + "operationId": "DeleteAppVersion", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "App Template" + ], + "summary": "Patch the specified app template version", + "operationId": "ModifyAppVersion", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyAppVersionRequest" + } + }, + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps/{app}/versions/{version}/action": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Perform submit or other operations on app", + "operationId": "DoAppVersionAction", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/apps/{app}/versions/{version}/audits": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "List audits information of version-specific app template", + "operationId": "ListAppVersionAudits", + "parameters": [ + { + "type": "string", + "description": "app template version id", + "name": "version", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "app template id", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.AppVersionAudit" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/clusters/{cluster}/applications": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "List all applications in special cluster", + "operationId": "ListApplications", + "parameters": [ + { + "type": "string", + "format": "key=value,key~value", + "description": "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/applications": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "List all applications within the specified namespace", + "operationId": "ListApplications", + "parameters": [ + { + "type": "string", + "format": "key=value,key~value", + "description": "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "Deploy a new application", + "operationId": "CreateApplication", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateClusterRequest" + } + }, + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/applications/{application}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "Describe the specified application of the namespace", + "operationId": "DescribeApplication", + "parameters": [ + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the id of the application", + "name": "application", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.Application" + } + } + } + }, + "post": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "Upgrade application", + "operationId": "UpgradeApplication", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.UpgradeClusterRequest" + } + }, + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the id of the application", + "name": "application", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "Delete the specified application", + "operationId": "DeleteApplication", + "parameters": [ + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the id of the application", + "name": "application", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "Modify application", + "operationId": "ModifyApplication", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyClusterAttributesRequest" + } + }, + { + "type": "string", + "description": "the name of the cluster.", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the id of the application", + "name": "application", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/namespaces/{namespace}/applications": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "List all applications within the specified namespace", + "operationId": "ListApplications", + "parameters": [ + { + "type": "string", + "format": "key=value,key~value", + "description": "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "description": "the name of the project.", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/namespaces/{namespace}/applications/{application}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "App Instance" + ], + "summary": "Describe the specified application of the namespace", + "operationId": "DescribeApplication", + "parameters": [ + { + "type": "string", + "description": "the name of the project", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the id of the application", + "name": "application", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.Application" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/repos": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "List repositories in the specified workspace", + "operationId": "ListRepos", + "parameters": [ + { + "type": "string", + "format": "key=%s,key~%s", + "description": "query conditions,connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a", + "name": "conditions", + "in": "query" + }, + { + "type": "string", + "format": "limit=%d,page=%d", + "default": "limit=10,page=1", + "description": "paging query, e.g. limit=100,page=1", + "name": "paging", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. reverse=true", + "name": "reverse", + "in": "query" + }, + { + "type": "string", + "description": "sort parameters, e.g. orderBy=createTime", + "name": "orderBy", + "in": "query" + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" + } + } + } + }, + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Create repository in the specified workspace, repository used to store package of app", + "operationId": "CreateRepo", + "parameters": [ + { + "type": "string", + "description": "Validate repository", + "name": "validate", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.CreateRepoRequest" + } + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.CreateRepoResponse" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/repos/{repo}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Describe the specified repository in the specified workspace", + "operationId": "DescribeRepo", + "parameters": [ + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/openpitrix.Repo" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Delete the specified repository in the specified workspace", + "operationId": "DeleteRepo", + "parameters": [ + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + }, + "patch": { + "consumes": [ + "application/json", + "application/merge-patch+json", + "application/json-patch+json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Patch the specified repository in the specified workspace", + "operationId": "ModifyRepo", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.ModifyRepoRequest" + } + }, + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/repos/{repo}/action": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "App Management" + ], + "summary": "Start index repository event", + "operationId": "DoRepoAction", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/openpitrix.RepoActionRequest" + } + }, + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/errors.Error" + } + } + } + } + }, + "/kapis/openpitrix.io/v1/workspaces/{workspace}/repos/{repo}/events": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Repository" + ], + "summary": "Get repository events", + "operationId": "ListRepoEvents", + "parameters": [ + { + "type": "string", + "description": "repo id", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/models.PageableResponse" } } } @@ -7607,12 +9141,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -7633,12 +9161,6 @@ "schema": { "$ref": "#/definitions/api.Workloads" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.Workloads" - } } } } @@ -7659,12 +9181,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.HealthStatus" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.HealthStatus" - } } } } @@ -7688,15 +9204,6 @@ "$ref": "#/definitions/v1alpha2.ComponentStatus" } } - }, - "default": { - "description": "ok", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha2.ComponentStatus" - } - } } } } @@ -7726,12 +9233,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.ComponentStatus" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.ComponentStatus" - } } } } @@ -7742,7 +9243,7 @@ "application/json" ], "tags": [ - "Verification" + "Git" ], "summary": "Verify if the kubernetes secret has read access to the git repository", "operationId": "handleVerifyGitCredential", @@ -7762,12 +9263,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -7797,12 +9292,6 @@ "schema": { "$ref": "#/definitions/api.Workloads" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.Workloads" - } } } } @@ -7846,12 +9335,6 @@ "schema": { "$ref": "#/definitions/v1.DaemonSet" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.DaemonSet" - } } } } @@ -7895,12 +9378,6 @@ "schema": { "$ref": "#/definitions/v1.ReplicaSet" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.ReplicaSet" - } } } } @@ -7930,12 +9407,6 @@ "schema": { "$ref": "#/definitions/api.ResourceQuota" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ResourceQuota" - } } } } @@ -7965,12 +9436,6 @@ "schema": { "$ref": "#/definitions/v1.Service" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Service" - } } } }, @@ -7998,12 +9463,6 @@ "schema": { "$ref": "#/definitions/v1.Service" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Service" - } } } }, @@ -8031,12 +9490,6 @@ "schema": { "$ref": "#/definitions/v1.Service" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Service" - } } } }, @@ -8064,12 +9517,6 @@ "schema": { "$ref": "#/definitions/v1.Service" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Service" - } } } } @@ -8113,12 +9560,6 @@ "schema": { "$ref": "#/definitions/v1.StatefulSet" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.StatefulSet" - } } } } @@ -8183,12 +9624,6 @@ "schema": { "$ref": "#/definitions/models.PageableResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/models.PageableResponse" - } } } } @@ -8209,12 +9644,6 @@ "schema": { "$ref": "#/definitions/api.ResourceQuota" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ResourceQuota" - } } } } @@ -8259,12 +9688,6 @@ "schema": { "$ref": "#/definitions/registries.ImageDetails" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/registries.ImageDetails" - } } } } @@ -8275,7 +9698,7 @@ "application/json" ], "tags": [ - "Verification" + "Docker Registry" ], "summary": "verify if a user has access to the docker registry", "operationId": "handleVerifyRegistryCredential", @@ -8295,12 +9718,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } } @@ -8312,7 +9729,7 @@ "application/json" ], "tags": [ - "User Resources" + "Toolbox" ], "summary": "get users' kubeconfig", "operationId": "GetKubeconfig", @@ -8331,12 +9748,6 @@ "schema": { "type": "string" } - }, - "default": { - "description": "ok", - "schema": { - "type": "string" - } } } } @@ -8347,7 +9758,7 @@ "application/json" ], "tags": [ - "User Resources" + "Toolbox" ], "summary": "get user's kubectl pod", "operationId": "GetKubectlPod", @@ -8366,12 +9777,6 @@ "schema": { "$ref": "#/definitions/models.PodInfo" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/models.PodInfo" - } } } } @@ -8429,12 +9834,6 @@ "schema": { "$ref": "#/definitions/models.PageableResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/models.PageableResponse" - } } } } @@ -8455,12 +9854,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.HealthStatus" } - }, - "default": { - "description": "OK", - "schema": { - "$ref": "#/definitions/v1alpha2.HealthStatus" - } } } } @@ -8484,15 +9877,6 @@ "$ref": "#/definitions/v1alpha2.ComponentStatus" } } - }, - "default": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/v1alpha2.ComponentStatus" - } - } } } } @@ -8522,12 +9906,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.ComponentStatus" } - }, - "default": { - "description": "OK", - "schema": { - "$ref": "#/definitions/v1alpha2.ComponentStatus" - } } } } @@ -8597,12 +9975,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -8646,12 +10018,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -8714,12 +10080,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -8753,9 +10113,6 @@ "responses": { "200": { "description": "ok" - }, - "default": { - "description": "ok" } } } @@ -8824,12 +10181,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.NotFoundError" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.graphResponse" - } } } } @@ -8880,12 +10231,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.appHealthResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.appHealthResponse" - } } } } @@ -8991,12 +10336,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.metricsResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.metricsResponse" - } } } } @@ -9072,12 +10411,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.NotFoundError" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.graphResponse" - } } } } @@ -9133,12 +10466,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.NotFoundError" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.namespaceAppHealthResponse" - } } } } @@ -9237,12 +10564,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.metricsResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.metricsResponse" - } } } } @@ -9293,12 +10614,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.serviceHealthResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.serviceHealthResponse" - } } } } @@ -9404,12 +10719,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.metricsResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.metricsResponse" - } } } } @@ -9533,12 +10842,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.workloadHealthResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.workloadHealthResponse" - } } } } @@ -9644,12 +10947,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.metricsResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.metricsResponse" - } } } } @@ -9820,12 +11117,6 @@ "schema": { "$ref": "#/definitions/v1alpha1.APIResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha1.APIResponse" - } } } } @@ -9836,7 +11127,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "User's Resources" ], "summary": "List clusters available to users", "operationId": "ListClusters", @@ -9846,12 +11137,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -9987,12 +11272,6 @@ "schema": { "$ref": "#/definitions/v1alpha1.APIResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha1.APIResponse" - } } } } @@ -10003,7 +11282,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "List the federated namespaces for the current user", "operationId": "ListFederatedNamespaces", @@ -10013,12 +11292,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -10142,12 +11415,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.APIResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.APIResponse" - } } } } @@ -10158,7 +11425,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "List the namespaces for the current user", "operationId": "ListNamespaces", @@ -10168,12 +11435,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -10184,7 +11445,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "List all workspaces that belongs to the current user", "operationId": "ListWorkspaces", @@ -10194,12 +11455,6 @@ "schema": { "$ref": "#/definitions/models.PageableResponse" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/models.PageableResponse" - } } } }, @@ -10208,7 +11463,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "Create workspace.", "operationId": "CreateWorkspace", @@ -10228,12 +11483,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" - } } } } @@ -10244,7 +11493,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "Describe workspace.", "operationId": "DescribeWorkspace", @@ -10263,12 +11512,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" - } } } }, @@ -10277,7 +11520,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "Update workspace.", "operationId": "UpdateWorkspace", @@ -10304,12 +11547,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" - } } } }, @@ -10318,7 +11555,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "Delete workspace.", "operationId": "DeleteWorkspace", @@ -10337,12 +11574,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -10356,7 +11587,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "Update workspace.", "operationId": "PatchWorkspace", @@ -10383,12 +11614,6 @@ "schema": { "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1alpha2.WorkspaceTemplate" - } } } } @@ -10399,7 +11624,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Workspace" ], "summary": "List clusters authorized to the specified workspace.", "operationId": "ListWorkspaceClusters", @@ -10418,12 +11643,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -10434,7 +11653,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "DevOps Project" ], "summary": "List the devops projects of the specified workspace for the current user", "operationId": "ListDevOpsProjects", @@ -10453,12 +11672,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -10469,7 +11682,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "List the federated namespaces of the specified workspace for the current user", "operationId": "ListFederatedNamespaces", @@ -10488,12 +11701,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } } @@ -10504,7 +11711,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "List the namespaces of the specified workspace for the current user", "operationId": "ListNamespaces", @@ -10523,12 +11730,6 @@ "schema": { "$ref": "#/definitions/api.ListResult" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/api.ListResult" - } } } }, @@ -10537,7 +11738,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "List the namespaces of the specified workspace for the current user", "operationId": "CreateNamespace", @@ -10564,12 +11765,6 @@ "schema": { "$ref": "#/definitions/v1.Namespace" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Namespace" - } } } } @@ -10580,7 +11775,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "Retrieve namespace details.", "operationId": "DescribeNamespace", @@ -10606,12 +11801,6 @@ "schema": { "$ref": "#/definitions/v1.Namespace" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Namespace" - } } } }, @@ -10620,7 +11809,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "operationId": "UpdateNamespace", "parameters": [ @@ -10653,12 +11842,6 @@ "schema": { "$ref": "#/definitions/v1.Namespace" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Namespace" - } } } }, @@ -10667,7 +11850,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "Delete namespace.", "operationId": "DeleteNamespace", @@ -10693,12 +11876,6 @@ "schema": { "$ref": "#/definitions/errors.Error" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/errors.Error" - } } } }, @@ -10712,7 +11889,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "operationId": "PatchNamespace", "parameters": [ @@ -10745,12 +11922,6 @@ "schema": { "$ref": "#/definitions/v1.Namespace" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Namespace" - } } } } @@ -10761,7 +11932,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "DevOps Project" ], "summary": "List the devops projects of specified workspace for the workspace member", "operationId": "ListDevOpsProjects", @@ -10795,12 +11966,6 @@ "schema": { "$ref": "#/definitions/v1.Namespace" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Namespace" - } } } } @@ -10811,7 +11976,7 @@ "application/json" ], "tags": [ - "Tenant Resources" + "Namespace" ], "summary": "List the namespaces of the specified workspace for the workspace member", "operationId": "ListNamespaces", @@ -10845,12 +12010,6 @@ "schema": { "$ref": "#/definitions/v1.Namespace" } - }, - "default": { - "description": "ok", - "schema": { - "$ref": "#/definitions/v1.Namespace" - } } } } @@ -10887,6 +12046,188 @@ } } } + }, + "/oauth/authenticate": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.", + "operationId": "TokenReview", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/auth.TokenReview" + } + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/auth.TokenReview" + } + } + } + } + }, + "/oauth/authorize": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "All requests for OAuth tokens involve a request to /oauth/authorize.", + "operationId": "Authorize", + "parameters": [ + { + "type": "string", + "description": "The value MUST be one of \"code\" for requesting an authorization code as described by [RFC6749] Section 4.1.1, \"token\" for requesting an access token (implicit grant) as described by [RFC6749] Section 4.2.2.", + "name": "response_type", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "The client identifier issued to the client during the registration process described by [RFC6749] Section 2.2.", + "name": "client_id", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "After completing its interaction with the resource owner, the authorization server directs the resource owner's user-agent back to the client.The redirection endpoint URI MUST be an absolute URI as defined by [RFC3986] Section 4.3.", + "name": "redirect_uri", + "in": "query" + } + ], + "responses": { + "302": { + "description": "Found", + "schema": { + "type": "string" + } + } + } + } + }, + "/oauth/callback/{callback}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "OAuth callback API, the path param callback is config by identity provider", + "operationId": "oAuthCallBack", + "parameters": [ + { + "type": "string", + "description": "The access token issued by the authorization server.", + "name": "access_token", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "The type of the token issued as described in [RFC6479] Section 7.1. Value is case insensitive.", + "name": "token_type", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "The lifetime in seconds of the access token. For example, the value \"3600\" denotes that the access token will expire in one hour from the time the response was generated.If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value.", + "name": "expires_in", + "in": "query" + }, + { + "type": "string", + "description": "if identical to the scope requested by the client;otherwise, REQUIRED. The scope of the access token as described by [RFC6479] Section 3.3.", + "name": "scope", + "in": "query" + }, + { + "type": "string", + "description": "if the \"state\" parameter was present in the client authorization request.The exact value received from the client.", + "name": "state", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/oauth.Token" + } + } + } + } + }, + "/oauth/token": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "The resource owner password credentials grant type is suitable in\ncases where the resource owner has a trust relationship with the\nclient, such as the device operating system or a highly privileged application.", + "operationId": "Token", + "parameters": [ + { + "type": "string", + "description": "Value MUST be set to \"password\".", + "name": "grant_type", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "The resource owner username.", + "name": "username", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "The resource owner password.", + "name": "password", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/oauth.Token" + } + } + } + } } }, "definitions": { @@ -11393,6 +12734,71 @@ } } }, + "auth.LoginRequest": { + "required": [ + "username", + "password" + ], + "properties": { + "password": { + "description": "password", + "type": "string" + }, + "username": { + "description": "username", + "type": "string" + } + } + }, + "auth.Spec": { + "required": [ + "token" + ], + "properties": { + "token": { + "description": "access token", + "type": "string" + } + } + }, + "auth.Status": { + "required": [ + "authenticated" + ], + "properties": { + "authenticated": { + "description": "is authenticated", + "type": "boolean" + }, + "user": { + "description": "user info", + "type": "object" + } + } + }, + "auth.TokenReview": { + "required": [ + "apiVersion", + "kind" + ], + "properties": { + "apiVersion": { + "description": "Kubernetes API version", + "type": "string" + }, + "kind": { + "description": "kind of the API object", + "type": "string" + }, + "spec": { + "$ref": "#/definitions/auth.Spec" + }, + "status": { + "description": "token review status", + "$ref": "#/definitions/auth.Status" + } + } + }, "big.Int": { "required": [ "neg", @@ -11402,7 +12808,7 @@ "abs": { "type": "array", "items": { - "$ref": "#/definitions/big.Word" + "type": "integer" } }, "neg": { @@ -11410,7 +12816,6 @@ } } }, - "big.Word": {}, "cytoscape.EdgeData": { "required": [ "id", @@ -11688,6 +13093,13 @@ "description": "It’s a fully qualified name and is an identifier of the producer of this resource's capability.", "type": "string" }, + "choices": { + "description": "choices", + "type": "array", + "items": { + "$ref": "#/definitions/devops.BranchPipeline.parameters.choices" + } + }, "defaultParameterValue": { "$ref": "#/definitions/.defaultParameterValue" }, @@ -11705,6 +13117,7 @@ } } }, + "devops.BranchPipeline.parameters.choices": {}, "devops.BranchPipelineRunNodes": { "properties": { "_class": { @@ -13321,7 +14734,8 @@ ], "properties": { "scale": { - "$ref": "#/definitions/inf.Scale" + "type": "integer", + "format": "int32" }, "unscaled": { "$ref": "#/definitions/big.Int" @@ -13427,7 +14841,6 @@ } } }, - "model.LabelValue": {}, "model.SamplePair": { "required": [ "Timestamp", @@ -13435,10 +14848,12 @@ ], "properties": { "Timestamp": { - "type": "string" + "type": "string", + "format": "int64" }, "Value": { - "type": "string" + "type": "string", + "format": "double" } } }, @@ -13451,7 +14866,7 @@ "metric": { "type": "object", "additionalProperties": { - "$ref": "#/definitions/model.LabelValue" + "type": "string" } }, "values": { @@ -13640,7 +15055,12 @@ } } }, - "monitoring.MetricLabelSet.data": {}, + "monitoring.MetricLabelSet.data": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "monitoring.MetricValue": { "properties": { "metric": { @@ -13692,7 +15112,914 @@ } } }, - "monitoring.Point": {}, + "oauth.Token": { + "required": [ + "access_token" + ], + "properties": { + "access_token": { + "type": "string" + }, + "expires_in": { + "type": "integer", + "format": "int32" + }, + "refresh_token": { + "type": "string" + }, + "token_type": { + "type": "string" + } + } + }, + "openpitrix.App": { + "required": [ + "category_set" + ], + "properties": { + "abstraction": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "app_id": { + "type": "string" + }, + "app_version_types": { + "type": "string" + }, + "category_set": { + "type": "array", + "items": { + "$ref": "#/definitions/openpitrix.ResourceCategory" + } + }, + "chart_name": { + "type": "string" + }, + "cluster_total": { + "type": "integer", + "format": "int32" + }, + "company_join_time": { + "type": "string" + }, + "company_name": { + "type": "string" + }, + "company_profile": { + "type": "string" + }, + "company_website": { + "type": "string" + }, + "create_time": { + "type": "string" + }, + "description": { + "type": "string" + }, + "home": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "isv": { + "type": "string" + }, + "keywords": { + "type": "string" + }, + "latest_app_version": { + "$ref": "#/definitions/openpitrix.AppVersion" + }, + "maintainers": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "readme": { + "type": "string" + }, + "repo_id": { + "type": "string" + }, + "screenshots": { + "type": "string" + }, + "sources": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + }, + "tos": { + "type": "string" + }, + "update_time": { + "type": "string" + } + } + }, + "openpitrix.AppVersion": { + "properties": { + "active": { + "type": "boolean" + }, + "app_id": { + "type": "string" + }, + "cluster_total": { + "type": "integer", + "format": "int32" + }, + "create_time": { + "type": "string" + }, + "description": { + "type": "string" + }, + "home": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "keywords": { + "type": "string" + }, + "maintainers": { + "type": "string" + }, + "message": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "package_name": { + "type": "string" + }, + "readme": { + "type": "string" + }, + "review_id": { + "type": "string" + }, + "screenshots": { + "type": "string" + }, + "sequence": { + "type": "integer", + "format": "int64" + }, + "sources": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + }, + "type": { + "type": "string" + }, + "update_time": { + "type": "string" + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.AppVersionAudit": { + "properties": { + "app_id": { + "type": "string" + }, + "app_name": { + "type": "string" + }, + "message": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "operator_type": { + "type": "string" + }, + "review_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + }, + "version_id": { + "type": "string" + }, + "version_name": { + "type": "string" + }, + "version_type": { + "type": "string" + } + } + }, + "openpitrix.AppVersionReview": { + "properties": { + "app_id": { + "type": "string" + }, + "app_name": { + "type": "string" + }, + "phase": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/openpitrix.AppVersionReviewPhase" + } + }, + "review_id": { + "type": "string" + }, + "reviewer": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + }, + "version_id": { + "type": "string" + }, + "version_name": { + "type": "string" + }, + "version_type": { + "type": "string" + } + } + }, + "openpitrix.AppVersionReviewPhase": { + "properties": { + "message": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "operator_type": { + "type": "string" + }, + "review_time": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + } + } + }, + "openpitrix.Application": { + "required": [ + "name" + ], + "properties": { + "app": { + "description": "application template info", + "$ref": "#/definitions/openpitrix.App" + }, + "cluster": { + "description": "application cluster info", + "$ref": "#/definitions/openpitrix.Cluster" + }, + "ingresses": { + "description": "application ingresses", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.Ingress" + } + }, + "name": { + "description": "application name", + "type": "string" + }, + "services": { + "description": "application services", + "type": "array", + "items": { + "$ref": "#/definitions/v1.Service" + } + }, + "version": { + "description": "application template version info", + "$ref": "#/definitions/openpitrix.AppVersion" + }, + "workloads": { + "description": "application workloads", + "$ref": "#/definitions/openpitrix.workLoads" + } + } + }, + "openpitrix.Attachment": { + "properties": { + "attachment_content": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "attachment_id": { + "type": "string" + }, + "create_time": { + "type": "string" + } + } + }, + "openpitrix.Category": { + "properties": { + "app_total": { + "type": "integer", + "format": "int32" + }, + "category_id": { + "type": "string" + }, + "create_time": { + "type": "string" + }, + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "update_time": { + "type": "string" + } + } + }, + "openpitrix.Cluster": { + "properties": { + "additional_info": { + "type": "string" + }, + "app_id": { + "type": "string" + }, + "cluster_id": { + "type": "string" + }, + "cluster_type": { + "type": "integer", + "format": "int64" + }, + "create_time": { + "type": "string" + }, + "debug": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "endpoints": { + "type": "string" + }, + "env": { + "type": "string" + }, + "frontgate_id": { + "type": "string" + }, + "global_uuid": { + "type": "string" + }, + "metadata_root_access": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "runtime_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + }, + "subnet_id": { + "type": "string" + }, + "transition_status": { + "type": "string" + }, + "upgrade_status": { + "type": "string" + }, + "upgrade_time": { + "type": "string" + }, + "version_id": { + "type": "string" + }, + "vpc_id": { + "type": "string" + }, + "zone": { + "type": "string" + } + } + }, + "openpitrix.CreateAppRequest": { + "properties": { + "icon": { + "type": "string" + }, + "isv": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version_name": { + "type": "string" + }, + "version_package": { + "type": "string" + }, + "version_type": { + "type": "string" + } + } + }, + "openpitrix.CreateAppResponse": { + "properties": { + "app_id": { + "type": "string" + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.CreateAppVersionRequest": { + "properties": { + "app_id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "package": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "openpitrix.CreateAppVersionResponse": { + "properties": { + "version_id": { + "type": "string" + } + } + }, + "openpitrix.CreateCategoryRequest": { + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "openpitrix.CreateCategoryResponse": { + "properties": { + "category_id": { + "type": "string" + } + } + }, + "openpitrix.CreateClusterRequest": { + "required": [ + "advanced_param" + ], + "properties": { + "advanced_param": { + "type": "array", + "items": { + "type": "string" + } + }, + "app_id": { + "type": "string" + }, + "conf": { + "type": "string" + }, + "runtime_id": { + "type": "string" + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.CreateRepoRequest": { + "required": [ + "providers" + ], + "properties": { + "app_default_status": { + "type": "string" + }, + "category_id": { + "type": "string" + }, + "credential": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "providers": { + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "visibility": { + "type": "string" + }, + "workspace": { + "type": "string" + } + } + }, + "openpitrix.CreateRepoResponse": { + "properties": { + "repo_id": { + "type": "string" + } + } + }, + "openpitrix.GetAppVersionPackageFilesResponse": { + "properties": { + "files": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.GetAppVersionPackageResponse": { + "properties": { + "app_id": { + "type": "string" + }, + "package": { + "type": "string" + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.ModifyAppVersionRequest": { + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "package": { + "type": "string" + }, + "package_files": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.ModifyCategoryRequest": { + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "openpitrix.ModifyClusterAttributesRequest": { + "properties": { + "cluster_id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "openpitrix.ModifyRepoRequest": { + "required": [ + "providers" + ], + "properties": { + "app_default_status": { + "type": "string" + }, + "category_id": { + "type": "string" + }, + "credential": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "providers": { + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "visibility": { + "type": "string" + }, + "workspace": { + "type": "string" + } + } + }, + "openpitrix.Repo": { + "required": [ + "category_set", + "labels", + "providers", + "selectors" + ], + "properties": { + "app_default_status": { + "type": "string" + }, + "category_set": { + "type": "array", + "items": { + "$ref": "#/definitions/openpitrix.ResourceCategory" + } + }, + "controller": { + "type": "integer", + "format": "int32" + }, + "create_time": { + "type": "string" + }, + "credential": { + "type": "string" + }, + "description": { + "type": "string" + }, + "labels": { + "type": "array", + "items": { + "$ref": "#/definitions/openpitrix.RepoLabel" + } + }, + "name": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "providers": { + "type": "array", + "items": { + "type": "string" + } + }, + "repo_id": { + "type": "string" + }, + "selectors": { + "type": "array", + "items": { + "$ref": "#/definitions/openpitrix.RepoSelector" + } + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "visibility": { + "type": "string" + } + } + }, + "openpitrix.RepoActionRequest": { + "required": [ + "action" + ], + "properties": { + "action": { + "type": "string" + } + } + }, + "openpitrix.RepoLabel": { + "properties": { + "create_time": { + "type": "string" + }, + "label_key": { + "type": "string" + }, + "label_value": { + "type": "string" + } + } + }, + "openpitrix.RepoSelector": { + "properties": { + "create_time": { + "type": "string" + }, + "selector_key": { + "type": "string" + }, + "selector_value": { + "type": "string" + } + } + }, + "openpitrix.ResourceCategory": { + "properties": { + "category_id": { + "type": "string" + }, + "create_time": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "status_time": { + "type": "string" + } + } + }, + "openpitrix.UpgradeClusterRequest": { + "required": [ + "cluster_id", + "advanced_param" + ], + "properties": { + "advanced_param": { + "type": "array", + "items": { + "type": "string" + } + }, + "cluster_id": { + "type": "string" + }, + "conf": { + "type": "string" + }, + "runtime_id": { + "type": "string" + }, + "version_id": { + "type": "string" + } + } + }, + "openpitrix.workLoads": { + "properties": { + "daemonsets": { + "description": "daemonset list", + "type": "array", + "items": { + "$ref": "#/definitions/v1.DaemonSet" + } + }, + "deployments": { + "description": "deployment list", + "type": "array", + "items": { + "$ref": "#/definitions/v1.Deployment" + } + }, + "statefulsets": { + "description": "statefulset list", + "type": "array", + "items": { + "$ref": "#/definitions/v1.StatefulSet" + } + } + } + }, "prometheus.Metric": { "required": [ "matrix", @@ -13710,7 +16037,12 @@ } } }, - "prometheus.Metrics.histograms": {}, + "prometheus.Metrics.histograms": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/prometheus.Metric" + } + }, "registries.Config": { "properties": { "ArgsEscaped": { @@ -14111,7 +16443,8 @@ ], "properties": { "scale": { - "$ref": "#/definitions/resource.Scale" + "type": "integer", + "format": "int32" }, "value": { "type": "integer", @@ -14173,8 +16506,6 @@ } } }, - "v1.AzureDataDiskCachingMode": {}, - "v1.AzureDataDiskKind": {}, "v1.AzureDiskVolumeSource": { "description": "AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.", "required": [ @@ -14184,7 +16515,7 @@ "properties": { "cachingMode": { "description": "Host Caching mode: None, Read Only, Read Write.", - "$ref": "#/definitions/v1.AzureDataDiskCachingMode" + "type": "string" }, "diskName": { "description": "The Name of the data disk in the blob storage", @@ -14200,7 +16531,7 @@ }, "kind": { "description": "Expected values Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared", - "$ref": "#/definitions/v1.AzureDataDiskKind" + "type": "string" }, "readOnly": { "description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", @@ -14267,19 +16598,18 @@ "description": "Added capabilities", "type": "array", "items": { - "$ref": "#/definitions/v1.Capability" + "type": "string" } }, "drop": { "description": "Removed capabilities", "type": "array", "items": { - "$ref": "#/definitions/v1.Capability" + "type": "string" } } } }, - "v1.Capability": {}, "v1.CephFSVolumeSource": { "description": "Represents a Ceph Filesystem mount that lasts the lifetime of a pod Cephfs volumes do not support ownership management or SELinux relabeling.", "required": [ @@ -14766,6 +17096,169 @@ } } }, + "v1.Deployment": { + "description": "Deployment enables declarative updates for Pods and ReplicaSets.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "description": "Standard object metadata.", + "$ref": "#/definitions/v1.ObjectMeta" + }, + "spec": { + "description": "Specification of the desired behavior of the Deployment.", + "$ref": "#/definitions/v1.DeploymentSpec" + }, + "status": { + "description": "Most recently observed status of the Deployment.", + "$ref": "#/definitions/v1.DeploymentStatus" + } + } + }, + "v1.DeploymentCondition": { + "description": "DeploymentCondition describes the state of a deployment at a certain point.", + "required": [ + "type", + "status" + ], + "properties": { + "lastTransitionTime": { + "description": "Last time the condition transitioned from one status to another.", + "type": "string" + }, + "lastUpdateTime": { + "description": "The last time this condition was updated.", + "type": "string" + }, + "message": { + "description": "A human readable message indicating details about the transition.", + "type": "string" + }, + "reason": { + "description": "The reason for the condition's last transition.", + "type": "string" + }, + "status": { + "description": "Status of the condition, one of True, False, Unknown.", + "type": "string" + }, + "type": { + "description": "Type of deployment condition.", + "type": "string" + } + } + }, + "v1.DeploymentSpec": { + "description": "DeploymentSpec is the specification of the desired behavior of the Deployment.", + "required": [ + "selector", + "template" + ], + "properties": { + "minReadySeconds": { + "description": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", + "type": "integer", + "format": "int32" + }, + "paused": { + "description": "Indicates that the deployment is paused.", + "type": "boolean" + }, + "progressDeadlineSeconds": { + "description": "The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s.", + "type": "integer", + "format": "int32" + }, + "replicas": { + "description": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", + "type": "integer", + "format": "int32" + }, + "revisionHistoryLimit": { + "description": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", + "type": "integer", + "format": "int32" + }, + "selector": { + "description": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.", + "$ref": "#/definitions/v1.LabelSelector" + }, + "strategy": { + "description": "The deployment strategy to use to replace existing pods with new ones.", + "$ref": "#/definitions/v1.DeploymentStrategy" + }, + "template": { + "description": "Template describes the pods that will be created.", + "$ref": "#/definitions/v1.PodTemplateSpec" + } + } + }, + "v1.DeploymentStatus": { + "description": "DeploymentStatus is the most recently observed status of the Deployment.", + "properties": { + "availableReplicas": { + "description": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", + "type": "integer", + "format": "int32" + }, + "collisionCount": { + "description": "Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", + "type": "integer", + "format": "int32" + }, + "conditions": { + "description": "Represents the latest available observations of a deployment's current state.", + "type": "array", + "items": { + "$ref": "#/definitions/v1.DeploymentCondition" + } + }, + "observedGeneration": { + "description": "The generation observed by the deployment controller.", + "type": "integer", + "format": "int64" + }, + "readyReplicas": { + "description": "Total number of ready pods targeted by this deployment.", + "type": "integer", + "format": "int32" + }, + "replicas": { + "description": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", + "type": "integer", + "format": "int32" + }, + "unavailableReplicas": { + "description": "Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", + "type": "integer", + "format": "int32" + }, + "updatedReplicas": { + "description": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", + "type": "integer", + "format": "int32" + } + } + }, + "v1.DeploymentStrategy": { + "description": "DeploymentStrategy describes how to replace existing pods with new ones.", + "properties": { + "rollingUpdate": { + "description": "Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate.", + "$ref": "#/definitions/v1.RollingUpdateDeployment" + }, + "type": { + "description": "Type of deployment. Can be \"Recreate\" or \"RollingUpdate\". Default is RollingUpdate.", + "type": "string" + } + } + }, "v1.DownwardAPIProjection": { "description": "Represents downward API info for projecting into a projected volume. Note that this is identical to a downwardAPI volume source without the default mode.", "properties": { @@ -15167,7 +17660,6 @@ } } }, - "v1.FinalizerName": {}, "v1.FlexVolumeSource": { "description": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.", "required": [ @@ -15359,7 +17851,6 @@ } } }, - "v1.HostPathType": {}, "v1.HostPathVolumeSource": { "description": "Represents a host path mapped into a pod. Host path volumes do not support ownership management or SELinux relabeling.", "required": [ @@ -15372,11 +17863,10 @@ }, "type": { "description": "Type for HostPath Volume Defaults to \"\" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath", - "$ref": "#/definitions/v1.HostPathType" + "type": "string" } } }, - "v1.IPFamily": {}, "v1.ISCSIVolumeSource": { "description": "Represents an ISCSI disk. ISCSI volumes can only be mounted as read/write once. ISCSI volumes support ownership management and SELinux relabeling.", "required": [ @@ -15576,7 +18066,6 @@ } } }, - "v1.MountPropagationMode": {}, "v1.NFSVolumeSource": { "description": "Represents an NFS mount that lasts the lifetime of a pod. NFS volumes do not support ownership management or SELinux relabeling.", "required": [ @@ -15656,7 +18145,7 @@ "description": "Finalizers is an opaque list of values that must be empty to permanently remove object from storage. More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/", "type": "array", "items": { - "$ref": "#/definitions/v1.FinalizerName" + "type": "string" } } } @@ -15921,7 +18410,6 @@ } } }, - "v1.PersistentVolumeAccessMode": {}, "v1.PersistentVolumeClaim": { "description": "PersistentVolumeClaim is a user's request for and claim to a persistent volume", "properties": { @@ -15985,7 +18473,7 @@ "description": "AccessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1", "type": "array", "items": { - "$ref": "#/definitions/v1.PersistentVolumeAccessMode" + "type": "string" } }, "dataSource": { @@ -16006,7 +18494,7 @@ }, "volumeMode": { "description": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. This is a beta feature.", - "$ref": "#/definitions/v1.PersistentVolumeMode" + "type": "string" }, "volumeName": { "description": "VolumeName is the binding reference to the PersistentVolume backing this claim.", @@ -16021,7 +18509,7 @@ "description": "AccessModes contains the actual access modes the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1", "type": "array", "items": { - "$ref": "#/definitions/v1.PersistentVolumeAccessMode" + "type": "string" } }, "capacity": { @@ -16060,7 +18548,6 @@ } } }, - "v1.PersistentVolumeMode": {}, "v1.PhotonPersistentDiskVolumeSource": { "description": "Represents a Photon Controller persistent disk resource.", "required": [ @@ -16336,7 +18823,7 @@ }, "preemptionPolicy": { "description": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is alpha-level and is only honored by servers that enable the NonPreemptingPriority feature.", - "$ref": "#/definitions/v1.PreemptionPolicy" + "type": "string" }, "priority": { "description": "The priority value. Various system components use this field to find the priority of the pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.", @@ -16490,7 +18977,6 @@ } } }, - "v1.PreemptionPolicy": {}, "v1.PreferredSchedulingTerm": { "description": "An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).", "required": [ @@ -16551,7 +19037,6 @@ } } }, - "v1.ProcMountType": {}, "v1.ProjectedVolumeSource": { "description": "Represents a projected volume source", "required": [ @@ -16863,6 +19348,19 @@ } } }, + "v1.RollingUpdateDeployment": { + "description": "Spec to control the desired behavior of rolling update.", + "properties": { + "maxSurge": { + "description": "The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods.", + "type": "string" + }, + "maxUnavailable": { + "description": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.", + "type": "string" + } + } + }, "v1.RollingUpdateStatefulSetStrategy": { "description": "RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.", "properties": { @@ -16955,7 +19453,7 @@ "description": "Data contains the secret data. Each key must consist of alphanumeric characters, '-', '_' or '.'. The serialized form of the secret data is a base64 encoded string, representing the arbitrary (possibly non-string) data value here. Described in https://tools.ietf.org/html/rfc4648#section-4", "type": "object", "additionalProperties": { - "$ref": "#/definitions/v1.Secret.data" + "type": "string" } }, "kind": { @@ -17087,7 +19585,7 @@ }, "procMount": { "description": "procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled.", - "$ref": "#/definitions/v1.ProcMountType" + "type": "string" }, "readOnlyRootFilesystem": { "description": "Whether this container has a read-only root filesystem. Default is false.", @@ -17222,7 +19720,7 @@ }, "ipFamily": { "description": "ipFamily specifies whether this Service has a preference for a particular IP family (e.g. IPv4 vs. IPv6). If a specific IP family is requested, the clusterIP field will be allocated from that family, if it is available in the cluster. If no IP family is requested, the cluster's primary IP family will be used. Other IP fields (loadBalancerIP, loadBalancerSourceRanges, externalIPs) and controllers which allocate external load-balancers should use the same IP family. Endpoints for this Service will be of this family. This field is immutable after creation. Assigning a ServiceIPFamily not available in the cluster (e.g. IPv6 in IPv4 only cluster) is an error condition and will fail during clusterIP assignment.", - "$ref": "#/definitions/v1.IPFamily" + "type": "string" }, "loadBalancerIP": { "description": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.", @@ -17745,7 +20243,7 @@ }, "mountPropagation": { "description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.", - "$ref": "#/definitions/v1.MountPropagationMode" + "type": "string" }, "name": { "description": "This must match the Name of a Volume.", @@ -18222,9 +20720,9 @@ }, "v1alpha2.Node": { "required": [ - "id", "label", "rank", + "id", "labelMinor", "controls" ], @@ -18671,10 +21169,10 @@ }, "v1alpha2.graphResponse": { "required": [ + "timestamp", "duration", "graphType", - "elements", - "timestamp" + "elements" ], "properties": { "duration": { @@ -19254,6 +21752,139 @@ } } }, + "v1beta1.HTTPIngressPath": { + "description": "HTTPIngressPath associates a path regex with a backend. Incoming urls matching the path are forwarded to the backend.", + "required": [ + "backend" + ], + "properties": { + "backend": { + "description": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "$ref": "#/definitions/v1beta1.IngressBackend" + }, + "path": { + "description": "Path is an extended POSIX regex as defined by IEEE Std 1003.1, (i.e this follows the egrep/unix syntax, not the perl syntax) matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. If unspecified, the path defaults to a catch all sending traffic to the backend.", + "type": "string" + } + } + }, + "v1beta1.HTTPIngressRuleValue": { + "description": "HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: http://\u003chost\u003e/\u003cpath\u003e?\u003csearchpart\u003e -\u003e backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.", + "required": [ + "paths" + ], + "properties": { + "paths": { + "description": "A collection of paths that map requests to backends.", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.HTTPIngressPath" + } + } + } + }, + "v1beta1.Ingress": { + "description": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc. DEPRECATED - This group version of Ingress is deprecated by networking.k8s.io/v1beta1 Ingress. See the release notes for more information.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "$ref": "#/definitions/v1.ObjectMeta" + }, + "spec": { + "description": "Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "$ref": "#/definitions/v1beta1.IngressSpec" + }, + "status": { + "description": "Status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "$ref": "#/definitions/v1beta1.IngressStatus" + } + } + }, + "v1beta1.IngressBackend": { + "description": "IngressBackend describes all endpoints for a given service and port.", + "required": [ + "serviceName", + "servicePort" + ], + "properties": { + "serviceName": { + "description": "Specifies the name of the referenced service.", + "type": "string" + }, + "servicePort": { + "description": "Specifies the port of the referenced service.", + "type": "string" + } + } + }, + "v1beta1.IngressRule": { + "description": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", + "properties": { + "host": { + "description": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in the RFC: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the\n\t IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.", + "type": "string" + }, + "http": { + "$ref": "#/definitions/v1beta1.HTTPIngressRuleValue" + } + } + }, + "v1beta1.IngressSpec": { + "description": "IngressSpec describes the Ingress the user wishes to exist.", + "properties": { + "backend": { + "description": "A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.", + "$ref": "#/definitions/v1beta1.IngressBackend" + }, + "rules": { + "description": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.IngressRule" + } + }, + "tls": { + "description": "TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.IngressTLS" + } + } + } + }, + "v1beta1.IngressStatus": { + "description": "IngressStatus describe the current state of the Ingress.", + "properties": { + "loadBalancer": { + "description": "LoadBalancer contains the current status of the load-balancer.", + "$ref": "#/definitions/v1.LoadBalancerStatus" + } + } + }, + "v1beta1.IngressTLS": { + "description": "IngressTLS describes the transport layer security associated with an Ingress.", + "properties": { + "hosts": { + "description": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", + "type": "array", + "items": { + "type": "string" + } + }, + "secretName": { + "description": "SecretName is the name of the secret used to terminate SSL traffic on 443. Field is left optional to allow SSL routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", + "type": "string" + } + } + }, "v1beta1.WorkspaceTemplate": { "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", "properties": { diff --git a/build/ks-controller-manager/Dockerfile b/build/ks-controller-manager/Dockerfile index 263ab11a1..c7ba5dd40 100644 --- a/build/ks-controller-manager/Dockerfile +++ b/build/ks-controller-manager/Dockerfile @@ -3,10 +3,10 @@ # that can be found in the LICENSE file. FROM alpine:3.11 -COPY /bin/cmd/controller-manager /usr/local/bin/ - RUN apk add --no-cache ca-certificates +COPY /bin/cmd/controller-manager /usr/local/bin/ + EXPOSE 8443 8080 CMD ["sh"] \ No newline at end of file diff --git a/config/crds/iam.kubesphere.io_groupbindings.yaml b/config/crds/iam.kubesphere.io_groupbindings.yaml new file mode 100644 index 000000000..df2fdecf5 --- /dev/null +++ b/config/crds/iam.kubesphere.io_groupbindings.yaml @@ -0,0 +1,69 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: groupbindings.iam.kubesphere.io +spec: + additionalPrinterColumns: + - JSONPath: .groupRef.name + name: Group + type: string + - JSONPath: .users + name: Users + type: string + group: iam.kubesphere.io + names: + categories: + - group + kind: GroupBinding + listKind: GroupBindingList + plural: groupbindings + singular: groupbinding + scope: Cluster + subresources: {} + validation: + openAPIV3Schema: + description: GroupBinding is the Schema for the groupbindings API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + groupRef: + description: Ref defines the desired relation of GroupBinding + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + users: + items: + type: string + type: array + type: object + version: v1alpha2 + versions: + - name: v1alpha2 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/iam.kubesphere.io_groups.yaml b/config/crds/iam.kubesphere.io_groups.yaml new file mode 100644 index 000000000..110bb746c --- /dev/null +++ b/config/crds/iam.kubesphere.io_groups.yaml @@ -0,0 +1,58 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: groups.iam.kubesphere.io +spec: + additionalPrinterColumns: + - JSONPath: .metadata.labels.kubesphere\.io/workspace + name: Workspace + type: string + group: iam.kubesphere.io + names: + categories: + - group + kind: Group + listKind: GroupList + plural: groups + singular: group + scope: Cluster + subresources: {} + validation: + openAPIV3Schema: + description: Group is the Schema for the groups API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: GroupSpec defines the desired state of Group + type: object + status: + description: GroupStatus defines the observed state of Group + type: object + type: object + version: v1alpha2 + versions: + - name: v1alpha2 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/samples/iam_v1alpha2_group.yaml b/config/samples/iam_v1alpha2_group.yaml new file mode 100644 index 000000000..3f204665c --- /dev/null +++ b/config/samples/iam_v1alpha2_group.yaml @@ -0,0 +1,4 @@ +apiVersion: iam.kubesphere.io/v1alpha2 +kind: Group +metadata: + name: group2 diff --git a/config/samples/iam_v1alpha2_groupbinding.yaml b/config/samples/iam_v1alpha2_groupbinding.yaml new file mode 100644 index 000000000..29847a4c3 --- /dev/null +++ b/config/samples/iam_v1alpha2_groupbinding.yaml @@ -0,0 +1,12 @@ +apiVersion: iam.kubesphere.io/v1alpha2 +kind: GroupBinding +metadata: + name: groupbinding-sample1 +groupRef: + apiGroup: rbac.authorization.k8s.io + kind: Group + name: groupdemo +users: +- user1 +- user2 + diff --git a/config/samples/iam_v1alpha2_rolebindings.yaml b/config/samples/iam_v1alpha2_rolebindings.yaml new file mode 100644 index 000000000..dc42f835a --- /dev/null +++ b/config/samples/iam_v1alpha2_rolebindings.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + iam.kubesphere.io/group-ref: admin + name: group-group1-admin + namespace: proj2 + +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: admin +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: group1 diff --git a/go.mod b/go.mod index dd304be7b..283a1bfda 100644 --- a/go.mod +++ b/go.mod @@ -21,8 +21,8 @@ require ( github.com/elastic/go-elasticsearch/v6 v6.8.2 github.com/elastic/go-elasticsearch/v7 v7.3.0 github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 // indirect - github.com/emicklei/go-restful v2.11.1+incompatible - github.com/emicklei/go-restful-openapi v1.0.0 + github.com/emicklei/go-restful v2.14.3+incompatible + github.com/emicklei/go-restful-openapi v1.4.1 github.com/emirpasic/gods v1.12.0 // indirect github.com/fatih/structs v1.1.0 github.com/go-ldap/ldap v3.0.3+incompatible @@ -94,6 +94,7 @@ require ( k8s.io/klog v1.0.0 k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a k8s.io/kubectl v0.17.3 + k8s.io/utils v0.0.0-20191114184206-e782cd3c129f openpitrix.io/openpitrix v0.4.9-0.20200611125425-ae07f141e797 sigs.k8s.io/application v1.0.0 sigs.k8s.io/controller-runtime v0.5.0 @@ -187,8 +188,8 @@ replace ( github.com/elastic/go-elasticsearch/v7 => github.com/elastic/go-elasticsearch/v7 v7.3.0 github.com/elazarl/goproxy => github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 github.com/elazarl/goproxy/ext => github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 - github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.9.5+incompatible - github.com/emicklei/go-restful-openapi => github.com/emicklei/go-restful-openapi v1.0.0 + github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.14.3+incompatible + github.com/emicklei/go-restful-openapi => github.com/emicklei/go-restful-openapi v1.4.1 github.com/emirpasic/gods => github.com/emirpasic/gods v1.12.0 github.com/erikstmartin/go-testdb => github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.5.0+incompatible diff --git a/go.sum b/go.sum index 314c8c248..afadb4017 100644 --- a/go.sum +++ b/go.sum @@ -124,10 +124,10 @@ github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 h1:aZtFdDNWY/yH86J github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful-openapi v1.0.0 h1:ZFk3RuCl8ZmG1yUAF/mSbXRi5cuyA/k5+EpHayuuTXM= -github.com/emicklei/go-restful-openapi v1.0.0/go.mod h1:Q+bHVYfUWv1fvC4FNTsz2AVvFSsXAC7RCiWjF1Sva1A= +github.com/emicklei/go-restful v2.14.3+incompatible h1:i59XyRHAxKCVBw3vHzQlpP/+pi89wH1v1HL+RKyVgxk= +github.com/emicklei/go-restful v2.14.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful-openapi v1.4.1 h1:SocVTIQWnXyit4dotTrwmncBAjtRaBmfcHjo3XGcCm4= +github.com/emicklei/go-restful-openapi v1.4.1/go.mod h1:kWQ8rQMVQ6G6lePwjDveJ00KjAUr/jq6z1X8DrDP3Gc= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= diff --git a/pkg/apis/iam/v1alpha2/group_types.go b/pkg/apis/iam/v1alpha2/group_types.go new file mode 100644 index 000000000..179c64132 --- /dev/null +++ b/pkg/apis/iam/v1alpha2/group_types.go @@ -0,0 +1,63 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + ResourcePluralGroup = "groups" + GroupReferenceLabel = "iam.kubesphere.io/group-ref" + GroupParent = "iam.kubesphere.io/group-parent" +) + +// GroupSpec defines the desired state of Group +type GroupSpec struct { +} + +// GroupStatus defines the observed state of Group +type GroupStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient:nonNamespaced +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:openapi-gen=true +// +kubebuilder:printcolumn:name="Workspace",type="string",JSONPath=".metadata.labels.kubesphere\\.io/workspace" +// +kubebuilder:resource:categories="group",scope="Cluster" + +// Group is the Schema for the groups API +type Group struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec GroupSpec `json:"spec,omitempty"` + Status GroupStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient:nonNamespaced + +// GroupList contains a list of Group +type GroupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Group `json:"items"` +} diff --git a/pkg/apis/iam/v1alpha2/groupbinding_types.go b/pkg/apis/iam/v1alpha2/groupbinding_types.go new file mode 100644 index 000000000..7e120cd88 --- /dev/null +++ b/pkg/apis/iam/v1alpha2/groupbinding_types.go @@ -0,0 +1,55 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// GroupRef defines the desired relation of GroupBinding +type GroupRef struct { + APIGroup string `json:"apiGroup,omitempty"` + Kind string `json:"kind,omitempty"` + Name string `json:"name,omitempty"` +} + +// +genclient:nonNamespaced +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:openapi-gen=true +// +kubebuilder:printcolumn:name="Group",type="string",JSONPath=".groupRef.name" +// +kubebuilder:printcolumn:name="Users",type="string",JSONPath=".users" +// +kubebuilder:resource:categories="group",scope="Cluster" + +// GroupBinding is the Schema for the groupbindings API +type GroupBinding struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + GroupRef GroupRef `json:"groupRef,omitempty"` + Users []string `json:"users,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient:nonNamespaced + +// GroupBindingList contains a list of GroupBinding +type GroupBindingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []GroupBinding `json:"items"` +} diff --git a/pkg/apis/iam/v1alpha2/register.go b/pkg/apis/iam/v1alpha2/register.go index 9843c679f..54467ed9e 100644 --- a/pkg/apis/iam/v1alpha2/register.go +++ b/pkg/apis/iam/v1alpha2/register.go @@ -63,6 +63,10 @@ func addKnownTypes(scheme *runtime.Scheme) error { &WorkspaceRoleBindingList{}, &RoleBase{}, &RoleBaseList{}, + &Group{}, + &GroupList{}, + &GroupBinding{}, + &GroupBindingList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go index 4e18ee6ea..2920eccd3 100644 --- a/pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go @@ -306,6 +306,180 @@ func (in *GlobalRoleList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Group) DeepCopyInto(out *Group) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Group. +func (in *Group) DeepCopy() *Group { + if in == nil { + return nil + } + out := new(Group) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Group) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupBinding) DeepCopyInto(out *GroupBinding) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.GroupRef = in.GroupRef + if in.Users != nil { + in, out := &in.Users, &out.Users + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupBinding. +func (in *GroupBinding) DeepCopy() *GroupBinding { + if in == nil { + return nil + } + out := new(GroupBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupBindingList) DeepCopyInto(out *GroupBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GroupBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupBindingList. +func (in *GroupBindingList) DeepCopy() *GroupBindingList { + if in == nil { + return nil + } + out := new(GroupBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupList) DeepCopyInto(out *GroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Group, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupList. +func (in *GroupList) DeepCopy() *GroupList { + if in == nil { + return nil + } + out := new(GroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupRef) DeepCopyInto(out *GroupRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupRef. +func (in *GroupRef) DeepCopy() *GroupRef { + if in == nil { + return nil + } + out := new(GroupRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupSpec) DeepCopyInto(out *GroupSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupSpec. +func (in *GroupSpec) DeepCopy() *GroupSpec { + if in == nil { + return nil + } + out := new(GroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupStatus) DeepCopyInto(out *GroupStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupStatus. +func (in *GroupStatus) DeepCopy() *GroupStatus { + if in == nil { + return nil + } + out := new(GroupStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LoginRecord) DeepCopyInto(out *LoginRecord) { *out = *in diff --git a/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go b/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go new file mode 100644 index 000000000..31468526d --- /dev/null +++ b/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go @@ -0,0 +1,146 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package aliyunidaas + +import ( + "context" + "encoding/json" + "errors" + "io/ioutil" + + "golang.org/x/oauth2" + "gopkg.in/yaml.v3" + "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" + "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" +) + +type AliyunIDaaS struct { + // ClientID is the application's ID. + ClientID string `json:"clientID" yaml:"clientID"` + + // ClientSecret is the application's secret. + ClientSecret string `json:"-" yaml:"clientSecret"` + + // Endpoint contains the resource server's token endpoint + // URLs. These are constants specific to each server and are + // often available via site-specific packages, such as + // google.Endpoint or github.Endpoint. + Endpoint Endpoint `json:"endpoint" yaml:"endpoint"` + + // RedirectURL is the URL to redirect users going through + // the OAuth flow, after the resource owner's URLs. + RedirectURL string `json:"redirectURL" yaml:"redirectURL"` + + // Scope specifies optional requested permissions. + Scopes []string `json:"scopes" yaml:"scopes"` +} + +// Endpoint represents an OAuth 2.0 provider's authorization and token +// endpoint URLs. +type Endpoint struct { + AuthURL string `json:"authURL" yaml:"authURL"` + TokenURL string `json:"tokenURL" yaml:"tokenURL"` + UserInfoURL string `json:"user_info_url" yaml:"userInfoUrl"` +} + +type IDaaSIdentity struct { + Sub string `json:"sub"` + OuID string `json:"ou_id"` + Nickname string `json:"nickname"` + PhoneNumber string `json:"phone_number"` + OuName string `json:"ou_name"` + Email string `json:"email"` + Username string `json:"username"` +} + +type UserInfoResp struct { + Success bool `json:"success"` + Message string `json:"message"` + Code string `json:"code"` + IDaaSIdentity IDaaSIdentity `json:"data"` +} + +func init() { + identityprovider.RegisterOAuthProvider(&AliyunIDaaS{}) +} + +func (a *AliyunIDaaS) Type() string { + return "AliyunIDaasProvider" +} + +func (a *AliyunIDaaS) Setup(options *oauth.DynamicOptions) (identityprovider.OAuthProvider, error) { + data, err := yaml.Marshal(options) + if err != nil { + return nil, err + } + var provider AliyunIDaaS + err = yaml.Unmarshal(data, &provider) + if err != nil { + return nil, err + } + return &provider, nil +} + +func (a IDaaSIdentity) GetName() string { + return a.Username +} + +func (a IDaaSIdentity) GetEmail() string { + return a.Email +} + +func (g *AliyunIDaaS) IdentityExchange(code string) (identityprovider.Identity, error) { + config := oauth2.Config{ + ClientID: g.ClientID, + ClientSecret: g.ClientSecret, + Endpoint: oauth2.Endpoint{ + AuthURL: g.Endpoint.AuthURL, + TokenURL: g.Endpoint.TokenURL, + AuthStyle: oauth2.AuthStyleAutoDetect, + }, + RedirectURL: g.RedirectURL, + Scopes: g.Scopes, + } + token, err := config.Exchange(context.Background(), code) + if err != nil { + return nil, err + } + + resp, err := oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(token)).Get(g.Endpoint.UserInfoURL) + if err != nil { + return nil, err + } + + data, err := ioutil.ReadAll(resp.Body) + + defer resp.Body.Close() + if err != nil { + return nil, err + } + + var UserInfoResp UserInfoResp + err = json.Unmarshal(data, &UserInfoResp) + if err != nil { + return nil, err + } + + if !UserInfoResp.Success { + return nil, errors.New(UserInfoResp.Message) + } + + return UserInfoResp.IDaaSIdentity, nil +} diff --git a/pkg/apiserver/authentication/oauth/oauth_options.go b/pkg/apiserver/authentication/oauth/oauth_options.go index 9a64978cf..878eb4a3f 100644 --- a/pkg/apiserver/authentication/oauth/oauth_options.go +++ b/pkg/apiserver/authentication/oauth/oauth_options.go @@ -93,7 +93,7 @@ type IdentityProviderOptions struct { Type string `json:"type" yaml:"type"` // The options of identify provider - Provider *DynamicOptions `json:"-" yaml:"provider"` + Provider *DynamicOptions `json:"provider" yaml:"provider"` } type Token struct { diff --git a/pkg/apiserver/authentication/options/authenticate_options.go b/pkg/apiserver/authentication/options/authenticate_options.go index 1eead9558..95633ad02 100644 --- a/pkg/apiserver/authentication/options/authenticate_options.go +++ b/pkg/apiserver/authentication/options/authenticate_options.go @@ -19,6 +19,7 @@ package options import ( "fmt" "github.com/spf13/pflag" + _ "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider/aliyunidaas" _ "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider/github" "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" "time" diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_group.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_group.go new file mode 100644 index 000000000..df09f6f63 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_group.go @@ -0,0 +1,131 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" +) + +// FakeGroups implements GroupInterface +type FakeGroups struct { + Fake *FakeIamV1alpha2 +} + +var groupsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "groups"} + +var groupsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "Group"} + +// Get takes name of the group, and returns the corresponding group object, and an error if there is any. +func (c *FakeGroups) Get(name string, options v1.GetOptions) (result *v1alpha2.Group, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(groupsResource, name), &v1alpha2.Group{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.Group), err +} + +// List takes label and field selectors, and returns the list of Groups that match those selectors. +func (c *FakeGroups) List(opts v1.ListOptions) (result *v1alpha2.GroupList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(groupsResource, groupsKind, opts), &v1alpha2.GroupList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.GroupList{ListMeta: obj.(*v1alpha2.GroupList).ListMeta} + for _, item := range obj.(*v1alpha2.GroupList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested groups. +func (c *FakeGroups) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(groupsResource, opts)) +} + +// Create takes the representation of a group and creates it. Returns the server's representation of the group, and an error, if there is any. +func (c *FakeGroups) Create(group *v1alpha2.Group) (result *v1alpha2.Group, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(groupsResource, group), &v1alpha2.Group{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.Group), err +} + +// Update takes the representation of a group and updates it. Returns the server's representation of the group, and an error, if there is any. +func (c *FakeGroups) Update(group *v1alpha2.Group) (result *v1alpha2.Group, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(groupsResource, group), &v1alpha2.Group{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.Group), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeGroups) UpdateStatus(group *v1alpha2.Group) (*v1alpha2.Group, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(groupsResource, "status", group), &v1alpha2.Group{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.Group), err +} + +// Delete takes name of the group and deletes it. Returns an error if one occurs. +func (c *FakeGroups) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteAction(groupsResource, name), &v1alpha2.Group{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeGroups) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(groupsResource, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha2.GroupList{}) + return err +} + +// Patch applies the patch and returns the patched group. +func (c *FakeGroups) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Group, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(groupsResource, name, pt, data, subresources...), &v1alpha2.Group{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.Group), err +} diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_groupbinding.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_groupbinding.go new file mode 100644 index 000000000..5cd5ba724 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_groupbinding.go @@ -0,0 +1,120 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" +) + +// FakeGroupBindings implements GroupBindingInterface +type FakeGroupBindings struct { + Fake *FakeIamV1alpha2 +} + +var groupbindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "groupbindings"} + +var groupbindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "GroupBinding"} + +// Get takes name of the groupBinding, and returns the corresponding groupBinding object, and an error if there is any. +func (c *FakeGroupBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.GroupBinding, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(groupbindingsResource, name), &v1alpha2.GroupBinding{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.GroupBinding), err +} + +// List takes label and field selectors, and returns the list of GroupBindings that match those selectors. +func (c *FakeGroupBindings) List(opts v1.ListOptions) (result *v1alpha2.GroupBindingList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(groupbindingsResource, groupbindingsKind, opts), &v1alpha2.GroupBindingList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.GroupBindingList{ListMeta: obj.(*v1alpha2.GroupBindingList).ListMeta} + for _, item := range obj.(*v1alpha2.GroupBindingList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested groupBindings. +func (c *FakeGroupBindings) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(groupbindingsResource, opts)) +} + +// Create takes the representation of a groupBinding and creates it. Returns the server's representation of the groupBinding, and an error, if there is any. +func (c *FakeGroupBindings) Create(groupBinding *v1alpha2.GroupBinding) (result *v1alpha2.GroupBinding, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(groupbindingsResource, groupBinding), &v1alpha2.GroupBinding{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.GroupBinding), err +} + +// Update takes the representation of a groupBinding and updates it. Returns the server's representation of the groupBinding, and an error, if there is any. +func (c *FakeGroupBindings) Update(groupBinding *v1alpha2.GroupBinding) (result *v1alpha2.GroupBinding, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(groupbindingsResource, groupBinding), &v1alpha2.GroupBinding{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.GroupBinding), err +} + +// Delete takes name of the groupBinding and deletes it. Returns an error if one occurs. +func (c *FakeGroupBindings) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteAction(groupbindingsResource, name), &v1alpha2.GroupBinding{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeGroupBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(groupbindingsResource, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha2.GroupBindingList{}) + return err +} + +// Patch applies the patch and returns the patched groupBinding. +func (c *FakeGroupBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GroupBinding, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(groupbindingsResource, name, pt, data, subresources...), &v1alpha2.GroupBinding{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.GroupBinding), err +} diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go index e65b1b75f..b68a97c46 100644 --- a/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake/fake_iam_client.go @@ -36,6 +36,14 @@ func (c *FakeIamV1alpha2) GlobalRoleBindings() v1alpha2.GlobalRoleBindingInterfa return &FakeGlobalRoleBindings{c} } +func (c *FakeIamV1alpha2) Groups() v1alpha2.GroupInterface { + return &FakeGroups{c} +} + +func (c *FakeIamV1alpha2) GroupBindings() v1alpha2.GroupBindingInterface { + return &FakeGroupBindings{c} +} + func (c *FakeIamV1alpha2) LoginRecords() v1alpha2.LoginRecordInterface { return &FakeLoginRecords{c} } diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/generated_expansion.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/generated_expansion.go index fe6634c7a..7c75e16c8 100644 --- a/pkg/client/clientset/versioned/typed/iam/v1alpha2/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/generated_expansion.go @@ -22,6 +22,10 @@ type GlobalRoleExpansion interface{} type GlobalRoleBindingExpansion interface{} +type GroupExpansion interface{} + +type GroupBindingExpansion interface{} + type LoginRecordExpansion interface{} type RoleBaseExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/group.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/group.go new file mode 100644 index 000000000..4b0768360 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/group.go @@ -0,0 +1,180 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" + scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" +) + +// GroupsGetter has a method to return a GroupInterface. +// A group's client should implement this interface. +type GroupsGetter interface { + Groups() GroupInterface +} + +// GroupInterface has methods to work with Group resources. +type GroupInterface interface { + Create(*v1alpha2.Group) (*v1alpha2.Group, error) + Update(*v1alpha2.Group) (*v1alpha2.Group, error) + UpdateStatus(*v1alpha2.Group) (*v1alpha2.Group, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha2.Group, error) + List(opts v1.ListOptions) (*v1alpha2.GroupList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Group, err error) + GroupExpansion +} + +// groups implements GroupInterface +type groups struct { + client rest.Interface +} + +// newGroups returns a Groups +func newGroups(c *IamV1alpha2Client) *groups { + return &groups{ + client: c.RESTClient(), + } +} + +// Get takes name of the group, and returns the corresponding group object, and an error if there is any. +func (c *groups) Get(name string, options v1.GetOptions) (result *v1alpha2.Group, err error) { + result = &v1alpha2.Group{} + err = c.client.Get(). + Resource("groups"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Groups that match those selectors. +func (c *groups) List(opts v1.ListOptions) (result *v1alpha2.GroupList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.GroupList{} + err = c.client.Get(). + Resource("groups"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested groups. +func (c *groups) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("groups"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a group and creates it. Returns the server's representation of the group, and an error, if there is any. +func (c *groups) Create(group *v1alpha2.Group) (result *v1alpha2.Group, err error) { + result = &v1alpha2.Group{} + err = c.client.Post(). + Resource("groups"). + Body(group). + Do(). + Into(result) + return +} + +// Update takes the representation of a group and updates it. Returns the server's representation of the group, and an error, if there is any. +func (c *groups) Update(group *v1alpha2.Group) (result *v1alpha2.Group, err error) { + result = &v1alpha2.Group{} + err = c.client.Put(). + Resource("groups"). + Name(group.Name). + Body(group). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *groups) UpdateStatus(group *v1alpha2.Group) (result *v1alpha2.Group, err error) { + result = &v1alpha2.Group{} + err = c.client.Put(). + Resource("groups"). + Name(group.Name). + SubResource("status"). + Body(group). + Do(). + Into(result) + return +} + +// Delete takes name of the group and deletes it. Returns an error if one occurs. +func (c *groups) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Resource("groups"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *groups) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("groups"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched group. +func (c *groups) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Group, err error) { + result = &v1alpha2.Group{} + err = c.client.Patch(pt). + Resource("groups"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/groupbinding.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/groupbinding.go new file mode 100644 index 000000000..144418951 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/groupbinding.go @@ -0,0 +1,164 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" + scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" +) + +// GroupBindingsGetter has a method to return a GroupBindingInterface. +// A group's client should implement this interface. +type GroupBindingsGetter interface { + GroupBindings() GroupBindingInterface +} + +// GroupBindingInterface has methods to work with GroupBinding resources. +type GroupBindingInterface interface { + Create(*v1alpha2.GroupBinding) (*v1alpha2.GroupBinding, error) + Update(*v1alpha2.GroupBinding) (*v1alpha2.GroupBinding, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha2.GroupBinding, error) + List(opts v1.ListOptions) (*v1alpha2.GroupBindingList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GroupBinding, err error) + GroupBindingExpansion +} + +// groupBindings implements GroupBindingInterface +type groupBindings struct { + client rest.Interface +} + +// newGroupBindings returns a GroupBindings +func newGroupBindings(c *IamV1alpha2Client) *groupBindings { + return &groupBindings{ + client: c.RESTClient(), + } +} + +// Get takes name of the groupBinding, and returns the corresponding groupBinding object, and an error if there is any. +func (c *groupBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.GroupBinding, err error) { + result = &v1alpha2.GroupBinding{} + err = c.client.Get(). + Resource("groupbindings"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of GroupBindings that match those selectors. +func (c *groupBindings) List(opts v1.ListOptions) (result *v1alpha2.GroupBindingList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.GroupBindingList{} + err = c.client.Get(). + Resource("groupbindings"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested groupBindings. +func (c *groupBindings) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("groupbindings"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a groupBinding and creates it. Returns the server's representation of the groupBinding, and an error, if there is any. +func (c *groupBindings) Create(groupBinding *v1alpha2.GroupBinding) (result *v1alpha2.GroupBinding, err error) { + result = &v1alpha2.GroupBinding{} + err = c.client.Post(). + Resource("groupbindings"). + Body(groupBinding). + Do(). + Into(result) + return +} + +// Update takes the representation of a groupBinding and updates it. Returns the server's representation of the groupBinding, and an error, if there is any. +func (c *groupBindings) Update(groupBinding *v1alpha2.GroupBinding) (result *v1alpha2.GroupBinding, err error) { + result = &v1alpha2.GroupBinding{} + err = c.client.Put(). + Resource("groupbindings"). + Name(groupBinding.Name). + Body(groupBinding). + Do(). + Into(result) + return +} + +// Delete takes name of the groupBinding and deletes it. Returns an error if one occurs. +func (c *groupBindings) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Resource("groupbindings"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *groupBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("groupbindings"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched groupBinding. +func (c *groupBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GroupBinding, err error) { + result = &v1alpha2.GroupBinding{} + err = c.client.Patch(pt). + Resource("groupbindings"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/iam/v1alpha2/iam_client.go b/pkg/client/clientset/versioned/typed/iam/v1alpha2/iam_client.go index 4378bbf76..a0e925a87 100644 --- a/pkg/client/clientset/versioned/typed/iam/v1alpha2/iam_client.go +++ b/pkg/client/clientset/versioned/typed/iam/v1alpha2/iam_client.go @@ -28,6 +28,8 @@ type IamV1alpha2Interface interface { RESTClient() rest.Interface GlobalRolesGetter GlobalRoleBindingsGetter + GroupsGetter + GroupBindingsGetter LoginRecordsGetter RoleBasesGetter UsersGetter @@ -48,6 +50,14 @@ func (c *IamV1alpha2Client) GlobalRoleBindings() GlobalRoleBindingInterface { return newGlobalRoleBindings(c) } +func (c *IamV1alpha2Client) Groups() GroupInterface { + return newGroups(c) +} + +func (c *IamV1alpha2Client) GroupBindings() GroupBindingInterface { + return newGroupBindings(c) +} + func (c *IamV1alpha2Client) LoginRecords() LoginRecordInterface { return newLoginRecords(c) } diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 38dcc25b5..5407c9e17 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -93,6 +93,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GlobalRoles().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("globalrolebindings"): return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GlobalRoleBindings().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("groups"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().Groups().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("groupbindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GroupBindings().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("loginrecords"): return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().LoginRecords().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("rolebases"): diff --git a/pkg/client/informers/externalversions/iam/v1alpha2/group.go b/pkg/client/informers/externalversions/iam/v1alpha2/group.go new file mode 100644 index 000000000..f4c814846 --- /dev/null +++ b/pkg/client/informers/externalversions/iam/v1alpha2/group.go @@ -0,0 +1,88 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" + iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" + versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned" + internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" + v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2" +) + +// GroupInformer provides access to a shared informer and lister for +// Groups. +type GroupInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.GroupLister +} + +type groupInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewGroupInformer constructs a new informer for Group type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewGroupInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredGroupInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredGroupInformer constructs a new informer for Group type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredGroupInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.IamV1alpha2().Groups().List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.IamV1alpha2().Groups().Watch(options) + }, + }, + &iamv1alpha2.Group{}, + resyncPeriod, + indexers, + ) +} + +func (f *groupInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredGroupInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *groupInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&iamv1alpha2.Group{}, f.defaultInformer) +} + +func (f *groupInformer) Lister() v1alpha2.GroupLister { + return v1alpha2.NewGroupLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/iam/v1alpha2/groupbinding.go b/pkg/client/informers/externalversions/iam/v1alpha2/groupbinding.go new file mode 100644 index 000000000..9531fc7a9 --- /dev/null +++ b/pkg/client/informers/externalversions/iam/v1alpha2/groupbinding.go @@ -0,0 +1,88 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" + iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" + versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned" + internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" + v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2" +) + +// GroupBindingInformer provides access to a shared informer and lister for +// GroupBindings. +type GroupBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.GroupBindingLister +} + +type groupBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewGroupBindingInformer constructs a new informer for GroupBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewGroupBindingInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredGroupBindingInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredGroupBindingInformer constructs a new informer for GroupBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredGroupBindingInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.IamV1alpha2().GroupBindings().List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.IamV1alpha2().GroupBindings().Watch(options) + }, + }, + &iamv1alpha2.GroupBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *groupBindingInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredGroupBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *groupBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&iamv1alpha2.GroupBinding{}, f.defaultInformer) +} + +func (f *groupBindingInformer) Lister() v1alpha2.GroupBindingLister { + return v1alpha2.NewGroupBindingLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/iam/v1alpha2/interface.go b/pkg/client/informers/externalversions/iam/v1alpha2/interface.go index 7d91aef4e..5e0dc0f56 100644 --- a/pkg/client/informers/externalversions/iam/v1alpha2/interface.go +++ b/pkg/client/informers/externalversions/iam/v1alpha2/interface.go @@ -28,6 +28,10 @@ type Interface interface { GlobalRoles() GlobalRoleInformer // GlobalRoleBindings returns a GlobalRoleBindingInformer. GlobalRoleBindings() GlobalRoleBindingInformer + // Groups returns a GroupInformer. + Groups() GroupInformer + // GroupBindings returns a GroupBindingInformer. + GroupBindings() GroupBindingInformer // LoginRecords returns a LoginRecordInformer. LoginRecords() LoginRecordInformer // RoleBases returns a RoleBaseInformer. @@ -61,6 +65,16 @@ func (v *version) GlobalRoleBindings() GlobalRoleBindingInformer { return &globalRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// Groups returns a GroupInformer. +func (v *version) Groups() GroupInformer { + return &groupInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// GroupBindings returns a GroupBindingInformer. +func (v *version) GroupBindings() GroupBindingInformer { + return &groupBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // LoginRecords returns a LoginRecordInformer. func (v *version) LoginRecords() LoginRecordInformer { return &loginRecordInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/listers/iam/v1alpha2/expansion_generated.go b/pkg/client/listers/iam/v1alpha2/expansion_generated.go index 27cb25919..cb0af8fff 100644 --- a/pkg/client/listers/iam/v1alpha2/expansion_generated.go +++ b/pkg/client/listers/iam/v1alpha2/expansion_generated.go @@ -26,6 +26,14 @@ type GlobalRoleListerExpansion interface{} // GlobalRoleBindingLister. type GlobalRoleBindingListerExpansion interface{} +// GroupListerExpansion allows custom methods to be added to +// GroupLister. +type GroupListerExpansion interface{} + +// GroupBindingListerExpansion allows custom methods to be added to +// GroupBindingLister. +type GroupBindingListerExpansion interface{} + // LoginRecordListerExpansion allows custom methods to be added to // LoginRecordLister. type LoginRecordListerExpansion interface{} diff --git a/pkg/client/listers/iam/v1alpha2/group.go b/pkg/client/listers/iam/v1alpha2/group.go new file mode 100644 index 000000000..ee61c76e8 --- /dev/null +++ b/pkg/client/listers/iam/v1alpha2/group.go @@ -0,0 +1,65 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" +) + +// GroupLister helps list Groups. +type GroupLister interface { + // List lists all Groups in the indexer. + List(selector labels.Selector) (ret []*v1alpha2.Group, err error) + // Get retrieves the Group from the index for a given name. + Get(name string) (*v1alpha2.Group, error) + GroupListerExpansion +} + +// groupLister implements the GroupLister interface. +type groupLister struct { + indexer cache.Indexer +} + +// NewGroupLister returns a new GroupLister. +func NewGroupLister(indexer cache.Indexer) GroupLister { + return &groupLister{indexer: indexer} +} + +// List lists all Groups in the indexer. +func (s *groupLister) List(selector labels.Selector) (ret []*v1alpha2.Group, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.Group)) + }) + return ret, err +} + +// Get retrieves the Group from the index for a given name. +func (s *groupLister) Get(name string) (*v1alpha2.Group, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("group"), name) + } + return obj.(*v1alpha2.Group), nil +} diff --git a/pkg/client/listers/iam/v1alpha2/groupbinding.go b/pkg/client/listers/iam/v1alpha2/groupbinding.go new file mode 100644 index 000000000..002baa1cf --- /dev/null +++ b/pkg/client/listers/iam/v1alpha2/groupbinding.go @@ -0,0 +1,65 @@ +/* +Copyright 2020 The KubeSphere Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" +) + +// GroupBindingLister helps list GroupBindings. +type GroupBindingLister interface { + // List lists all GroupBindings in the indexer. + List(selector labels.Selector) (ret []*v1alpha2.GroupBinding, err error) + // Get retrieves the GroupBinding from the index for a given name. + Get(name string) (*v1alpha2.GroupBinding, error) + GroupBindingListerExpansion +} + +// groupBindingLister implements the GroupBindingLister interface. +type groupBindingLister struct { + indexer cache.Indexer +} + +// NewGroupBindingLister returns a new GroupBindingLister. +func NewGroupBindingLister(indexer cache.Indexer) GroupBindingLister { + return &groupBindingLister{indexer: indexer} +} + +// List lists all GroupBindings in the indexer. +func (s *groupBindingLister) List(selector labels.Selector) (ret []*v1alpha2.GroupBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.GroupBinding)) + }) + return ret, err +} + +// Get retrieves the GroupBinding from the index for a given name. +func (s *groupBindingLister) Get(name string) (*v1alpha2.GroupBinding, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("groupbinding"), name) + } + return obj.(*v1alpha2.GroupBinding), nil +} diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 631613c76..5599a8192 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -32,63 +32,80 @@ const ( AdminUserName = "admin" IngressControllerPrefix = "kubesphere-router-" - WorkspaceLabelKey = "kubesphere.io/workspace" - NamespaceLabelKey = "kubesphere.io/namespace" - RuntimeLabelKey = "openpitrix.io/namespace" - DisplayNameAnnotationKey = "kubesphere.io/alias-name" - DescriptionAnnotationKey = "kubesphere.io/description" - CreatorAnnotationKey = "kubesphere.io/creator" - UsernameLabelKey = "kubesphere.io/username" - System = "system" - OpenPitrixRuntimeAnnotationKey = "openpitrix_runtime" - WorkspaceAdmin = "workspace-admin" - ClusterAdmin = "cluster-admin" - WorkspaceRegular = "workspace-regular" - WorkspaceViewer = "workspace-viewer" - WorkspacesManager = "workspaces-manager" - DevopsOwner = "owner" - DevopsReporter = "reporter" - DevOpsProjectLabelKey = "kubesphere.io/devopsproject" - KubefedManagedLabel = "kubefed.io/managed" + WorkspaceLabelKey = "kubesphere.io/workspace" + NamespaceLabelKey = "kubesphere.io/namespace" + DisplayNameAnnotationKey = "kubesphere.io/alias-name" + DescriptionAnnotationKey = "kubesphere.io/description" + CreatorAnnotationKey = "kubesphere.io/creator" + UsernameLabelKey = "kubesphere.io/username" + DevOpsProjectLabelKey = "kubesphere.io/devopsproject" + KubefedManagedLabel = "kubefed.io/managed" UserNameHeader = "X-Token-Username" - TenantResourcesTag = "Tenant Resources" - IdentityManagementTag = "Identity Management" - AccessManagementTag = "Access Management" - NamespaceResourcesTag = "Namespace Resources" - ClusterResourcesTag = "Cluster Resources" - ComponentStatusTag = "Component Status" - OpenpitrixTag = "Openpitrix Resources" - VerificationTag = "Verification" - RegistryTag = "Docker Registry" - NetworkTopologyTag = "Network Topology" - UserResourcesTag = "User Resources" - DevOpsProjectTag = "DevOps Project" - DevOpsProjectCredentialTag = "DevOps Project Credential" - DevOpsProjectMemberTag = "DevOps Project Member" - DevOpsPipelineTag = "DevOps Pipeline" - DevOpsWebhookTag = "DevOps Webhook" - DevOpsJenkinsfileTag = "DevOps Jenkinsfile" - DevOpsScmTag = "DevOps Scm" - KubeSphereMetricsTag = "KubeSphere Metrics" - ClusterMetricsTag = "Cluster Metrics" - NodeMetricsTag = "Node Metrics" - NamespaceMetricsTag = "Namespace Metrics" - PodMetricsTag = "Pod Metrics" - PVCMetricsTag = "PVC Metrics" - ContainerMetricsTag = "Container Metrics" - WorkloadMetricsTag = "Workload Metrics" - WorkspaceMetricsTag = "Workspace Metrics" - ComponentMetricsTag = "Component Metrics" - CustomMetricsTag = "Custom Metrics" - LogQueryTag = "Log Query" - TerminalTag = "Terminal" - EventsQueryTag = "Events Query" - AuditingQueryTag = "Auditing Query" + AuthenticationTag = "Authentication" + UserTag = "User" + GroupTag = "Group" + + WorkspaceMemberTag = "Workspace Member" + DevOpsProjectMemberTag = "DevOps Project Member" + NamespaceMemberTag = "Namespace Member" + ClusterMemberTag = "Cluster Member" + + GlobalRoleTag = "Global Role" + ClusterRoleTag = "Cluster Role" + WorkspaceRoleTag = "Workspace Role" + DevOpsProjectRoleTag = "DevOps Project Role" + NamespaceRoleTag = "Namespace Role" + + OpenpitrixAppInstanceTag = "App Instance" + OpenpitrixAppTemplateTag = "App Template" + OpenpitrixCategoryTag = "Category" + OpenpitrixAttachmentTag = "Attachment" + OpenpitrixRepositoryTag = "Repository" + OpenpitrixManagementTag = "App Management" + + DevOpsCredentialTag = "DevOps Credential" + DevOpsPipelineTag = "DevOps Pipeline" + DevOpsWebhookTag = "DevOps Webhook" + DevOpsJenkinsfileTag = "DevOps Jenkinsfile" + DevOpsScmTag = "DevOps Scm" + DevOpsJenkinsTag = "Jenkins" + + ToolboxTag = "Toolbox" + RegistryTag = "Docker Registry" + GitTag = "Git" + TerminalTag = "Terminal" + MultiClusterTag = "Multi-cluster" + + WorkspaceTag = "Workspace" + NamespaceTag = "Namespace" + DevOpsProjectTag = "DevOps Project" + UserResourceTag = "User's Resources" + + NamespaceResourcesTag = "Namespace Resources" + ClusterResourcesTag = "Cluster Resources" + ComponentStatusTag = "Component Status" + + NetworkTopologyTag = "Network Topology" + + KubeSphereMetricsTag = "KubeSphere Metrics" + ClusterMetricsTag = "Cluster Metrics" + NodeMetricsTag = "Node Metrics" + NamespaceMetricsTag = "Namespace Metrics" + PodMetricsTag = "Pod Metrics" + PVCMetricsTag = "PVC Metrics" + ContainerMetricsTag = "Container Metrics" + WorkloadMetricsTag = "Workload Metrics" + WorkspaceMetricsTag = "Workspace Metrics" + ComponentMetricsTag = "Component Metrics" + CustomMetricsTag = "Custom Metrics" + + LogQueryTag = "Log Query" + EventsQueryTag = "Events Query" + AuditingQueryTag = "Auditing Query" ) var ( - WorkSpaceRoles = []string{WorkspaceAdmin, WorkspaceRegular, WorkspaceViewer} SystemNamespaces = []string{KubeSphereNamespace, KubeSphereLoggingNamespace, KubeSphereMonitoringNamespace, OpenPitrixNamespace, KubeSystemNamespace, IstioNamespace, KubesphereDevOpsNamespace, PorterNamespace} ) diff --git a/pkg/controller/application/application_controller.go b/pkg/controller/application/application_controller.go index d1355b9d4..f69108e7e 100644 --- a/pkg/controller/application/application_controller.go +++ b/pkg/controller/application/application_controller.go @@ -112,6 +112,7 @@ func NewApplicationController(serviceInformer coreinformers.ServiceInformer, deploymentInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: v.enqueueObject, + UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) }, DeleteFunc: v.enqueueObject, }) @@ -120,6 +121,7 @@ func NewApplicationController(serviceInformer coreinformers.ServiceInformer, statefulSetInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: v.enqueueObject, + UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) }, DeleteFunc: v.enqueueObject, }) @@ -128,6 +130,7 @@ func NewApplicationController(serviceInformer coreinformers.ServiceInformer, serviceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: v.enqueueObject, + UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) }, DeleteFunc: v.enqueueObject, }) @@ -136,6 +139,7 @@ func NewApplicationController(serviceInformer coreinformers.ServiceInformer, strategyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: v.enqueueObject, + UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) }, DeleteFunc: v.enqueueObject, }) @@ -144,6 +148,7 @@ func NewApplicationController(serviceInformer coreinformers.ServiceInformer, servicePolicyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: v.enqueueObject, + UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) }, DeleteFunc: v.enqueueObject, }) diff --git a/pkg/controller/cluster/cluster_controller.go b/pkg/controller/cluster/cluster_controller.go index fe315df01..0a5377b9b 100644 --- a/pkg/controller/cluster/cluster_controller.go +++ b/pkg/controller/cluster/cluster_controller.go @@ -440,6 +440,12 @@ func (c *clusterController) syncCluster(key string) error { return nil } + // currently we didn't set cluster.Spec.Enable when creating cluster at client side, so only check + // if we enable cluster.Spec.JoinFederation now + if cluster.Spec.JoinFederation == false { + return nil + } + // save a old copy of cluster oldCluster := cluster.DeepCopy() diff --git a/pkg/kapis/cluster/v1alpha1/register.go b/pkg/kapis/cluster/v1alpha1/register.go index 91737f8a6..3b540b8e4 100644 --- a/pkg/kapis/cluster/v1alpha1/register.go +++ b/pkg/kapis/cluster/v1alpha1/register.go @@ -18,11 +18,13 @@ package v1alpha1 import ( "github.com/emicklei/go-restful" + restfulspec "github.com/emicklei/go-restful-openapi" "k8s.io/apimachinery/pkg/runtime/schema" k8sinformers "k8s.io/client-go/informers" "kubesphere.io/kubesphere/pkg/api" "kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/client/informers/externalversions" + "kubesphere.io/kubesphere/pkg/constants" "net/http" ) @@ -47,13 +49,15 @@ func AddToContainer(container *restful.Container, Doc("Return deployment yaml for cluster agent."). Param(webservice.PathParameter("cluster", "Name of the cluster.").Required(true)). To(h.generateAgentDeployment). - Returns(http.StatusOK, api.StatusOK, nil)) + Returns(http.StatusOK, api.StatusOK, nil). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.MultiClusterTag})) webservice.Route(webservice.POST("/clusters/validation"). Doc(""). Param(webservice.BodyParameter("cluster", "cluster specification")). To(h.validateCluster). - Returns(http.StatusOK, api.StatusOK, nil)) + Returns(http.StatusOK, api.StatusOK, nil). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.MultiClusterTag})) container.Add(webservice) diff --git a/pkg/kapis/devops/v1alpha2/register.go b/pkg/kapis/devops/v1alpha2/register.go index 3803a379a..5b6e7ec37 100644 --- a/pkg/kapis/devops/v1alpha2/register.go +++ b/pkg/kapis/devops/v1alpha2/register.go @@ -84,7 +84,7 @@ func AddPipelineToWebService(webservice *restful.WebService, devopsClient devops webservice.Route(webservice.GET("/devops/{devops}/credentials/{credential}/usage"). To(projectPipelineHandler.GetProjectCredentialUsage). Doc("Get the specified credential usage of the DevOps project"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectCredentialTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsCredentialTag}). Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")). Param(webservice.PathParameter("credential", "credential's ID, e.g. dockerhub-id")). Returns(http.StatusOK, RespOK, devops.Credential{})) @@ -697,7 +697,9 @@ func AddJenkinsToContainer(webservice *restful.WebService, devopsClient devops.I u.Path = strings.Replace(request.Request.URL.Path, fmt.Sprintf("/kapis/%s/%s/jenkins", GroupVersion.Group, GroupVersion.Version), "", 1) httpProxy := proxy.NewUpgradeAwareHandler(u, http.DefaultTransport, false, false, &errorResponder{}) httpProxy.ServeHTTP(response, request.Request) - }).Returns(http.StatusOK, RespOK, nil)) + }). + Returns(http.StatusOK, RespOK, nil). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsJenkinsTag})) return nil } diff --git a/pkg/kapis/iam/v1alpha2/register.go b/pkg/kapis/iam/v1alpha2/register.go index c82e461b3..06a50b08f 100644 --- a/pkg/kapis/iam/v1alpha2/register.go +++ b/pkg/kapis/iam/v1alpha2/register.go @@ -46,336 +46,335 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf // users ws.Route(ws.POST("/users"). To(handler.CreateUser). - Doc("Create user in global scope."). + Doc("Create a global user account."). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). Reads(iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserTag})) ws.Route(ws.DELETE("/users/{user}"). To(handler.DeleteUser). - Doc("Delete user."). + Doc("Delete the specified user."). Param(ws.PathParameter("user", "username")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserTag})) ws.Route(ws.PUT("/users/{user}"). To(handler.UpdateUser). - Doc("Update user info."). + Doc("Update user profile."). Reads(iamv1alpha2.User{}). Param(ws.PathParameter("user", "username")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserTag})) ws.Route(ws.PUT("/users/{user}/password"). To(handler.ModifyPassword). - Doc("Modify user's password."). + Doc("Reset password of the specified user."). Reads(iam.PasswordReset{}). Param(ws.PathParameter("user", "username")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserTag})) ws.Route(ws.GET("/users/{user}"). To(handler.DescribeUser). Doc("Retrieve user details."). Param(ws.PathParameter("user", "username")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) - + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserTag})) ws.Route(ws.GET("/users"). To(handler.ListUsers). - Doc("List all users in global scope."). + Doc("List all users."). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserTag})) ws.Route(ws.GET("/users/{user}/loginrecords"). To(handler.ListUserLoginRecords). Param(ws.PathParameter("user", "username of the user")). - Doc("List user's login records."). + Doc("List login records of the specified user."). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.LoginRecord{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourceTag})) // clustermembers ws.Route(ws.POST("/clustermembers"). To(handler.CreateClusterMembers). - Doc("Add user to current cluster."). + Doc("Add members to current cluster in bulk."). Reads([]Member{}). Returns(http.StatusOK, api.StatusOK, []Member{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterMemberTag})) ws.Route(ws.DELETE("/clustermembers/{clustermember}"). To(handler.RemoveClusterMember). - Doc("Delete member in cluster scope."). + Doc("Delete a member from current cluster."). Param(ws.PathParameter("clustermember", "cluster member's username")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterMemberTag})) ws.Route(ws.PUT("/clustermembers/{clustermember}"). To(handler.UpdateClusterMember). - Doc("Update cluster member role bind."). + Doc("Update the cluster role bind of the member."). Reads(Member{}). Returns(http.StatusOK, api.StatusOK, Member{}). Param(ws.PathParameter("clustermember", "cluster member's username")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterMemberTag})) ws.Route(ws.GET("/clustermembers/{clustermember}"). To(handler.DescribeClusterMember). - Doc("Retrieve member details in cluster."). + Doc("Retrieve the cluster role of the specified member."). Param(ws.PathParameter("clustermember", "cluster member's username")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterMemberTag})) ws.Route(ws.GET("/clustermembers"). To(handler.ListClusterMembers). Doc("List all members in cluster."). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterMemberTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers"). To(handler.ListWorkspaceMembers). Doc("List all members in the specified workspace."). Param(ws.PathParameter("workspace", "workspace name")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceMemberTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers/{workspacemember}"). To(handler.DescribeWorkspaceMember). - Doc("Retrieve workspace member details."). + Doc("Retrieve the workspace role of the specified member."). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacemember", "workspace member's username")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceMemberTag})) ws.Route(ws.POST("/workspaces/{workspace}/workspacemembers"). To(handler.CreateWorkspaceMembers). - Doc("Batch add workspace members."). + Doc("Add members to current cluster in bulk."). Reads([]Member{}). Returns(http.StatusOK, api.StatusOK, []Member{}). Param(ws.PathParameter("workspace", "workspace name")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceMemberTag})) ws.Route(ws.PUT("/workspaces/{workspace}/workspacemembers/{workspacemember}"). To(handler.UpdateWorkspaceMember). - Doc("Update member in workspace."). + Doc("Update the workspace role bind of the member."). Reads(Member{}). Returns(http.StatusOK, api.StatusOK, Member{}). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacemember", "workspace member's username")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceMemberTag})) ws.Route(ws.DELETE("/workspaces/{workspace}/workspacemembers/{workspacemember}"). To(handler.RemoveWorkspaceMember). - Doc("Delete member in workspace scope."). + Doc("Delete a member from the workspace."). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacemember", "workspace member's username")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceMemberTag})) ws.Route(ws.GET("/namespaces/{namespace}/members"). To(handler.ListNamespaceMembers). Doc("List all members in the specified namespace."). Param(ws.PathParameter("namespace", "namespace")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceMemberTag})) ws.Route(ws.GET("/namespaces/{namespace}/members/{member}"). To(handler.DescribeNamespaceMember). - Doc("Retrieve namespace member details."). + Doc("Retrieve the role of the specified member."). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("member", "namespace member's username")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceMemberTag})) ws.Route(ws.POST("/namespaces/{namespace}/members"). To(handler.CreateNamespaceMembers). - Doc("Batch add namespace members."). + Doc("Add members to the namespace in bulk."). Reads([]Member{}). Returns(http.StatusOK, api.StatusOK, []Member{}). Param(ws.PathParameter("namespace", "namespace")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceMemberTag})) ws.Route(ws.PUT("/namespaces/{namespace}/members/{member}"). To(handler.UpdateNamespaceMember). - Doc("Update member in namespace."). + Doc("Update the role bind of the member."). Reads(Member{}). Returns(http.StatusOK, api.StatusOK, Member{}). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("member", "namespace member's username")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceMemberTag})) ws.Route(ws.DELETE("/namespaces/{namespace}/members/{member}"). To(handler.RemoveNamespaceMember). - Doc("Delete member in namespace scope."). + Doc("Delete a member from the namespace."). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("member", "namespace member's username")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceMemberTag})) ws.Route(ws.GET("/devops/{devops}/members"). To(handler.ListNamespaceMembers). Doc("List all members in the specified devops project."). Param(ws.PathParameter("devops", "devops project name")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag})) ws.Route(ws.GET("/devops/{devops}/members/{member}"). To(handler.DescribeNamespaceMember). Doc("Retrieve devops project member details."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("member", "devops project member's username")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.User{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag})) ws.Route(ws.POST("/devops/{devops}/members"). To(handler.CreateNamespaceMembers). - Doc("Batch add devops project members."). + Doc("Add members to the DevOps project in bulk."). Reads([]Member{}). Returns(http.StatusOK, api.StatusOK, []Member{}). Param(ws.PathParameter("devops", "devops project name")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag})) ws.Route(ws.PUT("/devops/{devops}/members/{member}"). To(handler.UpdateNamespaceMember). - Doc("Update member in devops project."). + Doc("Update the role bind of the member."). Reads(Member{}). Returns(http.StatusOK, api.StatusOK, Member{}). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("member", "devops project member's username")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag})) ws.Route(ws.DELETE("/devops/{devops}/members/{member}"). To(handler.RemoveNamespaceMember). - Doc("Remove member in namespace."). + Doc("Delete a member from the DevOps project."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("member", "devops project member's username")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag})) // globalroles ws.Route(ws.POST("/globalroles"). To(handler.CreateGlobalRole). - Doc("Create global role. Automatically aggregate policy rules according to annotation."). + Doc("Create global role."). Reads(iamv1alpha2.GlobalRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) ws.Route(ws.DELETE("/globalroles/{globalrole}"). To(handler.DeleteGlobalRole). Doc("Delete global role."). Param(ws.PathParameter("globalrole", "global role name")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) ws.Route(ws.PUT("/globalroles/{globalrole}"). To(handler.UpdateGlobalRole). - Doc("Update global role. Automatically aggregate policy rules according to annotation."). + Doc("Update global role."). Param(ws.PathParameter("globalrole", "global role name")). Reads(iamv1alpha2.GlobalRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) ws.Route(ws.PATCH("/globalroles/{globalrole}"). To(handler.PatchGlobalRole). - Doc("Patch global role. Automatically aggregate policy rules according to annotation."). + Doc("Patch global role."). Param(ws.PathParameter("globalrole", "global role name")). Reads(iamv1alpha2.GlobalRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) ws.Route(ws.GET("/globalroles"). To(handler.ListGlobalRoles). Doc("List all global roles."). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.GlobalRole{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) ws.Route(ws.GET("/globalroles/{globalrole}"). To(handler.DescribeGlobalRole). Param(ws.PathParameter("globalrole", "global role name")). Doc("Retrieve global role details."). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) // clusterroles ws.Route(ws.POST("/clusterroles"). To(handler.CreateClusterRole). - Doc("Create cluster role. Automatically aggregate policy rules according to annotation."). + Doc("Create cluster role."). Reads(rbacv1.ClusterRole{}). Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) ws.Route(ws.DELETE("/clusterroles/{clusterrole}"). To(handler.DeleteClusterRole). Doc("Delete cluster role."). Param(ws.PathParameter("clusterrole", "cluster role name")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) ws.Route(ws.PUT("/clusterroles/{clusterrole}"). To(handler.UpdateClusterRole). - Doc("Update cluster role. Automatically aggregate policy rules according to annotation."). + Doc("Update cluster role."). Param(ws.PathParameter("clusterrole", "cluster role name")). Reads(rbacv1.ClusterRole{}). Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) ws.Route(ws.PATCH("/clusterroles/{clusterrole}"). To(handler.PatchClusterRole). - Doc("Patch cluster role. Automatically aggregate policy rules according to annotation."). + Doc("Patch cluster role."). Param(ws.PathParameter("clusterrole", "cluster role name")). Reads(rbacv1.ClusterRole{}). Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) ws.Route(ws.GET("/clusterroles"). To(handler.ListClusterRoles). Doc("List all cluster roles."). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{rbacv1.ClusterRole{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) ws.Route(ws.GET("/clusterroles/{clusterrole}"). To(handler.DescribeClusterRole). Param(ws.PathParameter("clusterrole", "cluster role name")). Doc("Retrieve cluster role details."). Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) // workspaceroles ws.Route(ws.POST("/workspaces/{workspace}/workspaceroles"). To(handler.CreateWorkspaceRole). - Doc("Create workspace role. Automatically aggregate policy rules according to annotation."). + Doc("Create workspace role."). Reads(iamv1alpha2.WorkspaceRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.WorkspaceRole{}). Param(ws.PathParameter("workspace", "workspace name")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) ws.Route(ws.DELETE("/workspaces/{workspace}/workspaceroles/{workspacerole}"). To(handler.DeleteWorkspaceRole). Doc("Delete workspace role."). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacerole", "workspace role name")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) ws.Route(ws.PATCH("/workspaces/{workspace}/workspaceroles/{workspacerole}"). To(handler.PatchWorkspaceRole). - Doc("Patch workspace role. Automatically aggregate policy rules according to annotation."). + Doc("Patch workspace role."). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacerole", "workspace role name")). Reads(iamv1alpha2.WorkspaceRole{}). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) ws.Route(ws.PUT("/workspaces/{workspace}/workspaceroles/{workspacerole}"). To(handler.UpdateWorkspaceRole). - Doc("Update workspace role. Automatically aggregate policy rules according to annotation."). + Doc("Update workspace role."). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacerole", "workspace role name")). Reads(iamv1alpha2.WorkspaceRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.WorkspaceRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspaceroles"). To(handler.ListWorkspaceRoles). Doc("List all workspace roles."). Param(ws.PathParameter("workspace", "workspace name")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.WorkspaceRole{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspaceroles/{workspacerole}"). To(handler.DescribeWorkspaceRole). Doc("Retrieve workspace role details."). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspacerole", "workspace role name")). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.WorkspaceRole{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) // roles ws.Route(ws.POST("/namespaces/{namespace}/roles"). To(handler.CreateNamespaceRole). - Doc("Create role in the specified namespace. Automatically aggregate policy rules according to annotation."). + Doc("Create role in the specified namespace."). Reads(rbacv1.Role{}). Param(ws.PathParameter("namespace", "namespace")). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) ws.Route(ws.DELETE("/namespaces/{namespace}/roles/{role}"). To(handler.DeleteNamespaceRole). Doc("Delete role in the specified namespace."). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("role", "role name")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) ws.Route(ws.PUT("/namespaces/{namespace}/roles/{role}"). To(handler.UpdateNamespaceRole). - Doc("Update namespace role. Automatically aggregate policy rules according to annotation."). + Doc("Update namespace role."). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("role", "role name")). Reads(rbacv1.Role{}). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) ws.Route(ws.PATCH("/namespaces/{namespace}/roles/{role}"). To(handler.PatchNamespaceRole). Doc("Patch namespace role."). @@ -383,99 +382,99 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf Param(ws.PathParameter("role", "role name")). Reads(rbacv1.Role{}). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) ws.Route(ws.GET("/namespaces/{namespace}/roles"). To(handler.ListRoles). Doc("List all roles in the specified namespace."). Param(ws.PathParameter("namespace", "namespace")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{rbacv1.Role{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}"). To(handler.DescribeNamespaceRole). Doc("Retrieve role details."). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("role", "role name")). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) // roles ws.Route(ws.POST("/devops/{devops}/roles"). To(handler.CreateNamespaceRole). - Doc("Create role in the specified devops project. Automatically aggregate policy rules according to annotation."). + Doc("Create role in the specified devops project."). Reads(rbacv1.Role{}). Param(ws.PathParameter("devops", "devops project name")). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) ws.Route(ws.DELETE("/devops/{devops}/roles/{role}"). To(handler.DeleteNamespaceRole). Doc("Delete role in the specified devops project."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("role", "role name")). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) ws.Route(ws.PUT("/devops/{devops}/roles/{role}"). To(handler.UpdateNamespaceRole). - Doc("Update devops project role. Automatically aggregate policy rules according to annotation."). + Doc("Update devops project role."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("role", "role name")). Reads(rbacv1.Role{}). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) ws.Route(ws.PATCH("/devops/{devops}/roles/{role}"). To(handler.PatchNamespaceRole). - Doc("Patch devops project role. Automatically aggregate policy rules according to annotation."). + Doc("Patch devops project role."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("role", "role name")). Reads(rbacv1.Role{}). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) ws.Route(ws.GET("/devops/{devops}/roles"). To(handler.ListRoles). Doc("List all roles in the specified devops project."). Param(ws.PathParameter("devops", "devops project name")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{rbacv1.Role{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) ws.Route(ws.GET("/devops/{devops}/roles/{role}"). To(handler.DescribeNamespaceRole). Doc("Retrieve devops project role details."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("role", "role name")). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) ws.Route(ws.GET("/users/{user}/globalroles"). To(handler.RetrieveMemberRoleTemplates). Doc("Retrieve user's global role templates."). Param(ws.PathParameter("user", "username")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.GlobalRole{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GlobalRoleTag})) ws.Route(ws.GET("/clustermembers/{clustermember}/clusterroles"). To(handler.RetrieveMemberRoleTemplates). Doc("Retrieve user's role templates in cluster."). Param(ws.PathParameter("clustermember", "cluster member's username")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{rbacv1.ClusterRole{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterRoleTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers/{workspacemember}/workspaceroles"). To(handler.RetrieveMemberRoleTemplates). Doc("Retrieve member's role templates in workspace."). Param(ws.PathParameter("workspace", "workspace")). Param(ws.PathParameter("workspacemember", "workspace member's username")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.WorkspaceRole{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceRoleTag})) ws.Route(ws.GET("/namespaces/{namespace}/members/{member}/roles"). To(handler.RetrieveMemberRoleTemplates). Doc("Retrieve member's role templates in namespace."). Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("member", "namespace member's username")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{rbacv1.Role{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag})) ws.Route(ws.GET("/devops/{devops}/members/{member}/roles"). To(handler.RetrieveMemberRoleTemplates). Doc("Retrieve member's role templates in devops project."). Param(ws.PathParameter("devops", "devops project name")). Param(ws.PathParameter("member", "devops project member's username")). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{rbacv1.Role{}}}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectRoleTag})) container.Add(ws) return nil diff --git a/pkg/kapis/oauth/register.go b/pkg/kapis/oauth/register.go index af76e0235..a647326c6 100644 --- a/pkg/kapis/oauth/register.go +++ b/pkg/kapis/oauth/register.go @@ -50,7 +50,7 @@ func AddToContainer(c *restful.Container, im im.IdentityManagementInterface, tok Reads(auth.TokenReview{}). To(handler.TokenReview). Returns(http.StatusOK, api.StatusOK, auth.TokenReview{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.IdentityManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag})) // Only support implicit grant flow // https://tools.ietf.org/html/rfc6749#section-4.2 @@ -64,15 +64,22 @@ func AddToContainer(c *restful.Container, im im.IdentityManagementInterface, tok Param(ws.QueryParameter("redirect_uri", "After completing its interaction with the resource owner, "+ "the authorization server directs the resource owner's user-agent back to the client.The redirection endpoint "+ "URI MUST be an absolute URI as defined by [RFC3986] Section 4.3.").Required(false)). - To(handler.Authorize)) + To(handler.Authorize). + Returns(http.StatusFound, http.StatusText(http.StatusFound), ""). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag})) // Resource Owner Password Credentials Grant // https://tools.ietf.org/html/rfc6749#section-4.3 ws.Route(ws.POST("/token"). Consumes("application/x-www-form-urlencoded"). - Doc("The resource owner password credentials grant type is suitable in\n" + - "cases where the resource owner has a trust relationship with the\n" + + Doc("The resource owner password credentials grant type is suitable in\n"+ + "cases where the resource owner has a trust relationship with the\n"+ "client, such as the device operating system or a highly privileged application."). - To(handler.Token)) + Param(ws.FormParameter("grant_type", "Value MUST be set to \"password\".").Required(true)). + Param(ws.FormParameter("username", "The resource owner username.").Required(true)). + Param(ws.FormParameter("password", "The resource owner password.").Required(true)). + To(handler.Token). + Returns(http.StatusOK, http.StatusText(http.StatusOK), &oauth.Token{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag})) // Authorization callback URL, where the end of the URL contains the identity provider name. // The provider name is also used to build the callback URL. @@ -92,7 +99,8 @@ func AddToContainer(c *restful.Container, im im.IdentityManagementInterface, tok Param(ws.QueryParameter("state", "if the \"state\" parameter was present in the client authorization request."+ "The exact value received from the client.").Required(true)). To(handler.oAuthCallBack). - Returns(http.StatusOK, api.StatusOK, oauth.Token{})) + Returns(http.StatusOK, api.StatusOK, oauth.Token{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag})) c.Add(ws) @@ -107,7 +115,7 @@ func AddToContainer(c *restful.Container, im im.IdentityManagementInterface, tok Doc("KubeSphere APIs support token-based authentication via the Authtoken request header. The POST Login API is used to retrieve the authentication token. After the authentication token is obtained, it must be inserted into the Authtoken header for all requests."). Reads(auth.LoginRequest{}). Returns(http.StatusOK, api.StatusOK, oauth.Token{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.IdentityManagementTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag})) c.Add(legacy) diff --git a/pkg/kapis/openpitrix/v1/handler.go b/pkg/kapis/openpitrix/v1/handler.go index 5e4bf1457..014c10f87 100644 --- a/pkg/kapis/openpitrix/v1/handler.go +++ b/pkg/kapis/openpitrix/v1/handler.go @@ -922,7 +922,7 @@ func handleOpenpitrixError(resp *restful.Response, err error) { api.HandleNotFound(resp, nil, err) return } - if status.Code(err) == codes.InvalidArgument { + if status.Code(err) == codes.InvalidArgument || status.Code(err) == codes.FailedPrecondition { klog.V(4).Infoln(err) api.HandleBadRequest(resp, nil, err) return diff --git a/pkg/kapis/openpitrix/v1/register.go b/pkg/kapis/openpitrix/v1/register.go index bc6728e46..55dc2b724 100644 --- a/pkg/kapis/openpitrix/v1/register.go +++ b/pkg/kapis/openpitrix/v1/register.go @@ -36,9 +36,6 @@ const ( var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} func AddToContainer(c *restful.Container, factory informers.InformerFactory, op op.Client) error { - if op == nil { - return nil - } mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson} webservice := runtime.NewWebService(GroupVersion) handler := newOpenpitrixHandler(factory, op) @@ -46,7 +43,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/applications"). To(handler.ListApplications). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Doc("List all applications"). Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a"). Required(false). @@ -60,7 +57,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/workspaces/{workspace}/namespaces/{namespace}/applications"). To(handler.ListApplications). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Doc("List all applications within the specified namespace"). Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a"). Required(false). @@ -75,7 +72,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/workspaces/{workspace}/namespaces/{namespace}/applications/{application}"). To(handler.DescribeApplication). Returns(http.StatusOK, api.StatusOK, openpitrix2.Application{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Doc("Describe the specified application of the namespace"). Param(webservice.PathParameter("namespace", "the name of the project").Required(true)). Param(webservice.PathParameter("application", "the id of the application").Required(true))) @@ -83,7 +80,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/workspaces/{workspace}/clusters/{cluster}/applications"). To(handler.ListApplications). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Doc("List all applications in special cluster"). Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a"). Required(false). @@ -98,7 +95,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/applications"). To(handler.ListApplications). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Doc("List all applications within the specified namespace"). Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a"). Required(false). @@ -114,7 +111,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/applications/{application}"). To(handler.DescribeApplication). Returns(http.StatusOK, api.StatusOK, openpitrix2.Application{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Doc("Describe the specified application of the namespace"). Param(webservice.PathParameter("cluster", "the name of the cluster.").Required(true)). Param(webservice.PathParameter("namespace", "the name of the project").Required(true)). @@ -123,7 +120,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.POST("/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/applications"). To(handler.CreateApplication). Doc("Deploy a new application"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Reads(openpitrix2.CreateClusterRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("cluster", "the name of the cluster.").Required(true)). @@ -133,7 +130,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Consumes(mimePatch...). To(handler.ModifyApplication). Doc("Modify application"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Reads(openpitrix2.ModifyClusterAttributesRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("cluster", "the name of the cluster.").Required(true)). @@ -143,7 +140,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.DELETE("/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/applications/{application}"). To(handler.DeleteApplication). Doc("Delete the specified application"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("cluster", "the name of the cluster.").Required(true)). Param(webservice.PathParameter("namespace", "the name of the project").Required(true)). @@ -153,7 +150,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Consumes(mimePatch...). To(handler.UpgradeApplication). Doc("Upgrade application"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppInstanceTag}). Reads(openpitrix2.UpgradeClusterRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("cluster", "the name of the cluster.").Required(true)). @@ -163,7 +160,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.POST("/apps/{app}/versions"). To(handler.CreateAppVersion). Doc("Create a new app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Reads(openpitrix2.CreateAppVersionRequest{}). Param(webservice.QueryParameter("validate", "Validate format of package(pack by op tool)")). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateAppVersionResponse{}). @@ -171,7 +168,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.POST("/workspaces/{workspace}/apps/{app}/versions"). To(handler.CreateAppVersion). Doc("Create a new app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Reads(openpitrix2.CreateAppVersionRequest{}). Param(webservice.QueryParameter("validate", "Validate format of package(pack by op tool)")). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateAppVersionResponse{}). @@ -179,14 +176,14 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.DELETE("/apps/{app}/versions/{version}"). To(handler.DeleteAppVersion). Doc("Delete the specified app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.DELETE("/workspaces/{workspace}/apps/{app}/versions/{version}"). To(handler.DeleteAppVersion). Doc("Delete the specified app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) @@ -194,7 +191,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Consumes(mimePatch...). To(handler.ModifyAppVersion). Doc("Patch the specified app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Reads(openpitrix2.ModifyAppVersionRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). @@ -203,7 +200,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Consumes(mimePatch...). To(handler.ModifyAppVersion). Doc("Patch the specified app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Reads(openpitrix2.ModifyAppVersionRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). @@ -211,7 +208,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op webservice.Route(webservice.GET("/apps/{app}/versions/{version}"). To(handler.DescribeAppVersion). Doc("Describe the specified app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersion{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) @@ -228,11 +225,12 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Param(webservice.PathParameter("app", "app template id")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.GET("/workspaces/{workspace}/apps/{app}/versions/{version}"). To(handler.DescribeAppVersion). Doc("Describe the specified app template version"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersion{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) @@ -249,16 +247,19 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Param(webservice.PathParameter("app", "app template id")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.GET("/workspaces/{workspace}/apps/{app}/versions/{version}/audits"). To(handler.ListAppVersionAudits). Doc("List audits information of version-specific app template"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersionAudit{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.GET("/apps/{app}/versions/{version}/audits"). To(handler.ListAppVersionAudits). Doc("List audits information of version-specific app template"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersionAudit{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) @@ -266,23 +267,27 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op To(handler.GetAppVersionPackage). Doc("Get packages of version-specific app"). Returns(http.StatusOK, api.StatusOK, openpitrix2.GetAppVersionPackageResponse{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.POST("/apps/{app}/versions/{version}/action"). To(handler.DoAppVersionAction). Doc("Perform submit or other operations on app"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.POST("/workspaces/{workspace}/apps/{app}/versions/{version}/action"). To(handler.DoAppVersionAction). Doc("Perform submit or other operations on app"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.GET("/apps/{app}/versions/{version}/files"). To(handler.GetAppVersionFiles). Doc("Get app template package files"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.GetAppVersionPackageFilesResponse{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) @@ -296,43 +301,45 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Required(false). DataFormat("limit=%d,page=%d"). DefaultValue("limit=10,page=1")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersionReview{})) webservice.Route(webservice.GET("/apps/{app}/audits"). To(handler.ListAppVersionAudits). Doc("List audits information of the specific app template"). Param(webservice.PathParameter("app", "app template id")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersionAudit{})) webservice.Route(webservice.POST("/apps"). To(handler.CreateApp). Doc("Create a new app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateAppResponse{}). Reads(openpitrix2.CreateAppRequest{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.POST("/workspaces/{workspace}/apps"). To(handler.CreateApp). Doc("Create a new app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateAppResponse{}). Reads(openpitrix2.CreateAppRequest{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.DELETE("/apps/{app}"). To(handler.DeleteApp). Doc("Delete the specified app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.DELETE("/workspaces/{workspace}/apps/{app}"). To(handler.DeleteApp). Doc("Delete the specified app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.PATCH("/apps/{app}"). Consumes(mimePatch...). To(handler.ModifyApp). Doc("Patch the specified app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Reads(openpitrix2.ModifyAppVersionRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("app", "app template id"))) @@ -340,31 +347,33 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Consumes(mimePatch...). To(handler.ModifyApp). Doc("Patch the specified app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Reads(openpitrix2.ModifyAppVersionRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.GET("/workspaces/{workspace}/apps/{app}"). To(handler.DescribeApp). Doc("Describe the specified app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersion{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.GET("/apps/{app}"). To(handler.DescribeApp). Doc("Describe the specified app template"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.AppVersion{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.POST("/apps/{app}/action"). To(handler.DoAppAction). Doc("Perform recover or suspend operation on app"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.POST("/workspaces/{workspace}/apps/{app}/action"). To(handler.DoAppAction). Doc("Perform recover or suspend operation on app"). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("version", "app template version id")). Param(webservice.PathParameter("app", "app template id"))) @@ -380,6 +389,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op DefaultValue("limit=10,page=1")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.GET("/workspaces/{workspace}/apps"). To(handler.ListApps). @@ -394,32 +404,33 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op DefaultValue("limit=10,page=1")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAppTemplateTag}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.POST("/categories"). To(handler.CreateCategory). Doc("Create app template category"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixCategoryTag}). Reads(openpitrix2.CreateCategoryRequest{}). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateCategoryResponse{}). Param(webservice.PathParameter("app", "app template id"))) webservice.Route(webservice.DELETE("/categories/{category}"). To(handler.DeleteCategory). Doc("Delete the specified category"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixCategoryTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("category", "category id"))) webservice.Route(webservice.PATCH("/categories/{category}"). Consumes(mimePatch...). To(handler.ModifyCategory). Doc("Patch the specified category"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixCategoryTag}). Reads(openpitrix2.ModifyCategoryRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("category", "category id"))) webservice.Route(webservice.GET("/categories/{category}"). To(handler.DescribeCategory). Doc("Describe the specified category"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixCategoryTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.Category{}). Param(webservice.PathParameter("category", "category id"))) webservice.Route(webservice.GET("/categories"). @@ -434,45 +445,47 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op DefaultValue("limit=10,page=1")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixCategoryTag}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.GET("/attachments/{attachment}"). To(handler.DescribeAttachment). Doc("Get attachment by attachment id"). Param(webservice.PathParameter("attachment", "attachment id")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixAttachmentTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.Attachment{})) webservice.Route(webservice.POST("/repos"). To(handler.CreateRepo). Doc("Create repository in the specified workspace, repository used to store package of app"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Param(webservice.QueryParameter("validate", "Validate repository")). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateRepoResponse{}). Reads(openpitrix2.CreateRepoRequest{})) webservice.Route(webservice.POST("/workspaces/{workspace}/repos"). To(handler.CreateRepo). Doc("Create repository in the specified workspace, repository used to store package of app"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Param(webservice.QueryParameter("validate", "Validate repository")). Returns(http.StatusOK, api.StatusOK, openpitrix2.CreateRepoResponse{}). Reads(openpitrix2.CreateRepoRequest{})) webservice.Route(webservice.DELETE("/repos/{repo}"). To(handler.DeleteRepo). Doc("Delete the specified repository in the specified workspace"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.DELETE("/workspaces/{workspace}/repos/{repo}"). To(handler.DeleteRepo). Doc("Delete the specified repository in the specified workspace"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.PATCH("/repos/{repo}"). Consumes(mimePatch...). To(handler.ModifyRepo). Doc("Patch the specified repository in the specified workspace"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Reads(openpitrix2.ModifyRepoRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("repo", "repo id"))) @@ -480,20 +493,20 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Consumes(mimePatch...). To(handler.ModifyRepo). Doc("Patch the specified repository in the specified workspace"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Reads(openpitrix2.ModifyRepoRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.GET("/repos/{repo}"). To(handler.DescribeRepo). Doc("Describe the specified repository in the specified workspace"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.Repo{}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.GET("/workspaces/{workspace}/repos/{repo}"). To(handler.DescribeRepo). Doc("Describe the specified repository in the specified workspace"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Returns(http.StatusOK, api.StatusOK, openpitrix2.Repo{}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.GET("/repos"). @@ -507,6 +520,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op DataFormat("limit=%d,page=%d"). DefaultValue("limit=10,page=1")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.GET("/workspaces/{workspace}/repos"). @@ -521,6 +535,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op DefaultValue("limit=10,page=1")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{})) webservice.Route(webservice.POST("/repos/{repo}/action"). @@ -528,22 +543,26 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, op Doc("Start index repository event"). Reads(openpitrix2.RepoActionRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.POST("/workspaces/{workspace}/repos/{repo}/action"). To(handler.DoRepoAction). Doc("Start index repository event"). Reads(openpitrix2.RepoActionRequest{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixManagementTag}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.GET("/repos/{repo}/events"). To(handler.ListRepoEvents). Doc("Get repository events"). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Param(webservice.PathParameter("repo", "repo id"))) webservice.Route(webservice.GET("/workspaces/{workspace}/repos/{repo}/events"). To(handler.ListRepoEvents). Doc("Get repository events"). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.OpenpitrixRepositoryTag}). Param(webservice.PathParameter("repo", "repo id"))) c.Add(webservice) diff --git a/pkg/kapis/resources/v1alpha2/register.go b/pkg/kapis/resources/v1alpha2/register.go index fda31a218..a1d28d77a 100644 --- a/pkg/kapis/resources/v1alpha2/register.go +++ b/pkg/kapis/resources/v1alpha2/register.go @@ -86,7 +86,7 @@ func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, factor To(handler.GetKubectlPod). Doc("get user's kubectl pod"). Param(webservice.PathParameter("user", "username")). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourcesTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ToolboxTag}). Returns(http.StatusOK, api.StatusOK, models.PodInfo{})) webservice.Route(webservice.GET("/users/{user}/kubeconfig"). @@ -95,7 +95,7 @@ func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, factor Doc("get users' kubeconfig"). Param(webservice.PathParameter("user", "username")). Returns(http.StatusOK, api.StatusOK, ""). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.ToolboxTag})) webservice.Route(webservice.GET("/components"). To(handler.handleGetComponents). @@ -130,7 +130,7 @@ func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, factor webservice.Route(webservice.POST("registry/verify"). To(handler.handleVerifyRegistryCredential). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.VerificationTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.RegistryTag}). Doc("verify if a user has access to the docker registry"). Reads(api.RegistryCredential{}). Returns(http.StatusOK, api.StatusOK, errors.Error{})) @@ -152,7 +152,7 @@ func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, factor ) webservice.Route(webservice.POST("git/verify"). To(handler.handleVerifyGitCredential). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.VerificationTag}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GitTag}). Doc("Verify if the kubernetes secret has read access to the git repository"). Reads(gitmodel.AuthInfo{}). Returns(http.StatusOK, api.StatusOK, errors.Error{}), diff --git a/pkg/kapis/tenant/v1alpha2/register.go b/pkg/kapis/tenant/v1alpha2/register.go index acb77cec6..4c28a42d9 100644 --- a/pkg/kapis/tenant/v1alpha2/register.go +++ b/pkg/kapis/tenant/v1alpha2/register.go @@ -59,21 +59,21 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s To(handler.ListClusters). Doc("List clusters available to users"). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourceTag})) ws.Route(ws.POST("/workspaces"). To(handler.CreateWorkspace). Reads(tenantv1alpha2.WorkspaceTemplate{}). Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}). Doc("Create workspace."). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.DELETE("/workspaces/{workspace}"). To(handler.DeleteWorkspace). Param(ws.PathParameter("workspace", "workspace name")). Returns(http.StatusOK, api.StatusOK, errors.None). Doc("Delete workspace."). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.PUT("/workspaces/{workspace}"). To(handler.UpdateWorkspace). @@ -81,7 +81,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Reads(tenantv1alpha2.WorkspaceTemplate{}). Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}). Doc("Update workspace."). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.PATCH("/workspaces/{workspace}"). To(handler.PatchWorkspace). @@ -90,60 +90,60 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Reads(tenantv1alpha2.WorkspaceTemplate{}). Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}). Doc("Update workspace."). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.GET("/workspaces"). To(handler.ListWorkspaces). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). Doc("List all workspaces that belongs to the current user"). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.GET("/workspaces/{workspace}"). To(handler.DescribeWorkspace). Param(ws.PathParameter("workspace", "workspace name")). Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}). Doc("Describe workspace."). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.GET("/workspaces/{workspace}/clusters"). To(handler.ListWorkspaceClusters). Param(ws.PathParameter("workspace", "workspace name")). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Doc("List clusters authorized to the specified workspace."). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag})) ws.Route(ws.GET("/namespaces"). To(handler.ListNamespaces). Doc("List the namespaces for the current user"). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.GET("/federatednamespaces"). To(handler.ListFederatedNamespaces). Doc("List the federated namespaces for the current user"). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.GET("/workspaces/{workspace}/federatednamespaces"). To(handler.ListFederatedNamespaces). Param(ws.PathParameter("workspace", "workspace name")). Doc("List the federated namespaces of the specified workspace for the current user"). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.GET("/workspaces/{workspace}/namespaces"). To(handler.ListNamespaces). Param(ws.PathParameter("workspace", "workspace name")). Doc("List the namespaces of the specified workspace for the current user"). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.GET("/workspaces/{workspace}/devops"). To(handler.ListDevOpsProjects). Param(ws.PathParameter("workspace", "workspace name")). Doc("List the devops projects of the specified workspace for the current user"). Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers/{workspacemember}/devops"). To(handler.ListDevOpsProjects). @@ -152,7 +152,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Doc("List the devops projects of specified workspace for the workspace member"). Reads(corev1.Namespace{}). Returns(http.StatusOK, api.StatusOK, corev1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag})) ws.Route(ws.GET("/workspaces/{workspace}/namespaces/{namespace}"). To(handler.DescribeNamespace). @@ -160,7 +160,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Param(ws.PathParameter("namespace", "project name")). Doc("Retrieve namespace details."). Returns(http.StatusOK, api.StatusOK, corev1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.DELETE("/workspaces/{workspace}/namespaces/{namespace}"). To(handler.DeleteNamespace). @@ -168,7 +168,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Param(ws.PathParameter("namespace", "project name")). Doc("Delete namespace."). Returns(http.StatusOK, api.StatusOK, errors.None). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.POST("/workspaces/{workspace}/namespaces"). To(handler.CreateNamespace). @@ -176,7 +176,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Doc("List the namespaces of the specified workspace for the current user"). Reads(corev1.Namespace{}). Returns(http.StatusOK, api.StatusOK, corev1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers/{workspacemember}/namespaces"). To(handler.ListNamespaces). @@ -185,7 +185,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Doc("List the namespaces of the specified workspace for the workspace member"). Reads(corev1.Namespace{}). Returns(http.StatusOK, api.StatusOK, corev1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.PUT("/workspaces/{workspace}/namespaces/{namespace}"). To(handler.UpdateNamespace). @@ -193,7 +193,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Param(ws.PathParameter("namespace", "project name")). Reads(corev1.Namespace{}). Returns(http.StatusOK, api.StatusOK, corev1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.PATCH("/workspaces/{workspace}/namespaces/{namespace}"). To(handler.PatchNamespace). @@ -202,7 +202,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s Param(ws.PathParameter("namespace", "project name")). Reads(corev1.Namespace{}). Returns(http.StatusOK, api.StatusOK, corev1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) + Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceTag})) ws.Route(ws.GET("/events"). To(handler.Events). diff --git a/pkg/models/devops/devops.go b/pkg/models/devops/devops.go index 0dd59097c..804e80682 100644 --- a/pkg/models/devops/devops.go +++ b/pkg/models/devops/devops.go @@ -299,6 +299,7 @@ func (d devopsOperator) DeleteCredentialObj(projectName string, secret string) e func (d devopsOperator) UpdateCredentialObj(projectName string, secret *v1.Secret) (*v1.Secret, error) { projectObj, err := d.ksInformers.Devops().V1alpha3().DevOpsProjects().Lister().Get(projectName) + secret.Annotations[devopsv1alpha3.CredentialAutoSyncAnnoKey] = "true" if err != nil { return nil, err } diff --git a/pkg/models/resources/v1alpha2/storageclass/storageclasses.go b/pkg/models/resources/v1alpha2/storageclass/storageclasses.go index fa651e1e4..9c04aa1b3 100644 --- a/pkg/models/resources/v1alpha2/storageclass/storageclasses.go +++ b/pkg/models/resources/v1alpha2/storageclass/storageclasses.go @@ -107,7 +107,7 @@ func (s *storageClassesSearcher) countPersistentVolumeClaims(name string) int { var count int for _, pvc := range pvcs { - if *pvc.Spec.StorageClassName == name || (pvc.Annotations != nil && pvc.Annotations[corev1.BetaStorageClassAnnotation] == name) { + if (pvc.Spec.StorageClassName != nil && *pvc.Spec.StorageClassName == name) || (pvc.Annotations != nil && pvc.Annotations[corev1.BetaStorageClassAnnotation] == name) { count++ } } diff --git a/pkg/models/resources/v1alpha2/storageclass/storageclasses_test.go b/pkg/models/resources/v1alpha2/storageclass/storageclasses_test.go new file mode 100644 index 000000000..5224dc50a --- /dev/null +++ b/pkg/models/resources/v1alpha2/storageclass/storageclasses_test.go @@ -0,0 +1,109 @@ +package storageclass + +import ( + "github.com/google/go-cmp/cmp" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/utils/pointer" + "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2" + "kubesphere.io/kubesphere/pkg/server/params" + "testing" +) + +var ( + sc1 = &v1.StorageClass{ + ObjectMeta: metav1.ObjectMeta{ + Name: "sc1", + }, + } + + scs = []interface{}{sc1} + + pvc1 = &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc1", + Namespace: "default", + }, + Spec: corev1.PersistentVolumeClaimSpec{ + VolumeName: "pvc1-volume", + StorageClassName: pointer.StringPtr("sc1"), + }, + } + + pvc2 = &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc2", + Namespace: "default", + }, + Spec: corev1.PersistentVolumeClaimSpec{ + VolumeName: "pvc2-volume", + }, + } + + pvcs = []interface{}{pvc1, pvc2} +) + +func prepare() (v1alpha2.Interface, error) { + client := fake.NewSimpleClientset() + informer := informers.NewSharedInformerFactory(client, 0) + + for _, sc := range scs { + err := informer.Storage().V1().StorageClasses().Informer().GetIndexer().Add(sc) + if err != nil { + return nil, err + } + } + + for _, pvc := range pvcs { + err := informer.Core().V1().PersistentVolumeClaims().Informer().GetIndexer().Add(pvc) + if err != nil { + return nil, err + } + } + + return NewStorageClassesSearcher(informer, nil), nil +} + +func TestSearch(t *testing.T) { + tests := []struct { + namespace string + name string + conditions *params.Conditions + orderBy string + reverse bool + expected interface{} + expectedErr error + }{ + { + namespace: "default", + name: sc1.Name, + conditions: ¶ms.Conditions{}, + orderBy: "name", + reverse: true, + expected: scs, + expectedErr: nil, + }, + } + + searcher, err := prepare() + if err != nil { + t.Fatal(err) + } + + for _, test := range tests { + got, err := searcher.Search(test.namespace, test.conditions, test.orderBy, test.reverse) + if test.expectedErr != nil && err != test.expectedErr { + t.Errorf("expected error, got nothing") + } else if err != nil { + t.Fatal(err) + } + + if diff := cmp.Diff(got, test.expected); diff != "" { + t.Errorf("%T differ (-got, +want): %s", test.expected, diff) + } + } + +} diff --git a/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot.go b/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot.go index 41088004d..916c8edab 100644 --- a/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot.go +++ b/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot.go @@ -28,6 +28,7 @@ import ( const ( statusCreating = "creating" statusReady = "ready" + statusDeleting = "deleting" volumeSnapshotClassName = "volumeSnapshotClassName" persistentVolumeClaimName = "persistentVolumeClaimName" @@ -96,5 +97,8 @@ func snapshotStatus(item *v1beta1.VolumeSnapshot) string { if item != nil && item.Status != nil && item.Status.ReadyToUse != nil && *item.Status.ReadyToUse { status = statusReady } + if item != nil && item.DeletionTimestamp != nil { + status = statusDeleting + } return status } diff --git a/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot_test.go b/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot_test.go index bbf514f2e..cd6a5d887 100644 --- a/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot_test.go +++ b/pkg/models/resources/v1alpha3/volumesnapshot/volumesnapshot_test.go @@ -208,13 +208,17 @@ func TestListVolumeSnapshot(t *testing.T) { } Expect(snapshotStatus(snapshot)).To(Equal(statusReady)) }) + + It("snapshot.DeletionTimestamp != nil", func() { + deleteTime := v1.Now() + snapshot.DeletionTimestamp = &deleteTime + defer func() { + snapshot.DeletionTimestamp = nil + }() + Expect(snapshotStatus(snapshot)).To(Equal(statusDeleting)) + }) + }) RunSpecs(t, "volume snapshot getter list") } - -//func TestVolumeSnapshotStatus( t *testing.T) { -// RegisterFailHandler(Fail) -// -// RunSpecs(t, "volume snapshot status") -//} diff --git a/tools/cmd/doc-gen/main.go b/tools/cmd/doc-gen/main.go index 19b785b75..01f595c8a 100644 --- a/tools/cmd/doc-gen/main.go +++ b/tools/cmd/doc-gen/main.go @@ -35,11 +35,13 @@ import ( "kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/informers" + clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1" devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2" devopsv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha3" iamv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2" monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2" + "kubesphere.io/kubesphere/pkg/kapis/oauth" openpitrixv1 "kubesphere.io/kubesphere/pkg/kapis/openpitrix/v1" operationsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/operations/v1alpha2" resourcesv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/resources/v1alpha2" @@ -49,8 +51,9 @@ import ( terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2" "kubesphere.io/kubesphere/pkg/models/iam/am" "kubesphere.io/kubesphere/pkg/models/iam/im" - "kubesphere.io/kubesphere/pkg/simple/client/devops/fake" + fakedevops "kubesphere.io/kubesphere/pkg/simple/client/devops/fake" "kubesphere.io/kubesphere/pkg/simple/client/k8s" + "kubesphere.io/kubesphere/pkg/simple/client/openpitrix" fakes3 "kubesphere.io/kubesphere/pkg/simple/client/s3/fake" "kubesphere.io/kubesphere/pkg/version" "log" @@ -111,11 +114,14 @@ func generateSwaggerJson() []byte { informerFactory := informers.NewNullInformerFactory() - urlruntime.Must(devopsv1alpha2.AddToContainer(container, informerFactory.KubeSphereSharedInformerFactory(), &fake.Devops{}, nil, clientsets.KubeSphere(), fakes3.NewFakeS3(), "")) - urlruntime.Must(devopsv1alpha3.AddToContainer(container, &fake.Devops{}, clientsets.Kubernetes(), clientsets.KubeSphere(), informerFactory.KubeSphereSharedInformerFactory(), informerFactory.KubernetesSharedInformerFactory())) + urlruntime.Must(oauth.AddToContainer(container, nil, nil, nil, nil, nil)) + urlruntime.Must(clusterkapisv1alpha1.AddToContainer(container, informerFactory.KubernetesSharedInformerFactory(), + informerFactory.KubeSphereSharedInformerFactory(), "", "", "")) + urlruntime.Must(devopsv1alpha2.AddToContainer(container, informerFactory.KubeSphereSharedInformerFactory(), &fakedevops.Devops{}, nil, clientsets.KubeSphere(), fakes3.NewFakeS3(), "")) + urlruntime.Must(devopsv1alpha3.AddToContainer(container, &fakedevops.Devops{}, clientsets.Kubernetes(), clientsets.KubeSphere(), informerFactory.KubeSphereSharedInformerFactory(), informerFactory.KubernetesSharedInformerFactory())) urlruntime.Must(iamv1alpha2.AddToContainer(container, im.NewOperator(clientsets.KubeSphere(), informerFactory, nil), am.NewReadOnlyOperator(informerFactory), authoptions.NewAuthenticateOptions())) urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, informerFactory, nil)) - urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, nil)) + urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, openpitrix.NewMockClient(nil))) urlruntime.Must(operationsv1alpha2.AddToContainer(container, clientsets.Kubernetes())) urlruntime.Must(resourcesv1alpha2.AddToContainer(container, clientsets.Kubernetes(), informerFactory, "")) urlruntime.Must(resourcesv1alpha3.AddToContainer(container, informerFactory)) @@ -129,47 +135,119 @@ func generateSwaggerJson() []byte { PostBuildSwaggerObjectHandler: enrichSwaggerObject} swagger := restfulspec.BuildSwagger(config) - swagger.Info.Extensions = make(spec.Extensions) swagger.Info.Extensions.Add("x-tagGroups", []struct { Name string `json:"name"` Tags []string `json:"tags"` }{ { - Name: "IAM", - Tags: []string{constants.IdentityManagementTag, constants.AccessManagementTag}, + Name: "Authentication", + Tags: []string{constants.AuthenticationTag}, + }, + { + Name: "Identity Management", + Tags: []string{ + constants.UserTag, + }, + }, + { + Name: "Access Management", + Tags: []string{ + constants.ClusterMemberTag, + constants.WorkspaceMemberTag, + constants.DevOpsProjectMemberTag, + constants.NamespaceMemberTag, + constants.GlobalRoleTag, + constants.ClusterRoleTag, + constants.WorkspaceRoleTag, + constants.DevOpsProjectRoleTag, + constants.NamespaceRoleTag, + }, + }, + { + Name: "Multi-tenancy", + Tags: []string{ + constants.WorkspaceTag, + constants.NamespaceTag, + constants.UserResourceTag, + }, + }, + { + Name: "Multi-cluster", + Tags: []string{ + constants.MultiClusterTag, + }, }, { Name: "Resources", - Tags: []string{constants.ClusterResourcesTag, constants.NamespaceResourcesTag, constants.UserResourcesTag}, + Tags: []string{ + constants.ClusterResourcesTag, + constants.NamespaceResourcesTag, + }, }, { - Name: "Monitoring", - Tags: []string{constants.ComponentStatusTag}, - }, - { - Name: "Tenant", - Tags: []string{constants.TenantResourcesTag}, + Name: "App Store", + Tags: []string{ + constants.OpenpitrixAppInstanceTag, + constants.OpenpitrixAppTemplateTag, + constants.OpenpitrixCategoryTag, + constants.OpenpitrixAttachmentTag, + constants.OpenpitrixRepositoryTag, + constants.OpenpitrixManagementTag, + }, }, { Name: "Other", - Tags: []string{constants.VerificationTag, constants.RegistryTag}, + Tags: []string{ + constants.RegistryTag, + constants.GitTag, + constants.ToolboxTag, + constants.TerminalTag, + }, }, { Name: "DevOps", - Tags: []string{constants.DevOpsProjectTag, constants.DevOpsProjectCredentialTag, - constants.DevOpsPipelineTag, constants.DevOpsProjectMemberTag, - constants.DevOpsWebhookTag, constants.DevOpsJenkinsfileTag, constants.DevOpsScmTag}, + Tags: []string{ + constants.DevOpsProjectTag, + constants.DevOpsCredentialTag, + constants.DevOpsPipelineTag, + constants.DevOpsProjectMemberTag, + constants.DevOpsWebhookTag, + constants.DevOpsJenkinsfileTag, + constants.DevOpsScmTag, + constants.DevOpsJenkinsTag, + }, }, { Name: "Monitoring", - Tags: []string{constants.ClusterMetricsTag, constants.NodeMetricsTag, constants.NamespaceMetricsTag, constants.WorkloadMetricsTag, - constants.PodMetricsTag, constants.ContainerMetricsTag, constants.WorkspaceMetricsTag, constants.ComponentMetricsTag}, + Tags: []string{ + constants.ClusterMetricsTag, + constants.NodeMetricsTag, + constants.NamespaceMetricsTag, + constants.WorkloadMetricsTag, + constants.PodMetricsTag, + constants.ContainerMetricsTag, + constants.WorkspaceMetricsTag, + constants.ComponentMetricsTag, + constants.ComponentStatusTag, + }, }, { Name: "Logging", Tags: []string{constants.LogQueryTag}, }, + { + Name: "Events", + Tags: []string{constants.EventsQueryTag}, + }, + { + Name: "Auditing", + Tags: []string{constants.AuditingQueryTag}, + }, + { + Name: "Network", + Tags: []string{constants.NetworkTopologyTag}, + }, }) data, _ := json.MarshalIndent(swagger, "", " ") diff --git a/vendor/github.com/emicklei/go-restful-openapi/CHANGES.md b/vendor/github.com/emicklei/go-restful-openapi/CHANGES.md index c6e5d7b27..7bd1eb805 100644 --- a/vendor/github.com/emicklei/go-restful-openapi/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful-openapi/CHANGES.md @@ -1,10 +1,38 @@ # changes to the go-restful-openapi package -## v1.0.0 +# v2+ versions are using the Go module of go-restful v3+ -- Fix for #19 MapModelTypeNameFunc has incomplete behavior -- prevent array param.Type be overwritten in the else case below (#47) -- Merge paths with existing paths from other webServices (#48) +## v1.4.0 + v2.2.0 + - Allow maps as top level types and support maps to slices (#63) + +## v1.3.0 + v2.1.0 + - add json.Number handling (PR #61) + - add type alias support for primitives (PR #61) + +## v1.2.0 + + - handle map[string][]byte (#59) + +## v1.1.0 (v0.14.1) + + - Add Host field to Config which is copied into Swagger object + - Enable CORS by default as per the documentation (#58) + - add go module + - update dependencies + +## v0.13.0 + + - Do not use 200 as default response, instead use the one explicitly defined. + - support time.Duration + - Fix Parameter 'AllowableValues' to populate swagger definition + +## v0.12.0 + + - add support for time.Duration + - Populate the swagger definition with the parameter's 'AllowableValues' as an enum (#53) + - Fix for #19 MapModelTypeNameFunc has incomplete behavior + - Merge paths with existing paths from other webServices (#48) + - prevent array param.Type be overwritten in the else case below (#47) ## v0.11.0 diff --git a/vendor/github.com/emicklei/go-restful-openapi/README.md b/vendor/github.com/emicklei/go-restful-openapi/README.md index cc1283c44..a5a081e17 100644 --- a/vendor/github.com/emicklei/go-restful-openapi/README.md +++ b/vendor/github.com/emicklei/go-restful-openapi/README.md @@ -23,4 +23,16 @@ See TestThatExtraTagsAreReadIntoModel for examples. - [go-restful](https://github.com/emicklei/go-restful) - [go-openapi](https://github.com/go-openapi/spec) -© 2018, ernestmicklei.com. MIT License. Contributions welcome. + +## Go modules + +Versions `v1` of this package require Go module version `v2` of the go-restful package. +To use version `v3` of the go-restful package, you need to import `v2 of this package, such as: + + import ( + restfulspec "github.com/emicklei/go-restful-openapi/v2" + restful "github.com/emicklei/go-restful/v3" + ) + + +© 2017-2020, ernestmicklei.com. MIT License. Contributions welcome. diff --git a/vendor/github.com/emicklei/go-restful-openapi/build_path.go b/vendor/github.com/emicklei/go-restful-openapi/build_path.go index 634e4b75d..12b2432f8 100644 --- a/vendor/github.com/emicklei/go-restful-openapi/build_path.go +++ b/vendor/github.com/emicklei/go-restful-openapi/build_path.go @@ -100,9 +100,10 @@ func buildOperation(ws *restful.WebService, r restful.Route, patterns map[string for k, v := range r.ResponseErrors { r := buildResponse(v, cfg) props.StatusCodeResponses[k] = r - if 200 == k { // any 2xx code? - o.Responses.Default = &r - } + } + if r.DefaultResponse != nil { + r := buildResponse(*r.DefaultResponse, cfg) + o.Responses.Default = &r } if len(o.Responses.StatusCodeResponses) == 0 { o.Responses.StatusCodeResponses[200] = spec.Response{ResponseProps: spec.ResponseProps{Description: http.StatusText(http.StatusOK)}} @@ -133,6 +134,13 @@ func buildParameter(r restful.Route, restfulParam *restful.Parameter, pattern st p.Name = param.Name p.Required = param.Required + if len(param.AllowableValues) > 0 { + p.Enum = make([]interface{}, 0, len(param.AllowableValues)) + for key := range param.AllowableValues { + p.Enum = append(p.Enum, key) + } + } + if param.Kind == restful.PathParameterKind { p.Pattern = pattern } @@ -223,7 +231,7 @@ func isPrimitiveType(modelName string) bool { if len(modelName) == 0 { return false } - return strings.Contains("uint uint8 uint16 uint32 uint64 int int8 int16 int32 int64 float32 float64 bool string byte rune time.Time", modelName) + return strings.Contains("uint uint8 uint16 uint32 uint64 int int8 int16 int32 int64 float32 float64 bool string byte rune time.Time time.Duration", modelName) } func jsonSchemaType(modelName string) string { @@ -245,6 +253,7 @@ func jsonSchemaType(modelName string) string { "float32": "number", "bool": "boolean", "time.Time": "string", + "time.Duration": "integer", } mapped, ok := schemaMap[modelName] if !ok { diff --git a/vendor/github.com/emicklei/go-restful-openapi/config.go b/vendor/github.com/emicklei/go-restful-openapi/config.go index a3fa96f8c..354a7c960 100644 --- a/vendor/github.com/emicklei/go-restful-openapi/config.go +++ b/vendor/github.com/emicklei/go-restful-openapi/config.go @@ -22,6 +22,8 @@ type PostBuildSwaggerObjectFunc func(s *spec.Swagger) // Config holds service api metadata. type Config struct { + // [optional] If set then set this field with the generated Swagger Object + Host string // WebServicesURL is a DEPRECATED field; it never had any effect in this package. WebServicesURL string // APIPath is the path where the JSON api is avaiable , e.g. /apidocs.json diff --git a/vendor/github.com/emicklei/go-restful-openapi/definition_builder.go b/vendor/github.com/emicklei/go-restful-openapi/definition_builder.go index c89c51b7d..48ff7e505 100644 --- a/vendor/github.com/emicklei/go-restful-openapi/definition_builder.go +++ b/vendor/github.com/emicklei/go-restful-openapi/definition_builder.go @@ -39,21 +39,23 @@ func (b definitionBuilder) addModel(st reflect.Type, nameOverride string) *spec. if st.Kind() == reflect.Ptr { st = st.Elem() } + if b.isSliceOrArrayType(st.Kind()) { + st = st.Elem() + } modelName := keyFrom(st, b.Config) if nameOverride != "" { modelName = nameOverride } // no models needed for primitive types - if b.isPrimitiveType(modelName) { + if b.isPrimitiveType(modelName, st.Kind()) { return nil } // golang encoding/json packages says array and slice values encode as // JSON arrays, except that []byte encodes as a base64-encoded string. // If we see a []byte here, treat it at as a primitive type (string) // and deal with it in buildArrayTypeProperty. - if (st.Kind() == reflect.Slice || st.Kind() == reflect.Array) && - st.Elem().Kind() == reflect.Uint8 { + if b.isByteArrayType(st) { return nil } // see if we already have visited this model @@ -70,9 +72,10 @@ func (b definitionBuilder) addModel(st reflect.Type, nameOverride string) *spec. // reference the model before further initializing (enables recursive structs) b.Definitions[modelName] = sm - // check for slice or array - if st.Kind() == reflect.Slice || st.Kind() == reflect.Array { - st = st.Elem() + if st.Kind() == reflect.Map { + _, sm = b.buildMapType(st, "value", modelName) + b.Definitions[modelName] = sm + return &sm } // check for structure or primitive type if st.Kind() != reflect.Struct { @@ -165,7 +168,7 @@ func (b definitionBuilder) buildProperty(field reflect.StructField, model *spec. prop.Type = []string{pType} } if prop.Format == "" { - prop.Format = b.jsonSchemaFormat(keyFrom(fieldType, b.Config)) + prop.Format = b.jsonSchemaFormat(keyFrom(fieldType, b.Config), fieldType.Kind()) } return jsonName, modelDescription, prop } @@ -185,26 +188,22 @@ func (b definitionBuilder) buildProperty(field reflect.StructField, model *spec. case fieldKind == reflect.Struct: jsonName, prop := b.buildStructTypeProperty(field, jsonName, model) return jsonName, modelDescription, prop - case fieldKind == reflect.Slice || fieldKind == reflect.Array: + case b.isSliceOrArrayType(fieldKind): jsonName, prop := b.buildArrayTypeProperty(field, jsonName, modelName) return jsonName, modelDescription, prop case fieldKind == reflect.Ptr: jsonName, prop := b.buildPointerTypeProperty(field, jsonName, modelName) return jsonName, modelDescription, prop - case fieldKind == reflect.String: - stringt := "string" - prop.Type = []string{stringt} - return jsonName, modelDescription, prop case fieldKind == reflect.Map: jsonName, prop := b.buildMapTypeProperty(field, jsonName, modelName) return jsonName, modelDescription, prop } fieldTypeName := keyFrom(fieldType, b.Config) - if b.isPrimitiveType(fieldTypeName) { - mapped := b.jsonSchemaType(fieldTypeName) + if b.isPrimitiveType(fieldTypeName, fieldKind) { + mapped := b.jsonSchemaType(fieldTypeName, fieldKind) prop.Type = []string{mapped} - prop.Format = b.jsonSchemaFormat(fieldTypeName) + prop.Format = b.jsonSchemaFormat(fieldTypeName, fieldKind) return jsonName, modelDescription, prop } modelType := keyFrom(fieldType, b.Config) @@ -294,13 +293,13 @@ func (b definitionBuilder) buildArrayTypeProperty(field reflect.StructField, jso } var pType = "array" prop.Type = []string{pType} - isPrimitive := b.isPrimitiveType(fieldType.Elem().Name()) + isPrimitive := b.isPrimitiveType(fieldType.Elem().Name(), fieldType.Elem().Kind()) elemTypeName := b.getElementTypeName(modelName, jsonName, fieldType.Elem()) prop.Items = &spec.SchemaOrArray{ Schema: &spec.Schema{}, } if isPrimitive { - mapped := b.jsonSchemaType(elemTypeName) + mapped := b.jsonSchemaType(elemTypeName, fieldType.Elem().Kind()) prop.Items.Schema.Type = []string{mapped} } else { prop.Items.Schema.Ref = spec.MustCreateRef("#/definitions/" + elemTypeName) @@ -316,37 +315,62 @@ func (b definitionBuilder) buildArrayTypeProperty(field reflect.StructField, jso } func (b definitionBuilder) buildMapTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop spec.Schema) { + nameJson, prop = b.buildMapType(field.Type, jsonName, modelName) setPropertyMetadata(&prop, field) - fieldType := field.Type + return nameJson, prop +} + +func (b definitionBuilder) buildMapType(mapType reflect.Type, jsonName, modelName string) (nameJson string, prop spec.Schema) { var pType = "object" prop.Type = []string{pType} // As long as the element isn't an interface, we should be able to figure out what the // intended type is and represent it in `AdditionalProperties`. // See: https://swagger.io/docs/specification/data-models/dictionaries/ - if fieldType.Elem().Kind().String() != "interface" { - isPrimitive := b.isPrimitiveType(fieldType.Elem().Name()) - elemTypeName := b.getElementTypeName(modelName, jsonName, fieldType.Elem()) + if mapType.Elem().Kind().String() != "interface" { + isSlice := b.isSliceOrArrayType(mapType.Elem().Kind()) + if isSlice && !b.isByteArrayType(mapType.Elem()) { + mapType = mapType.Elem() + } + isPrimitive := b.isPrimitiveType(mapType.Elem().Name(), mapType.Elem().Kind()) + elemTypeName := b.getElementTypeName(modelName, jsonName, mapType.Elem()) prop.AdditionalProperties = &spec.SchemaOrBool{ Schema: &spec.Schema{}, } - if isPrimitive { - mapped := b.jsonSchemaType(elemTypeName) - prop.AdditionalProperties.Schema.Type = []string{mapped} + // golang encoding/json packages says array and slice values encode as + // JSON arrays, except that []byte encodes as a base64-encoded string. + // If we see a []byte here, treat it at as a string + if b.isByteArrayType(mapType.Elem()) { + prop.AdditionalProperties.Schema.Type = []string{"string"} } else { - prop.AdditionalProperties.Schema.Ref = spec.MustCreateRef("#/definitions/" + elemTypeName) - } - // add|overwrite model for element type - if fieldType.Elem().Kind() == reflect.Ptr { - fieldType = fieldType.Elem() - } - if !isPrimitive { - b.addModel(fieldType.Elem(), elemTypeName) + if isSlice { + var item *spec.Schema + if isPrimitive { + mapped := b.jsonSchemaType(elemTypeName, mapType.Kind()) + item = &spec.Schema{} + item.Type = []string{mapped} + item.Format = b.jsonSchemaFormat(elemTypeName, mapType.Kind()) + } else { + item = spec.RefProperty("#/definitions/" + elemTypeName) + } + prop.AdditionalProperties.Schema = spec.ArrayProperty(item) + } else if isPrimitive { + mapped := b.jsonSchemaType(elemTypeName, mapType.Elem().Kind()) + prop.AdditionalProperties.Schema.Type = []string{mapped} + } else { + prop.AdditionalProperties.Schema.Ref = spec.MustCreateRef("#/definitions/" + elemTypeName) + } + // add|overwrite model for element type + if mapType.Elem().Kind() == reflect.Ptr { + mapType = mapType.Elem() + } + if !isPrimitive { + b.addModel(mapType.Elem(), elemTypeName) + } } } return jsonName, prop } - func (b definitionBuilder) buildPointerTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop spec.Schema) { setPropertyMetadata(&prop, field) fieldType := field.Type @@ -355,13 +379,13 @@ func (b definitionBuilder) buildPointerTypeProperty(field reflect.StructField, j if fieldType.Elem().Kind() == reflect.Slice || fieldType.Elem().Kind() == reflect.Array { var pType = "array" prop.Type = []string{pType} - isPrimitive := b.isPrimitiveType(fieldType.Elem().Elem().Name()) + isPrimitive := b.isPrimitiveType(fieldType.Elem().Elem().Name(), fieldType.Elem().Elem().Kind()) elemName := b.getElementTypeName(modelName, jsonName, fieldType.Elem().Elem()) prop.Items = &spec.SchemaOrArray{ Schema: &spec.Schema{}, } if isPrimitive { - primName := b.jsonSchemaType(elemName) + primName := b.jsonSchemaType(elemName, fieldType.Elem().Elem().Kind()) prop.Items.Schema.Type = []string{primName} } else { prop.Items.Schema.Ref = spec.MustCreateRef("#/definitions/" + elemName) @@ -373,10 +397,11 @@ func (b definitionBuilder) buildPointerTypeProperty(field reflect.StructField, j } else { // non-array, pointer type fieldTypeName := keyFrom(fieldType.Elem(), b.Config) - var pType = b.jsonSchemaType(fieldTypeName) // no star, include pkg path - if b.isPrimitiveType(fieldTypeName) { + isPrimitive := b.isPrimitiveType(fieldTypeName, fieldType.Elem().Kind()) + var pType = b.jsonSchemaType(fieldTypeName, fieldType.Elem().Kind()) // no star, include pkg path + if isPrimitive { prop.Type = []string{pType} - prop.Format = b.jsonSchemaFormat(fieldTypeName) + prop.Format = b.jsonSchemaFormat(fieldTypeName, fieldType.Elem().Kind()) return jsonName, prop } prop.Ref = spec.MustCreateRef("#/definitions/" + pType) @@ -385,7 +410,9 @@ func (b definitionBuilder) buildPointerTypeProperty(field reflect.StructField, j elemName = modelName + "." + jsonName prop.Ref = spec.MustCreateRef("#/definitions/" + elemName) } - b.addModel(fieldType.Elem(), elemName) + if !isPrimitive { + b.addModel(fieldType.Elem(), elemName) + } } return jsonName, prop } @@ -416,12 +443,34 @@ func keyFrom(st reflect.Type, cfg Config) string { return key } +func (b definitionBuilder) isSliceOrArrayType(t reflect.Kind) bool { + return t == reflect.Slice || t == reflect.Array +} + +// Does the type represent a []byte? +func (b definitionBuilder) isByteArrayType(t reflect.Type) bool { + return (t.Kind() == reflect.Slice || t.Kind() == reflect.Array) && + t.Elem().Kind() == reflect.Uint8 +} + // see also https://golang.org/ref/spec#Numeric_types -func (b definitionBuilder) isPrimitiveType(modelName string) bool { +func (b definitionBuilder) isPrimitiveType(modelName string, modelKind reflect.Kind) bool { + switch modelKind { + case reflect.Bool: + return true + case reflect.Float32, reflect.Float64, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + case reflect.String: + return true + } + if len(modelName) == 0 { return false } - return strings.Contains("uint uint8 uint16 uint32 uint64 int int8 int16 int32 int64 float32 float64 bool string byte rune time.Time", modelName) + + return strings.Contains("time.Time time.Duration json.Number", modelName) } // jsonNameOfField returns the name of the field as it should appear in JSON format @@ -440,54 +489,80 @@ func (b definitionBuilder) jsonNameOfField(field reflect.StructField) string { } // see also http://json-schema.org/latest/json-schema-core.html#anchor8 -func (b definitionBuilder) jsonSchemaType(modelName string) string { +func (b definitionBuilder) jsonSchemaType(modelName string, modelKind reflect.Kind) string { schemaMap := map[string]string{ - "uint": "integer", - "uint8": "integer", - "uint16": "integer", - "uint32": "integer", - "uint64": "integer", - - "int": "integer", - "int8": "integer", - "int16": "integer", - "int32": "integer", - "int64": "integer", - - "byte": "integer", - "float64": "number", - "float32": "number", - "bool": "boolean", - "time.Time": "string", + "time.Time": "string", + "time.Duration": "integer", + "json.Number": "number", } - mapped, ok := schemaMap[modelName] - if !ok { - return modelName // use as is (custom or struct) + + if mapped, ok := schemaMap[modelName]; ok { + return mapped } - return mapped + + // check if original type is primitive + switch modelKind { + case reflect.Bool: + return "boolean" + case reflect.Float32, reflect.Float64: + return "number" + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return "integer" + case reflect.String: + return "string" + } + + return modelName // use as is (custom or struct) } -func (b definitionBuilder) jsonSchemaFormat(modelName string) string { +func (b definitionBuilder) jsonSchemaFormat(modelName string, modelKind reflect.Kind) string { if b.Config.SchemaFormatHandler != nil { if mapped := b.Config.SchemaFormatHandler(modelName); mapped != "" { return mapped } } + schemaMap := map[string]string{ - "int": "int32", - "int32": "int32", - "int64": "int64", - "byte": "byte", - "uint": "integer", - "uint8": "byte", - "float64": "double", - "float32": "float", - "time.Time": "date-time", - "*time.Time": "date-time", + "time.Time": "date-time", + "*time.Time": "date-time", + "time.Duration": "integer", + "*time.Duration": "integer", + "json.Number": "double", + "*json.Number": "double", } - mapped, ok := schemaMap[modelName] - if !ok { - return "" // no format + + if mapped, ok := schemaMap[modelName]; ok { + return mapped } - return mapped + + // check if original type is primitive + switch modelKind { + case reflect.Float32: + return "float" + case reflect.Float64: + return "double" + case reflect.Int: + return "int32" + case reflect.Int8: + return "byte" + case reflect.Int16: + return "integer" + case reflect.Int32: + return "int32" + case reflect.Int64: + return "int64" + case reflect.Uint: + return "integer" + case reflect.Uint8: + return "byte" + case reflect.Uint16: + return "integer" + case reflect.Uint32: + return "integer" + case reflect.Uint64: + return "integer" + } + + return "" // no format } diff --git a/vendor/github.com/emicklei/go-restful-openapi/go.mod b/vendor/github.com/emicklei/go-restful-openapi/go.mod new file mode 100644 index 000000000..79947596d --- /dev/null +++ b/vendor/github.com/emicklei/go-restful-openapi/go.mod @@ -0,0 +1,18 @@ +module github.com/emicklei/go-restful-openapi + +require ( + github.com/PuerkitoBio/purell v1.1.0 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/emicklei/go-restful v2.9.6+incompatible + github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa // indirect + github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d // indirect + github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee + github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 // indirect + github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57 // indirect + github.com/stretchr/testify v1.3.0 // indirect + golang.org/x/net v0.0.0-20180530234432-1e491301e022 // indirect + golang.org/x/text v0.3.0 // indirect + gopkg.in/yaml.v2 v2.2.1 // indirect +) + +go 1.13 diff --git a/vendor/github.com/emicklei/go-restful-openapi/go.sum b/vendor/github.com/emicklei/go-restful-openapi/go.sum new file mode 100644 index 000000000..1448e65e4 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful-openapi/go.sum @@ -0,0 +1,49 @@ +github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful v1.1.3 h1:KOKLkEASmIa2roa2xEV6WkADqyWrok5dt3TOMMHF1fE= +github.com/emicklei/go-restful v1.1.3/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.3+incompatible h1:2OwhVdhtzYUp5P5wuGsVDPagKSRd9JK72sJCHVCXh5g= +github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w= +github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa h1:hr8WVDjg4JKtQptZpzyb196TmruCs7PIsdJz8KAOZp8= +github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d h1:k3UQ7Z8yFYq0BNkYykKIheY0HlZBl1Hku+pO9HE9FNU= +github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee h1:eo0HQoNFtbiEc7+1gRF9pgW6azx8a1cO2fXcqq1MuD0= +github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= +github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 h1:+vsw187FKvA2QUGAcE+vQSfyxqLbUXixPYRRMAzwu04= +github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57 h1:qhv1ir3dIyOFmFU+5KqG4dF3zSQTA4nn1DFhu2NQC44= +github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/net v0.0.0-20180530234432-1e491301e022 h1:MVYFTUmVD3/+ERcvRRI+P/C2+WOUimXh+Pd8LVsklZ4= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/emicklei/go-restful-openapi/spec_resource.go b/vendor/github.com/emicklei/go-restful-openapi/spec_resource.go index b36274061..b673e83fe 100644 --- a/vendor/github.com/emicklei/go-restful-openapi/spec_resource.go +++ b/vendor/github.com/emicklei/go-restful-openapi/spec_resource.go @@ -12,7 +12,7 @@ func NewOpenAPIService(config Config) *restful.WebService { ws := new(restful.WebService) ws.Path(config.APIPath) ws.Produces(restful.MIME_JSON) - if config.DisableCORS { + if !config.DisableCORS { ws.Filter(enableCORS) } @@ -45,6 +45,7 @@ func BuildSwagger(config Config) *spec.Swagger { } swagger := &spec.Swagger{ SwaggerProps: spec.SwaggerProps{ + Host: config.Host, Swagger: "2.0", Paths: paths, Definitions: definitions, diff --git a/vendor/github.com/emicklei/go-restful/.gitignore b/vendor/github.com/emicklei/go-restful/.gitignore index cece7be66..446be09b4 100644 --- a/vendor/github.com/emicklei/go-restful/.gitignore +++ b/vendor/github.com/emicklei/go-restful/.gitignore @@ -68,3 +68,4 @@ examples/restful-html-template s.html restful-path-tail +.idea diff --git a/vendor/github.com/emicklei/go-restful/.travis.yml b/vendor/github.com/emicklei/go-restful/.travis.yml index b22f8f547..3a0bf5ff1 100644 --- a/vendor/github.com/emicklei/go-restful/.travis.yml +++ b/vendor/github.com/emicklei/go-restful/.travis.yml @@ -3,4 +3,11 @@ language: go go: - 1.x -script: go test -v \ No newline at end of file +before_install: + - go test -v + +script: + - go test -race -coverprofile=coverage.txt -covermode=atomic + +after_success: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/CHANGES.md b/vendor/github.com/emicklei/go-restful/CHANGES.md index e52529631..115263571 100644 --- a/vendor/github.com/emicklei/go-restful/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/CHANGES.md @@ -1,59 +1,97 @@ -## Change history of go-restful +# Change history of go-restful -v2.9.5 +## [v2.14.3] - 2020-08-31 +- Fixed duplicate compression in dispatch. #449 + + +## [v2.14.2] - 2020-08-31 + +- Added check on writer to prevent compression of response twice. #447 + +## [v2.14.0] - 2020-08-19 + +- Enable content encoding on Handle and ServeHTTP (#446) +- List available representations in 406 body (#437) +- Convert to string using rune() (#443) + +## [v2.13.0] - 2020-06-21 + +- 405 Method Not Allowed must have Allow header (#436) +- add field allowedMethodsWithoutContentType (#424) + +## v2.12.0 + +- support describing response headers (#426) +- fix openapi examples (#425) +- merge v3 fix (#422) + +## v2.11.1 + +- fix WriteError return value (#415) + +## v2.11.0 + +- allow prefix and suffix in path variable expression (#414) + +## v2.9.6 + +- support google custome verb (#413) + +## v2.9.5 + - fix panic in Response.WriteError if err == nil -v2.9.4 +## v2.9.4 - fix issue #400 , parsing mime type quality - Route Builder added option for contentEncodingEnabled (#398) -v2.9.3 +## v2.9.3 - Avoid return of 415 Unsupported Media Type when request body is empty (#396) -v2.9.2 +## v2.9.2 - Reduce allocations in per-request methods to improve performance (#395) -v2.9.1 +## v2.9.1 - Fix issue with default responses and invalid status code 0. (#393) -v2.9.0 +## v2.9.0 - add per Route content encoding setting (overrides container setting) -v2.8.0 +## v2.8.0 - add Request.QueryParameters() - add json-iterator (via build tag) - disable vgo module (until log is moved) -v2.7.1 +## v2.7.1 - add vgo module -v2.6.1 +## v2.6.1 - add JSONNewDecoderFunc to allow custom JSON Decoder usage (go 1.10+) -v2.6.0 +## v2.6.0 - Make JSR 311 routing and path param processing consistent - Adding description to RouteBuilder.Reads() - Update example for Swagger12 and OpenAPI -2017-09-13 +## 2017-09-13 - added route condition functions using `.If(func)` in route building. -2017-02-16 +## 2017-02-16 - solved issue #304, make operation names unique -2017-01-30 +## 2017-01-30 [IMPORTANT] For swagger users, change your import statement to: swagger "github.com/emicklei/go-restful-swagger12" @@ -61,60 +99,60 @@ v2.6.0 - moved swagger 1.2 code to go-restful-swagger12 - created TAG 2.0.0 -2017-01-27 +## 2017-01-27 - remove defer request body close - expose Dispatch for testing filters and Routefunctions - swagger response model cannot be array - created TAG 1.0.0 -2016-12-22 +## 2016-12-22 - (API change) Remove code related to caching request content. Removes SetCacheReadEntity(doCache bool) -2016-11-26 +## 2016-11-26 - Default change! now use CurlyRouter (was RouterJSR311) - Default change! no more caching of request content - Default change! do not recover from panics -2016-09-22 +## 2016-09-22 - fix the DefaultRequestContentType feature -2016-02-14 +## 2016-02-14 - take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response - add constructors for custom entity accessors for xml and json -2015-09-27 +## 2015-09-27 - rename new WriteStatusAnd... to WriteHeaderAnd... for consistency -2015-09-25 +## 2015-09-25 - fixed problem with changing Header after WriteHeader (issue 235) -2015-09-14 +## 2015-09-14 - changed behavior of WriteHeader (immediate write) and WriteEntity (no status write) - added support for custom EntityReaderWriters. -2015-08-06 +## 2015-08-06 - add support for reading entities from compressed request content - use sync.Pool for compressors of http response and request body - add Description to Parameter for documentation in Swagger UI -2015-03-20 +## 2015-03-20 - add configurable logging -2015-03-18 +## 2015-03-18 - if not specified, the Operation is derived from the Route function -2015-03-17 +## 2015-03-17 - expose Parameter creation functions - make trace logger an interface @@ -123,26 +161,26 @@ v2.6.0 - JSR311 router now handles wildcards - add Notes to Route -2014-11-27 +## 2014-11-27 - (api add) PrettyPrint per response. (as proposed in #167) -2014-11-12 +## 2014-11-12 - (api add) ApiVersion(.) for documentation in Swagger UI -2014-11-10 +## 2014-11-10 - (api change) struct fields tagged with "description" show up in Swagger UI -2014-10-31 +## 2014-10-31 - (api change) ReturnsError -> Returns - (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder - fix swagger nested structs - sort Swagger response messages by code -2014-10-23 +## 2014-10-23 - (api add) ReturnsError allows you to document Http codes in swagger - fixed problem with greedy CurlyRouter @@ -156,73 +194,73 @@ v2.6.0 - (api add) added AllowedDomains in CORS - (api add) ParameterNamed for detailed documentation -2014-04-16 +## 2014-04-16 - (api add) expose constructor of Request for testing. -2014-06-27 +## 2014-06-27 - (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification). - (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons). -2014-07-03 +## 2014-07-03 - (api add) CORS can be configured with a list of allowed domains -2014-03-12 +## 2014-03-12 - (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter) -2014-02-26 +## 2014-02-26 - (api add) Request now provides information about the matched Route, see method SelectedRoutePath -2014-02-17 +## 2014-02-17 - (api change) renamed parameter constants (go-lint checks) -2014-01-10 +## 2014-01-10 - (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier -2014-01-07 +## 2014-01-07 - (api change) Write* methods in Response now return the error or nil. - added example of serving HTML from a Go template. - fixed comparing Allowed headers in CORS (is now case-insensitive) -2013-11-13 +## 2013-11-13 - (api add) Response knows how many bytes are written to the response body. -2013-10-29 +## 2013-10-29 - (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information. -2013-10-04 +## 2013-10-04 - (api add) Response knows what HTTP status has been written - (api add) Request can have attributes (map of string->interface, also called request-scoped variables -2013-09-12 +## 2013-09-12 - (api change) Router interface simplified - Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths -2013-08-05 +## 2013-08-05 - add OPTIONS support - add CORS support -2013-08-27 +## 2013-08-27 - fixed some reported issues (see github) - (api change) deprecated use of WriteError; use WriteErrorString instead -2014-04-15 +## 2014-04-15 - (fix) v1.0.1 tag: fix Issue 111: WriteErrorString -2013-08-08 +## 2013-08-08 - (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer. - (api add) the swagger package has be extended to have a UI per container. @@ -235,38 +273,38 @@ Important API changes: - (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead. -2013-07-06 +## 2013-07-06 - (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature. -2013-06-19 +## 2013-06-19 - (improve) DoNotRecover option, moved request body closer, improved ReadEntity -2013-06-03 +## 2013-06-03 - (api change) removed Dispatcher interface, hide PathExpression - changed receiver names of type functions to be more idiomatic Go -2013-06-02 +## 2013-06-02 - (optimize) Cache the RegExp compilation of Paths. -2013-05-22 +## 2013-05-22 - (api add) Added support for request/response filter functions -2013-05-18 +## 2013-05-18 - (api add) Added feature to change the default Http Request Dispatch function (travis cline) - (api change) Moved Swagger Webservice to swagger package (see example restful-user) -[2012-11-14 .. 2013-05-18> +## [2012-11-14 .. 2013-05-18> - See https://github.com/emicklei/go-restful/commits -2012-11-14 +## 2012-11-14 - Initial commit diff --git a/vendor/github.com/emicklei/go-restful/Makefile b/vendor/github.com/emicklei/go-restful/Makefile index b40081cc0..cfb0cc11b 100644 --- a/vendor/github.com/emicklei/go-restful/Makefile +++ b/vendor/github.com/emicklei/go-restful/Makefile @@ -1,7 +1,8 @@ all: test test: - go test -v . + go vet . + go test -cover -v . ex: cd examples && ls *.go | xargs go build -o /tmp/ignore \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/README.md b/vendor/github.com/emicklei/go-restful/README.md index f52c25acf..4b4d26e72 100644 --- a/vendor/github.com/emicklei/go-restful/README.md +++ b/vendor/github.com/emicklei/go-restful/README.md @@ -4,7 +4,8 @@ package for building REST-style Web Services using Google Go [![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful) [![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) -[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://godoc.org/github.com/emicklei/go-restful) +[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) +[![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) - [Code examples](https://github.com/emicklei/go-restful/tree/master/examples) @@ -18,6 +19,28 @@ REST asks developers to use HTTP methods explicitly and in a way that's consiste - PATCH = Update partial content of a resource - OPTIONS = Get information about the communication options for the request URI +### Usage + +#### Without Go Modules + +All versions up to `v2.*.*` (on the master) are not supporting Go modules. + +``` +import ( + restful "github.com/emicklei/go-restful" +) +``` + +#### Using Go Modules + +As of version `v3.0.0` (on the v3 branch), this package supports Go modules. + +``` +import ( + restful "github.com/emicklei/go-restful/v3" +) +``` + ### Example ```Go @@ -43,9 +66,9 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo ### Features -- Routes for request → function mapping with path parameter (e.g. {id}) support +- Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support - Configurable router: - - (default) Fast routing algorithm that allows static elements, regular expressions and dynamic parameters in the URL path (e.g. /meetings/{id} or /static/{subpath:*} + - (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*}) - Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions - Request API for reading structs from JSON/XML and accesing parameters (path,query,header) - Response API for writing structs to JSON/XML and setting headers @@ -85,4 +108,4 @@ TODO: write examples of these. Type ```git shortlog -s``` for a full list of contributors. -© 2012 - 2018, http://ernestmicklei.com. MIT License. Contributions are welcome. +© 2012 - 2020, http://ernestmicklei.com. MIT License. Contributions are welcome. diff --git a/vendor/github.com/emicklei/go-restful/container.go b/vendor/github.com/emicklei/go-restful/container.go index 061a8d718..afca312a4 100644 --- a/vendor/github.com/emicklei/go-restful/container.go +++ b/vendor/github.com/emicklei/go-restful/container.go @@ -185,6 +185,11 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) // when a ServiceError is returned during route selection. Default implementation // calls resp.WriteErrorString(err.Code, err.Message) func writeServiceError(err ServiceError, req *Request, resp *Response) { + for header, values := range err.Header { + for _, value := range values { + resp.Header().Add(header, value) + } + } resp.WriteErrorString(err.Code, err.Message) } @@ -201,6 +206,7 @@ func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.R // Dispatch the incoming Http Request to a matching WebService. func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { + // so we can assign a compressing one later writer := httpWriter // CompressingResponseWriter should be closed after all operations are done @@ -231,28 +237,8 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R c.webServices, httpRequest) }() - - // Detect if compression is needed - // assume without compression, test for override - contentEncodingEnabled := c.contentEncodingEnabled - if route != nil && route.contentEncodingEnabled != nil { - contentEncodingEnabled = *route.contentEncodingEnabled - } - if contentEncodingEnabled { - doCompress, encoding := wantsCompressedResponse(httpRequest) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - } - if err != nil { - // a non-200 response has already been written + // a non-200 response (may be compressed) has already been written // run container filters anyway ; they should not touch the response... chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { switch err.(type) { @@ -265,6 +251,29 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer)) return } + + // Unless httpWriter is already an CompressingResponseWriter see if we need to install one + if _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing { + // Detect if compression is needed + // assume without compression, test for override + contentEncodingEnabled := c.contentEncodingEnabled + if route != nil && route.contentEncodingEnabled != nil { + contentEncodingEnabled = *route.contentEncodingEnabled + } + if contentEncodingEnabled { + doCompress, encoding := wantsCompressedResponse(httpRequest) + if doCompress { + var err error + writer, err = NewCompressingResponseWriter(httpWriter, encoding) + if err != nil { + log.Print("unable to install compressor: ", err) + httpWriter.WriteHeader(http.StatusInternalServerError) + return + } + } + } + } + pathProcessor, routerProcessesPath := c.router.(PathProcessor) if !routerProcessesPath { pathProcessor = defaultPathProcessor{} @@ -272,16 +281,13 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path) wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams) // pass through filters (if any) - if len(c.containerFilters)+len(webService.filters)+len(route.Filters) > 0 { + if size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 { // compose filter chain - allFilters := []FilterFunction{} + allFilters := make([]FilterFunction, 0, size) allFilters = append(allFilters, c.containerFilters...) allFilters = append(allFilters, webService.filters...) allFilters = append(allFilters, route.Filters...) - chain := FilterChain{Filters: allFilters, Target: func(req *Request, resp *Response) { - // handle request by route after passing all filters - route.Function(wrappedRequest, wrappedResponse) - }} + chain := FilterChain{Filters: allFilters, Target: route.Function} chain.ProcessFilter(wrappedRequest, wrappedResponse) } else { // no filters, handle request by route @@ -299,13 +305,75 @@ func fixedPrefixPath(pathspec string) string { } // ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server -func (c *Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) { - c.ServeMux.ServeHTTP(httpwriter, httpRequest) +func (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) { + // Skip, if content encoding is disabled + if !c.contentEncodingEnabled { + c.ServeMux.ServeHTTP(httpWriter, httpRequest) + return + } + // content encoding is enabled + + // Skip, if httpWriter is already an CompressingResponseWriter + if _, ok := httpWriter.(*CompressingResponseWriter); ok { + c.ServeMux.ServeHTTP(httpWriter, httpRequest) + return + } + + writer := httpWriter + // CompressingResponseWriter should be closed after all operations are done + defer func() { + if compressWriter, ok := writer.(*CompressingResponseWriter); ok { + compressWriter.Close() + } + }() + + doCompress, encoding := wantsCompressedResponse(httpRequest) + if doCompress { + var err error + writer, err = NewCompressingResponseWriter(httpWriter, encoding) + if err != nil { + log.Print("unable to install compressor: ", err) + httpWriter.WriteHeader(http.StatusInternalServerError) + return + } + } + + c.ServeMux.ServeHTTP(writer, httpRequest) } // Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics. func (c *Container) Handle(pattern string, handler http.Handler) { - c.ServeMux.Handle(pattern, handler) + c.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) { + // Skip, if httpWriter is already an CompressingResponseWriter + if _, ok := httpWriter.(*CompressingResponseWriter); ok { + handler.ServeHTTP(httpWriter, httpRequest) + return + } + + writer := httpWriter + + // CompressingResponseWriter should be closed after all operations are done + defer func() { + if compressWriter, ok := writer.(*CompressingResponseWriter); ok { + compressWriter.Close() + } + }() + + if c.contentEncodingEnabled { + doCompress, encoding := wantsCompressedResponse(httpRequest) + if doCompress { + var err error + writer, err = NewCompressingResponseWriter(httpWriter, encoding) + if err != nil { + log.Print("unable to install compressor: ", err) + httpWriter.WriteHeader(http.StatusInternalServerError) + return + } + } + } + + handler.ServeHTTP(writer, httpRequest) + })) } // HandleWithFilter registers the handler for the given pattern. @@ -319,7 +387,7 @@ func (c *Container) HandleWithFilter(pattern string, handler http.Handler) { } chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - handler.ServeHTTP(httpResponse, httpRequest) + handler.ServeHTTP(resp, req.Request) }} chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse)) } diff --git a/vendor/github.com/emicklei/go-restful/curly.go b/vendor/github.com/emicklei/go-restful/curly.go index 14d5b76bf..ba1fc5d5f 100644 --- a/vendor/github.com/emicklei/go-restful/curly.go +++ b/vendor/github.com/emicklei/go-restful/curly.go @@ -47,7 +47,7 @@ func (c CurlyRouter) SelectRoute( func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes { candidates := make(sortableCurlyRoutes, 0, 8) for _, each := range ws.routes { - matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens) + matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb) if matches { candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers? } @@ -57,7 +57,7 @@ func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortab } // matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are. -func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string) (matches bool, paramCount int, staticCount int) { +func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string, routeHasCustomVerb bool) (matches bool, paramCount int, staticCount int) { if len(routeTokens) < len(requestTokens) { // proceed in matching only if last routeToken is wildcard count := len(routeTokens) @@ -72,6 +72,15 @@ func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []strin return false, 0, 0 } requestToken := requestTokens[i] + if routeHasCustomVerb && hasCustomVerb(routeToken){ + if !isMatchCustomVerb(routeToken, requestToken) { + return false, 0, 0 + } + staticCount++ + requestToken = removeCustomVerb(requestToken) + routeToken = removeCustomVerb(routeToken) + } + if strings.HasPrefix(routeToken, "{") { paramCount++ if colon := strings.Index(routeToken, ":"); colon != -1 { diff --git a/vendor/github.com/emicklei/go-restful/custom_verb.go b/vendor/github.com/emicklei/go-restful/custom_verb.go new file mode 100644 index 000000000..bfc17efde --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/custom_verb.go @@ -0,0 +1,29 @@ +package restful + +import ( + "fmt" + "regexp" +) + +var ( + customVerbReg = regexp.MustCompile(":([A-Za-z]+)$") +) + +func hasCustomVerb(routeToken string) bool { + return customVerbReg.MatchString(routeToken) +} + +func isMatchCustomVerb(routeToken string, pathToken string) bool { + rs := customVerbReg.FindStringSubmatch(routeToken) + if len(rs) < 2 { + return false + } + + customVerb := rs[1] + specificVerbReg := regexp.MustCompile(fmt.Sprintf(":%s$", customVerb)) + return specificVerbReg.MatchString(pathToken) +} + +func removeCustomVerb(str string) string { + return customVerbReg.ReplaceAllString(str, "") +} diff --git a/vendor/github.com/emicklei/go-restful/jsr311.go b/vendor/github.com/emicklei/go-restful/jsr311.go index 3ede1891e..9cfd59a1c 100644 --- a/vendor/github.com/emicklei/go-restful/jsr311.go +++ b/vendor/github.com/emicklei/go-restful/jsr311.go @@ -9,6 +9,7 @@ import ( "fmt" "net/http" "sort" + "strings" ) // RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions) @@ -98,7 +99,18 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R if trace { traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(previous), httpRequest.Method) } - return nil, NewError(http.StatusMethodNotAllowed, "405: Method Not Allowed") + allowed := []string{} + allowedLoop: + for _, candidate := range previous { + for _, method := range allowed { + if method == candidate.Method { + continue allowedLoop + } + } + allowed = append(allowed, candidate.Method) + } + header := http.Header{"Allow": []string{strings.Join(allowed, ", ")}} + return nil, NewErrorWithHeader(http.StatusMethodNotAllowed, "405: Method Not Allowed", header) } // content-type @@ -135,7 +147,14 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R if trace { traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(previous), accept) } - return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable") + available := []string{} + for _, candidate := range previous { + available = append(available, candidate.Produces...) + } + return nil, NewError( + http.StatusNotAcceptable, + fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")), + ) } // return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil return candidates[0], nil diff --git a/vendor/github.com/emicklei/go-restful/path_processor.go b/vendor/github.com/emicklei/go-restful/path_processor.go index 357c723a7..141573245 100644 --- a/vendor/github.com/emicklei/go-restful/path_processor.go +++ b/vendor/github.com/emicklei/go-restful/path_processor.go @@ -29,7 +29,12 @@ func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath } else { value = urlParts[i] } - if strings.HasPrefix(key, "{") { // path-parameter + if r.hasCustomVerb && hasCustomVerb(key) { + key = removeCustomVerb(key) + value = removeCustomVerb(value) + } + + if strings.Index(key, "{") > -1 { // path-parameter if colon := strings.Index(key, ":"); colon != -1 { // extract by regex regPart := key[colon+1 : len(key)-1] @@ -42,7 +47,13 @@ func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath } } else { // without enclosing {} - pathParameters[key[1:len(key)-1]] = value + startIndex := strings.Index(key, "{") + endKeyIndex := strings.Index(key, "}") + + suffixLength := len(key) - endKeyIndex - 1 + endValueIndex := len(value) - suffixLength + + pathParameters[key[startIndex+1:endKeyIndex]] = value[startIndex:endValueIndex] } } } diff --git a/vendor/github.com/emicklei/go-restful/response.go b/vendor/github.com/emicklei/go-restful/response.go index fbb48f2da..e2f78f00f 100644 --- a/vendor/github.com/emicklei/go-restful/response.go +++ b/vendor/github.com/emicklei/go-restful/response.go @@ -174,15 +174,16 @@ func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType return writeJSON(r, status, contentType, value) } -// WriteError write the http status and the error string on the response. err can be nil. -func (r *Response) WriteError(httpStatus int, err error) error { +// WriteError writes the http status and the error string on the response. err can be nil. +// Return an error if writing was not succesful. +func (r *Response) WriteError(httpStatus int, err error) (writeErr error) { r.err = err if err == nil { - r.WriteErrorString(httpStatus, "") + writeErr = r.WriteErrorString(httpStatus, "") } else { - r.WriteErrorString(httpStatus, err.Error()) + writeErr = r.WriteErrorString(httpStatus, err.Error()) } - return err + return writeErr } // WriteServiceError is a convenience method for a responding with a status and a ServiceError diff --git a/vendor/github.com/emicklei/go-restful/route.go b/vendor/github.com/emicklei/go-restful/route.go index 6d15dbf66..598aa57a7 100644 --- a/vendor/github.com/emicklei/go-restful/route.go +++ b/vendor/github.com/emicklei/go-restful/route.go @@ -49,11 +49,20 @@ type Route struct { //Overrides the container.contentEncodingEnabled contentEncodingEnabled *bool + + // indicate route path has custom verb + hasCustomVerb bool + + // if a request does not include a content-type header then + // depending on the method, it may return a 415 Unsupported Media + // Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,... + allowedMethodsWithoutContentType []string } // Initialize for Route func (r *Route) postBuild() { r.pathParts = tokenizePath(r.Path) + r.hasCustomVerb = hasCustomVerb(r.Path) } // Create Request and Response from their http versions @@ -67,17 +76,6 @@ func (r *Route) wrapRequestResponse(httpWriter http.ResponseWriter, httpRequest return wrappedRequest, wrappedResponse } -// dispatchWithFilters call the function after passing through its own filters -func (r *Route) dispatchWithFilters(wrappedRequest *Request, wrappedResponse *Response) { - if len(r.Filters) > 0 { - chain := FilterChain{Filters: r.Filters, Target: r.Function} - chain.ProcessFilter(wrappedRequest, wrappedResponse) - } else { - // unfiltered - r.Function(wrappedRequest, wrappedResponse) - } -} - func stringTrimSpaceCutset(r rune) bool { return r == ' ' } @@ -121,8 +119,17 @@ func (r Route) matchesContentType(mimeTypes string) bool { if len(mimeTypes) == 0 { // idempotent methods with (most-likely or guaranteed) empty content match missing Content-Type m := r.Method - if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" { - return true + // if route specifies less or non-idempotent methods then use that + if len(r.allowedMethodsWithoutContentType) > 0 { + for _, each := range r.allowedMethodsWithoutContentType { + if m == each { + return true + } + } + } else { + if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" { + return true + } } // proceed with default mimeTypes = MIME_OCTET diff --git a/vendor/github.com/emicklei/go-restful/route_builder.go b/vendor/github.com/emicklei/go-restful/route_builder.go index 0fccf61e9..1d67a4c23 100644 --- a/vendor/github.com/emicklei/go-restful/route_builder.go +++ b/vendor/github.com/emicklei/go-restful/route_builder.go @@ -17,14 +17,15 @@ import ( // RouteBuilder is a helper to construct Routes. type RouteBuilder struct { - rootPath string - currentPath string - produces []string - consumes []string - httpMethod string // required - function RouteFunction // required - filters []FilterFunction - conditions []RouteSelectionConditionFunction + rootPath string + currentPath string + produces []string + consumes []string + httpMethod string // required + function RouteFunction // required + filters []FilterFunction + conditions []RouteSelectionConditionFunction + allowedMethodsWithoutContentType []string // see Route typeNameHandleFunc TypeNameHandleFunction // required @@ -176,6 +177,15 @@ func (b *RouteBuilder) Returns(code int, message string, model interface{}) *Rou return b } +// ReturnsWithHeaders is similar to Returns, but can specify response headers +func (b *RouteBuilder) ReturnsWithHeaders(code int, message string, model interface{}, headers map[string]Header) *RouteBuilder { + b.Returns(code, message, model) + err := b.errorMap[code] + err.Headers = headers + b.errorMap[code] = err + return b +} + // DefaultReturns is a special Returns call that sets the default of the response. func (b *RouteBuilder) DefaultReturns(message string, model interface{}) *RouteBuilder { b.defaultResponse = &ResponseError{ @@ -200,14 +210,41 @@ func (b *RouteBuilder) Deprecate() *RouteBuilder { return b } +// AllowedMethodsWithoutContentType overides the default list GET,HEAD,OPTIONS,DELETE,TRACE +// If a request does not include a content-type header then +// depending on the method, it may return a 415 Unsupported Media. +// Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,... +func (b *RouteBuilder) AllowedMethodsWithoutContentType(methods []string) *RouteBuilder { + b.allowedMethodsWithoutContentType = methods + return b +} + // ResponseError represents a response; not necessarily an error. type ResponseError struct { Code int Message string Model interface{} + Headers map[string]Header IsDefault bool } +// Header describes a header for a response of the API +// +// For more information: http://goo.gl/8us55a#headerObject +type Header struct { + *Items + Description string +} + +// Items describe swagger simple schemas for headers +type Items struct { + Type string + Format string + Items *Items + CollectionFormat string + Default interface{} +} + func (b *RouteBuilder) servicePath(path string) *RouteBuilder { b.rootPath = path return b @@ -276,26 +313,27 @@ func (b *RouteBuilder) Build() Route { operationName = nameOfFunction(b.function) } route := Route{ - Method: b.httpMethod, - Path: concatPath(b.rootPath, b.currentPath), - Produces: b.produces, - Consumes: b.consumes, - Function: b.function, - Filters: b.filters, - If: b.conditions, - relativePath: b.currentPath, - pathExpr: pathExpr, - Doc: b.doc, - Notes: b.notes, - Operation: operationName, - ParameterDocs: b.parameters, - ResponseErrors: b.errorMap, - DefaultResponse: b.defaultResponse, - ReadSample: b.readSample, - WriteSample: b.writeSample, - Metadata: b.metadata, - Deprecated: b.deprecated, - contentEncodingEnabled: b.contentEncodingEnabled, + Method: b.httpMethod, + Path: concatPath(b.rootPath, b.currentPath), + Produces: b.produces, + Consumes: b.consumes, + Function: b.function, + Filters: b.filters, + If: b.conditions, + relativePath: b.currentPath, + pathExpr: pathExpr, + Doc: b.doc, + Notes: b.notes, + Operation: operationName, + ParameterDocs: b.parameters, + ResponseErrors: b.errorMap, + DefaultResponse: b.defaultResponse, + ReadSample: b.readSample, + WriteSample: b.writeSample, + Metadata: b.metadata, + Deprecated: b.deprecated, + contentEncodingEnabled: b.contentEncodingEnabled, + allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType, } route.postBuild() return route diff --git a/vendor/github.com/emicklei/go-restful/service_error.go b/vendor/github.com/emicklei/go-restful/service_error.go index 62d1108bb..a41575469 100644 --- a/vendor/github.com/emicklei/go-restful/service_error.go +++ b/vendor/github.com/emicklei/go-restful/service_error.go @@ -4,12 +4,16 @@ package restful // Use of this source code is governed by a license // that can be found in the LICENSE file. -import "fmt" +import ( + "fmt" + "net/http" +) // ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request. type ServiceError struct { Code int Message string + Header http.Header } // NewError returns a ServiceError using the code and reason @@ -17,6 +21,11 @@ func NewError(code int, message string) ServiceError { return ServiceError{Code: code, Message: message} } +// NewErrorWithHeader returns a ServiceError using the code, reason and header +func NewErrorWithHeader(code int, message string, header http.Header) ServiceError { + return ServiceError{Code: code, Message: message, Header: header} +} + // Error returns a text representation of the service error func (s ServiceError) Error() string { return fmt.Sprintf("[ServiceError:%v] %v", s.Code, s.Message) diff --git a/vendor/github.com/emicklei/go-restful/web_service.go b/vendor/github.com/emicklei/go-restful/web_service.go index 77ba9a8cf..4f9079674 100644 --- a/vendor/github.com/emicklei/go-restful/web_service.go +++ b/vendor/github.com/emicklei/go-restful/web_service.go @@ -188,7 +188,7 @@ func (w *WebService) RemoveRoute(path, method string) error { continue } newRoutes[current] = w.routes[ix] - current = current + 1 + current++ } w.routes = newRoutes return nil diff --git a/vendor/modules.txt b/vendor/modules.txt index 8dbc15d4a..8cb133cd0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -134,9 +134,9 @@ github.com/elastic/go-elasticsearch/v7 github.com/elastic/go-elasticsearch/v7/esapi github.com/elastic/go-elasticsearch/v7/estransport github.com/elastic/go-elasticsearch/v7/internal/version -# github.com/emicklei/go-restful v2.11.1+incompatible => github.com/emicklei/go-restful v2.9.5+incompatible +# github.com/emicklei/go-restful v2.14.3+incompatible => github.com/emicklei/go-restful v2.14.3+incompatible github.com/emicklei/go-restful -# github.com/emicklei/go-restful-openapi v1.0.0 => github.com/emicklei/go-restful-openapi v1.0.0 +# github.com/emicklei/go-restful-openapi v1.4.1 => github.com/emicklei/go-restful-openapi v1.4.1 github.com/emicklei/go-restful-openapi github.com/emicklei/go-restful/log # github.com/emirpasic/gods v1.12.0 => github.com/emirpasic/gods v1.12.0