diff --git a/Gopkg.lock b/Gopkg.lock index 117f41b7a..2410d4bda 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -568,7 +568,6 @@ "pkg/kbcontroller", "pkg/resource" ] - revision = "1be8f5eada07fe5b17804e4b91fc2f4c4fc4ecb9" source = "https://github.com/kubesphere/application" [[projects]] diff --git a/README.md b/README.md index a3ba55bee..bd6944773 100644 --- a/README.md +++ b/README.md @@ -8,23 +8,56 @@ [KubeSphere](https://kubesphere.io/) is an enterprise-grade multi-tenant container management platform that built on [Kubernetes](https://kubernetes.io). It provides an easy-to-use UI enables creation of computing resources with a few clicks and one-click deployment, which reduces the learning curve and empower the DevOps teams. It greatly reduces the complexity of the daily work of development, testing, operation and maintenance, aiming to solve the pain spots of Kubernetes' storage, network, security and ease of use, etc. -> See this [document](https://docs.kubesphere.io/advanced-v1.0/en/introduction/intro/) that describes the KubeSphere landscape and details. +> See this [document](https://docs.kubesphere.io/advanced-v2.0/zh-CN/introduction/intro/) that describes the KubeSphere landscape and details. ## Features -KubeSphere provides an easy-to-use console with the awesome user experience that allows you to quickly get started with a container management platform. KubeSphere provides and integrates workload management, DevOps Delivery, multi-tenant management, multi-dimensional monitoring, service and network management, application scheduling, infrastructure management, image registry management, etc. It also supports multiple open source storage and high-performance cloud storage as the persistent storage services. +KubeSphere Advanced Edition 2.0.0 provides an easy-to-use console with the awesome user experience that allows you to quickly get started with a container management platform. KubeSphere provides and supports following core features: -> See this [document](https://docs.kubesphere.io/advanced-v1.0/en/introduction/features/) that elaborates on the KubeSphere features and services from a professional point of view. + +- Workload management +- Service mesh (Istio-based) +- DevOps +- Source to Image +- Multi-tenant management +- Multi-dimensional and Multi-tenant Monitoring, Logging, Alerting, Notification +- Service and network management +- Application template and repository +- Infrastructure management, image registry management +- Integrate Harbor and GitLab +- LB controller for Kubernetes on bare metal ([Porter](https://github.com/kubesphere/porter)), [cloud LB plugin](https://github.com/yunify/qingcloud-cloud-controller-manager) +- Support GPU node + + +It also supports multiple open source storage and high-performance cloud storage as the persistent storage services, as well as supports multiple open source network plugins. + +> See this [document](https://docs.kubesphere.io/advanced-v2.0/zh-CN/introduction/features/) that elaborates on the KubeSphere features and services from a professional point of view. ---- +## Latest Release + +KubeSphere Advanced Edition 2.0.0 was released on **May 18th, 2019**. See the [Release Notes For 2.0.0](https://docs.kubesphere.io/advanced-v2.0/release/release-v200/) to preview the updates. + ## Installation -KubeSphere installation supports following 2 kinds of installation: +KubeSphere installation supports following 2 kinds of installation, please reference the following guides on how to get KubeSphere up and running. + +### All-in-One + +[All-in-One](https://docs.kubesphere.io/advanced-v2.0/zh-CN/installation/all-in-one/): For those who are new to KubeSphere and looking for the fastest way to install and experience the dashboard. + +Just download the installer and execute the `install.sh` under `/scripts` folder, choose `"1) All-in-one"` to trigger the installation. Generally, you can install it directly without any modification, for details please reference [All-in-One](https://docs.kubesphere.io/advanced-v2.0/zh-CN/installation/all-in-one/). + +```bash +$ curl -L https://kubesphere.io/download/stable/advanced-2.0.0 > advanced-2.0.0.tar.gz +$ tar -zxf advanced-2.0.0.tar.gz +``` + +### Multi-Node + +[Multi-Node](https://docs.kubesphere.io/advanced-v2.0/zh-CN/installation/multi-node/) is used for installing KubeSphere on multiple instances, supports for installing a highly available cluster which is able to use in a formal environment. -- [All-in-One](https://docs.kubesphere.io/advanced-v1.0/en/installation/all-in-one/): For those who are new to KubeSphere and looking for the fastest way to install and experience the dashboard, the all-in-one installation must be your best choice since it supports one-click installation. -- [Multi-Node](../https://docs.kubesphere.io/advanced-v1.0/en/installation/multi-node/): Multi-node is used for installing KubeSphere on multiple instances, supports for installing a highly available master and etcd cluster which is able to use in a formal environment. -- For Chinese version, see [KubeSphere Installation Guide (安装指南) ](https://docs.kubesphere.io/advanced-v1.0/zh-CN/installation/intro/). ### Minimum Requirements @@ -34,28 +67,25 @@ KubeSphere installation supports following 2 kinds of installation: - Red Hat Enterprise Linux Server 7.4 (64 bit) - Debian Stretch 9.5 (64 bit) - Hardware - - CPU:4 Core, Memory:8 G, Disk Space:100 G + - CPU:8 Core, Memory:16 G, Disk Space:100 G ## Quick Start -The [Quick Start Guide](https://docs.kubesphere.io/advanced-v1.0/en/quick-start/admin-quick-start/) provides 7 quick-start examples to walk you through the process and common manipulation in KubeSphere, with a quick overview of the basic features of KubeSphere that helps you to get familiar with it. +The [Quick Start Guide](https://docs.kubesphere.io/advanced-v2.0/quick-start/admin-quick-start/) provides 12 quick-start examples to walk you through the process and common manipulation in KubeSphere, with a quick overview of the core features of KubeSphere that helps you to get familiar with it. -## Latest Release - -KubeSphere Advanced Edition 1.0.1 was released on **January 28th, 2019**. See the [Release Notes For 1.0.1](https://docs.kubesphere.io/advanced-v1.0/en/release/release-v101/) to preview the updates. ## RoadMap -Currently, KubeSphere has released the following three major editions. Advanced Edition 2.0.0 will be released on April 18, 2019. The 2.0.0 release will include microservice governance, log query and collection, alerting, S2i, code continuous inspection (SonarQube), quota management for workspace, improve security performance, GPU support, as well as providing [Porter](https://github.com/kubesphere/porter), which is a load balancer for bare metal Kubernetes clusters. +Currently, KubeSphere has released the following 4 major editions. Advanced Edition 2.0.0 was released on May 18, 2019. The future releases will include Big data, AI, Multicluster, QingCloud SDN, etc. -**Community Edition** => **Express Edition** => **Advanced Edition** +**Community Edition** => **Express Edition** => **Advanced Edition 1.0.0** => **Advanced Edition 2.0.0** ![Roadmap](docs/images/roadmap-en.png) ## Documentation - [KubeSphere Documentation (En/中) ](https://docs.kubesphere.io/) -- [KubeSphere Docementation (PDF)](https://docs.kubesphere.io/KubeSphere-advanced-v1.0.pdf) +- [KubeSphere Docementation (PDF)](https://docs.kubesphere.io/KubeSphere-advanced-v2.0.pdf) ## Support, Discussion, and Community diff --git a/cmd/controller-manager/app/controllers.go b/cmd/controller-manager/app/controllers.go index d23f76e64..0bd907f0b 100644 --- a/cmd/controller-manager/app/controllers.go +++ b/cmd/controller-manager/app/controllers.go @@ -88,7 +88,8 @@ func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{ informerFactory.Core().V1().Services(), servicemeshInformer.Servicemesh().V1alpha2().ServicePolicies(), kubeClient, - istioclient) + istioclient, + servicemeshclient) apController := application.NewApplicationController(informerFactory.Core().V1().Services(), informerFactory.Apps().V1().Deployments(), diff --git a/docs/images/roadmap-en.png b/docs/images/roadmap-en.png index 5fe3630a1..af82f5f13 100644 Binary files a/docs/images/roadmap-en.png and b/docs/images/roadmap-en.png differ diff --git a/pkg/apis/iam/v1alpha2/register.go b/pkg/apis/iam/v1alpha2/register.go index d2e8e9406..bb3ff2460 100644 --- a/pkg/apis/iam/v1alpha2/register.go +++ b/pkg/apis/iam/v1alpha2/register.go @@ -20,11 +20,14 @@ package v1alpha2 import ( "github.com/emicklei/go-restful" "github.com/emicklei/go-restful-openapi" + rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/runtime/schema" "kubesphere.io/kubesphere/pkg/apiserver/iam" "kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/errors" "kubesphere.io/kubesphere/pkg/models" + "kubesphere.io/kubesphere/pkg/models/iam/policy" + "net/http" ) const GroupName = "iam.kubesphere.io" @@ -40,181 +43,220 @@ func addWebService(c *restful.Container) error { tags := []string{"IAM"} ws := runtime.NewWebService(GroupVersion) + ok := "ok" + pageableUserList := struct { + Items []models.User `json:"items"` + TotalCount int `json:"total_count"` + }{} + ws.Route(ws.POST("/authenticate"). To(iam.TokenReviewHandler). - Doc("Token review"). + Doc("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."). Reads(iam.TokenReview{}). - Writes(iam.TokenReview{}). - Doc("k8s token review"). + Returns(http.StatusOK, ok, iam.TokenReview{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.POST("/login"). To(iam.LoginHandler). - Doc("User login"). + 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(iam.LoginRequest{}). - Writes(models.Token{}). + Returns(http.StatusOK, ok, models.Token{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/users/{username}"). To(iam.DescribeUser). - Doc("User detail"). + Doc("Describes the specified user."). Param(ws.PathParameter("username", "username")). - Writes(models.User{}). + Returns(http.StatusOK, ok, models.User{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.POST("/users"). To(iam.CreateUser). + Doc("Create a user account."). Reads(models.User{}). - Writes(errors.Error{}). - Doc("Create user"). + Returns(http.StatusOK, ok, errors.Error{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.DELETE("/users/{name}"). To(iam.DeleteUser). + Doc("Remove a specified user."). Param(ws.PathParameter("name", "username")). - Doc("Delete user"). - Writes(errors.Error{}). + Returns(http.StatusOK, ok, errors.Error{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.PUT("/users/{name}"). To(iam.UpdateUser). + Doc("Updates information about the specified user."). Param(ws.PathParameter("name", "username")). Reads(models.User{}). - Writes(errors.Error{}). - Doc("Update user"). + Returns(http.StatusOK, ok, errors.Error{}). Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/users/{name}/log"). To(iam.UserLoginLog). + Doc("This method is used to retrieve the \"login logs\" for the specified user."). Param(ws.PathParameter("name", "username")). - Doc("User login log"). - Writes([]map[string]string{}). + Returns(http.StatusOK, ok, struct { + LoginTime string `json:"login_time"` + LoginIP string `json:"login_ip"` + }{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/users"). To(iam.ListUsers). - Doc("User list"). - Writes(models.PageableResponse{}). + Doc("List all users."). + Returns(http.StatusOK, ok, pageableUserList). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/groups"). To(iam.ListGroups). - Writes([]models.Group{}). - Doc("User group list"). + Doc("List all user groups."). + Returns(http.StatusOK, ok, []models.Group{}). Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/groups/{path}"). To(iam.DescribeGroup). - Param(ws.PathParameter("path", "group path")). - Doc("User group detail"). + Doc("Describes the specified user group."). + Param(ws.PathParameter("path", "user group path separated by colon.")). + Returns(http.StatusOK, ok, models.Group{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/groups/{path}/users"). To(iam.ListGroupUsers). - Param(ws.PathParameter("path", "group path")). - Doc("Group user list"). + Doc("List all users in the specified user group."). + Param(ws.PathParameter("path", "user group path separated by colon.")). + Returns(http.StatusOK, ok, []models.User{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.POST("/groups"). To(iam.CreateGroup). + Doc("Create a user group."). Reads(models.Group{}). - Doc("Create user group"). + Returns(http.StatusOK, ok, models.Group{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.DELETE("/groups/{path}"). To(iam.DeleteGroup). - Param(ws.PathParameter("path", "group path")). - Doc("Delete user group"). + Doc("Delete a user group."). + Param(ws.PathParameter("path", "user group path separated by colon.")). + Returns(http.StatusOK, ok, errors.Error{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.PUT("/groups/{path}"). To(iam.UpdateGroup). - Param(ws.PathParameter("path", "group path")). - Doc("Update user group"). + Doc("Updates information about the user group."). + Param(ws.PathParameter("path", "user group path separated by colon.")). + Reads(models.Group{}). + Returns(http.StatusOK, ok, models.Group{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/users/{username}/roles"). To(iam.ListUserRoles). + Doc("This method is used to retrieve all the roles that are assigned to the user."). Param(ws.PathParameter("username", "username")). - Doc("Get user role list"). + Returns(http.StatusOK, ok, iam.RoleList{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/namespaces/{namespace}/roles"). To(iam.ListRoles). - Param(ws.PathParameter("namespace", "namespace")). - Doc("Get role list"). + Doc("This method is used to retrieve the roles that are assigned to the user in the specified namespace."). + Param(ws.PathParameter("namespace", "kubernetes namespace")). + Returns(http.StatusOK, ok, struct { + Items []rbacv1.Role `json:"items"` + TotalCount int `json:"total_count"` + }{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/clusterroles"). To(iam.ListClusterRoles). - Doc("Get cluster role list"). + Doc("List all cluster roles."). + Returns(http.StatusOK, ok, struct { + Items []rbacv1.ClusterRole `json:"items"` + TotalCount int `json:"total_count"` + }{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/users"). To(iam.ListRoleUsers). - Param(ws.PathParameter("namespace", "namespace")). + Doc("This method is used to retrieve the users that are bind the role in the specified namespace."). + Param(ws.PathParameter("namespace", "kubernetes namespace")). Param(ws.PathParameter("role", "role name")). - Doc("Get user list by role"). + Returns(http.StatusOK, ok, []models.User{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/namespaces/{namespace}/users"). To(iam.ListNamespaceUsers). - Param(ws.PathParameter("namespace", "namespace")). - Doc("Get user list by namespace"). + Doc("List all users in the specified namespace"). + Param(ws.PathParameter("namespace", "kubernetes namespace")). + Returns(http.StatusOK, ok, []models.User{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/clusterroles/{clusterrole}/users"). To(iam.ListClusterRoleUsers). + Doc("List all users that are bind the cluster role."). Param(ws.PathParameter("clusterrole", "cluster role name")). - Doc("Get user list by cluster role"). + Returns(http.StatusOK, ok, pageableUserList). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/clusterroles/{clusterrole}/rules"). To(iam.ListClusterRoleRules). + Doc("List all policy rules of the specified cluster role."). Param(ws.PathParameter("clusterrole", "cluster role name")). - Doc("Get cluster role detail"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/rulesmapping/clusterroles"). - To(iam.ClusterRulesMapping). - Doc("Get cluster role policy rules mapping"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/rulesmapping/roles"). - To(iam.RulesMapping). - Doc("Get role policy rules mapping"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - - ws.Route(ws.GET("/workspaces/{workspace}/roles"). - To(iam.ListWorkspaceRoles). - Param(ws.PathParameter("workspace", "workspace name")). - Doc("List workspace role"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/workspaces/{workspace}/roles/{role}"). - To(iam.DescribeWorkspaceRole). - Param(ws.PathParameter("workspace", "workspace name")). - Param(ws.PathParameter("role", "workspace role name")). - Doc("Describe workspace role"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/workspaces/{workspace}/roles/{role}/rules"). - To(iam.ListWorkspaceRoleRules). - Param(ws.PathParameter("workspace", "workspace name")). - Param(ws.PathParameter("role", "workspace role name")). - Doc("Get workspace role policy rules"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/workspaces/{workspace}/members"). - To(iam.ListWorkspaceUsers). - Param(ws.PathParameter("workspace", "workspace name")). - Doc("Get workspace member list"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.POST("/workspaces/{workspace}/members"). - To(iam.InviteUser). - Param(ws.PathParameter("workspace", "workspace name")). - Doc("Add user to workspace"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.DELETE("/workspaces/{workspace}/members/{username}"). - To(iam.RemoveUser). - Param(ws.PathParameter("workspace", "workspace name")). - Param(ws.PathParameter("name", "username")). - Doc("Remove user from workspace"). - Metadata(restfulspec.KeyOpenAPITags, tags)) - ws.Route(ws.GET("/workspaces/{workspace}/members/{username}"). - To(iam.DescribeWorkspaceUser). - Param(ws.PathParameter("workspace", "workspace name")). - Param(ws.PathParameter("username", "username")). - Doc("Describe user in workspace"). + Returns(http.StatusOK, ok, []models.SimpleRule{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/rules"). To(iam.ListRoleRules). - Param(ws.PathParameter("namespace", "namespace")). + Doc("List all policy rules of the specified role."). + Param(ws.PathParameter("namespace", "kubernetes namespace")). Param(ws.PathParameter("role", "role name")). - Doc("Get namespace role policy rules"). + Returns(http.StatusOK, ok, []models.SimpleRule{}). Metadata(restfulspec.KeyOpenAPITags, tags)) ws.Route(ws.GET("/devops/{devops}/roles/{role}/rules"). To(iam.ListDevopsRoleRules). + Doc("List all policy rules of the specified role."). Param(ws.PathParameter("devops", "devops project id")). Param(ws.PathParameter("role", "devops role name")). - Doc("Get devops role policy rules"). + Returns(http.StatusOK, ok, []models.SimpleRule{}). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/rulesmapping/clusterroles"). + To(iam.ClusterRulesMapping). + Doc("Get the mapping relationships between cluster roles and policy rules."). + Returns(http.StatusOK, ok, policy.ClusterRoleRuleMapping). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/rulesmapping/roles"). + To(iam.RulesMapping). + Doc("Get the mapping relationships between namespaced roles and policy rules."). + Returns(http.StatusOK, ok, policy.RoleRuleMapping). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/workspaces/{workspace}/roles"). + To(iam.ListWorkspaceRoles). + Doc("List all workspace roles."). + Param(ws.PathParameter("workspace", "workspace name")). + Returns(http.StatusOK, ok, struct { + Items []rbacv1.ClusterRole `json:"items"` + TotalCount int `json:"total_count"` + }{}). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/workspaces/{workspace}/roles/{role}"). + To(iam.DescribeWorkspaceRole). + Doc("Describes the workspace role."). + Param(ws.PathParameter("workspace", "workspace name")). + Param(ws.PathParameter("role", "workspace role name")). + Returns(http.StatusOK, ok, rbacv1.ClusterRole{}). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/workspaces/{workspace}/roles/{role}/rules"). + To(iam.ListWorkspaceRoleRules). + Doc("List all policy rules of the specified workspace role."). + Param(ws.PathParameter("workspace", "workspace name")). + Param(ws.PathParameter("role", "workspace role name")). + Returns(http.StatusOK, ok, []models.SimpleRule{}). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/workspaces/{workspace}/members"). + To(iam.ListWorkspaceUsers). + Doc("List all members in the specified workspace."). + Param(ws.PathParameter("workspace", "workspace name")). + Returns(http.StatusOK, ok, pageableUserList). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.POST("/workspaces/{workspace}/members"). + To(iam.InviteUser). + Doc("Invite members to a workspace."). + Param(ws.PathParameter("workspace", "workspace name")). + Reads(models.User{}). + Returns(http.StatusOK, ok, errors.Error{}). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.DELETE("/workspaces/{workspace}/members/{username}"). + To(iam.RemoveUser). + Doc("Remove members from workspace."). + Param(ws.PathParameter("workspace", "workspace name")). + Param(ws.PathParameter("name", "username")). + Returns(http.StatusOK, ok, errors.Error{}). + Metadata(restfulspec.KeyOpenAPITags, tags)) + ws.Route(ws.GET("/workspaces/{workspace}/members/{username}"). + To(iam.DescribeWorkspaceUser). + Doc("Describes the specified user."). + Param(ws.PathParameter("workspace", "workspace name")). + Param(ws.PathParameter("username", "username")). + Returns(http.StatusOK, ok, models.User{}). Metadata(restfulspec.KeyOpenAPITags, tags)) c.Add(ws) return nil diff --git a/pkg/apiserver/devops/devops.go b/pkg/apiserver/devops/devops.go index 5245e3529..275635b4f 100644 --- a/pkg/apiserver/devops/devops.go +++ b/pkg/apiserver/devops/devops.go @@ -23,8 +23,11 @@ import ( log "github.com/golang/glog" "kubesphere.io/kubesphere/pkg/models/devops" "net/http" + "strings" ) +const jenkinsHeaderPre = "X-" + func GetPipeline(req *restful.Request, resp *restful.Response) { projectName := req.PathParameter("projectName") pipelineName := req.PathParameter("pipelineName") @@ -104,11 +107,17 @@ func GetBranchStepLog(req *restful.Request, resp *restful.Response) { nodeId := req.PathParameter("nodeId") stepId := req.PathParameter("stepId") - res, err := devops.GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId, req.Request) + res, header, err := devops.GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId, req.Request) + if err != nil { parseErr(err, resp) return } + for k, v := range header { + if strings.HasPrefix(k, jenkinsHeaderPre) { + resp.AddHeader(k, v[0]) + } + } resp.Write(res) } @@ -119,11 +128,16 @@ func GetStepLog(req *restful.Request, resp *restful.Response) { nodeId := req.PathParameter("nodeId") stepId := req.PathParameter("stepId") - res, err := devops.GetStepLog(projectName, pipelineName, runId, nodeId, stepId, req.Request) + res, header, err := devops.GetStepLog(projectName, pipelineName, runId, nodeId, stepId, req.Request) if err != nil { parseErr(err, resp) return } + for k, v := range header { + if strings.HasPrefix(k, jenkinsHeaderPre) { + resp.AddHeader(k, v[0]) + } + } resp.Write(res) } diff --git a/pkg/apiserver/iam/am.go b/pkg/apiserver/iam/am.go index 59175a22a..a86966593 100644 --- a/pkg/apiserver/iam/am.go +++ b/pkg/apiserver/iam/am.go @@ -30,7 +30,7 @@ import ( "kubesphere.io/kubesphere/pkg/models/iam/policy" ) -type roleList struct { +type RoleList struct { ClusterRoles []*v1.ClusterRole `json:"clusterRole" protobuf:"bytes,2,rep,name=clusterRoles"` Roles []*v1.Role `json:"roles" protobuf:"bytes,2,rep,name=roles"` } @@ -132,7 +132,7 @@ func ListUserRoles(req *restful.Request, resp *restful.Response) { return } - roleList := roleList{} + roleList := RoleList{} roleList.Roles = roles roleList.ClusterRoles = clusterRoles diff --git a/pkg/controller/add_clusterrolebinding.go b/pkg/controller/add_clusterrolebinding.go index 81f328438..2fc0def5d 100644 --- a/pkg/controller/add_clusterrolebinding.go +++ b/pkg/controller/add_clusterrolebinding.go @@ -18,7 +18,9 @@ package controller +import "kubesphere.io/kubesphere/pkg/controller/clusterrolebinding" + func init() { // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - //AddToManagerFuncs = append(AddToManagerFuncs, clusterrolebinding.Add) + AddToManagerFuncs = append(AddToManagerFuncs, clusterrolebinding.Add) } diff --git a/pkg/controller/application/application_controller.go b/pkg/controller/application/application_controller.go index bebd16e5e..208f28d85 100644 --- a/pkg/controller/application/application_controller.go +++ b/pkg/controller/application/application_controller.go @@ -149,7 +149,7 @@ func NewApplicationController(serviceInformer coreinformers.ServiceInformer, } func (v *ApplicationController) Start(stopCh <-chan struct{}) error { - v.Run(5, stopCh) + v.Run(2, stopCh) return nil } diff --git a/pkg/controller/destinationrule/destinationrule_controller.go b/pkg/controller/destinationrule/destinationrule_controller.go index 798834b81..3b9f5f588 100644 --- a/pkg/controller/destinationrule/destinationrule_controller.go +++ b/pkg/controller/destinationrule/destinationrule_controller.go @@ -34,6 +34,7 @@ import ( "k8s.io/client-go/util/workqueue" "time" + servicemeshclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned" servicemeshinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh/v1alpha2" servicemeshlisters "kubesphere.io/kubesphere/pkg/client/listers/servicemesh/v1alpha2" ) @@ -53,6 +54,7 @@ type DestinationRuleController struct { client clientset.Interface destinationRuleClient istioclientset.Interface + servicemeshClient servicemeshclient.Interface eventBroadcaster record.EventBroadcaster eventRecorder record.EventRecorder @@ -79,7 +81,8 @@ func NewDestinationRuleController(deploymentInformer informersv1.DeploymentInfor serviceInformer coreinformers.ServiceInformer, servicePolicyInformer servicemeshinformers.ServicePolicyInformer, client clientset.Interface, - destinationRuleClient istioclientset.Interface) *DestinationRuleController { + destinationRuleClient istioclientset.Interface, + servicemeshClient servicemeshclient.Interface) *DestinationRuleController { broadcaster := record.NewBroadcaster() broadcaster.StartLogging(func(format string, args ...interface{}) { @@ -95,6 +98,7 @@ func NewDestinationRuleController(deploymentInformer informersv1.DeploymentInfor v := &DestinationRuleController{ client: client, destinationRuleClient: destinationRuleClient, + servicemeshClient: servicemeshClient, queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "destinationrule"), workerLoopPeriod: time.Second, } @@ -211,12 +215,20 @@ func (v *DestinationRuleController) syncService(key string) error { service, err := v.serviceLister.Services(namespace).Get(name) if err != nil { - // Delete the corresponding destinationrule, as the service has been deleted. + // delete the corresponding destinationrule if there is any, as the service has been deleted. err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Delete(name, nil) - if !errors.IsNotFound(err) { + if err != nil && !errors.IsNotFound(err) { log.Error(err, "delete destination rule failed", "namespace", namespace, "name", name) return err } + + // delete orphan service policy if there is any + err = v.servicemeshClient.ServicemeshV1alpha2().ServicePolicies(namespace).Delete(name, nil) + if err != nil && !errors.IsNotFound(err) { + log.Error(err, "delete orphan service policy failed", "namespace", namespace, "name", name) + return err + } + return nil } @@ -293,6 +305,7 @@ func (v *DestinationRuleController) syncService(key string) error { } dr := currentDestinationRule.DeepCopy() + dr.Spec.TrafficPolicy = nil dr.Spec.Subsets = subsets // if len(servicePolicies) > 0 { @@ -332,9 +345,9 @@ func (v *DestinationRuleController) syncService(key string) error { } if createDestinationRule { - newDestinationRule, err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Create(newDestinationRule) + _, err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Create(newDestinationRule) } else { - newDestinationRule, err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Update(newDestinationRule) + _, err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Update(newDestinationRule) } if err != nil { diff --git a/pkg/controller/namespace/namespace_controller.go b/pkg/controller/namespace/namespace_controller.go index 8e0bee9e5..81917aa44 100644 --- a/pkg/controller/namespace/namespace_controller.go +++ b/pkg/controller/namespace/namespace_controller.go @@ -35,6 +35,8 @@ import ( "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix" "kubesphere.io/kubesphere/pkg/utils/k8sutil" + "kubesphere.io/kubesphere/pkg/utils/sliceutil" + "math" "reflect" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" @@ -44,6 +46,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" "sigs.k8s.io/controller-runtime/pkg/source" + "time" ) const ( @@ -115,25 +118,47 @@ func (r *ReconcileNamespace) Reconcile(request reconcile.Request) (reconcile.Res if errors.IsNotFound(err) { // Object not found, return. Created objects are automatically garbage collected. // For additional cleanup logic use finalizers. + // The object is being deleted + // our finalizer is present, so lets handle our external dependency return reconcile.Result{}, nil } // Error reading the object - requeue the request. return reconcile.Result{}, err } - if !instance.ObjectMeta.DeletionTimestamp.IsZero() { + // name of your custom finalizer + finalizer := "finalizers.kubesphere.io/namespaces" + + if instance.ObjectMeta.DeletionTimestamp.IsZero() { + // The object is not being deleted, so if it does not have our finalizer, + // then lets add the finalizer and update the object. + if !sliceutil.HasString(instance.ObjectMeta.Finalizers, finalizer) { + instance.ObjectMeta.Finalizers = append(instance.ObjectMeta.Finalizers, finalizer) + if err := r.Update(context.Background(), instance); err != nil { + return reconcile.Result{}, err + } + } + } else { // The object is being deleted + if sliceutil.HasString(instance.ObjectMeta.Finalizers, finalizer) { + if err := r.deleteRouter(instance.Name); err != nil { + return reconcile.Result{}, err + } - if err := r.deleteRouter(instance.Name); err != nil { - return reconcile.Result{}, err - } - - if err := r.deleteRuntime(instance); err != nil { - // if fail to delete the external dependency here, return with error - // so that it can be retried - return reconcile.Result{}, err + // delete runtime in the background, retry 3 times + go r.deleteRuntime(instance) + + // remove our finalizer from the list and update it. + instance.ObjectMeta.Finalizers = sliceutil.RemoveString(instance.ObjectMeta.Finalizers, func(item string) bool { + return item == finalizer + }) + + if err := r.Update(context.Background(), instance); err != nil { + return reconcile.Result{}, err + } } + // Our finalizer has finished, so the reconciler can do nothing. return reconcile.Result{}, nil } @@ -347,9 +372,17 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) func (r *ReconcileNamespace) deleteRuntime(namespace *corev1.Namespace) error { if runtimeId := namespace.Annotations[constants.OpenPitrixRuntimeAnnotationKey]; runtimeId != "" { - log.Info("Deleting openpitrix runtime", "namespace", namespace.Name, "runtime", runtimeId) - if err := openpitrix.Client().DeleteRuntime(runtimeId); err != nil { - return err + maxRetries := float64(3) + for i := float64(0); i < maxRetries; i++ { + time.Sleep(time.Duration(i*math.Pow(2, i)) * time.Second) + log.Info("Deleting openpitrix runtime", "namespace", namespace.Name, "runtime", runtimeId) + err := openpitrix.Client().DeleteRuntime(runtimeId) + + if err == nil || openpitrix.IsNotFound(err) || openpitrix.IsDeleted(err) { + return nil + } + + log.Error(err, fmt.Sprintf("Deleteing openpitrix runtime failed: %v times left", maxRetries-i-1)) } } diff --git a/pkg/controller/virtualservice/virtualservice_controller.go b/pkg/controller/virtualservice/virtualservice_controller.go index d3513c22f..ba81de932 100644 --- a/pkg/controller/virtualservice/virtualservice_controller.go +++ b/pkg/controller/virtualservice/virtualservice_controller.go @@ -231,6 +231,14 @@ func (v *VirtualServiceController) syncService(key string) error { log.Error(err, "delete orphan virtualservice failed", "namespace", namespace, "name", service.Name) return err } + + // delete the orphan strategy if there is any + err = v.servicemeshClient.ServicemeshV1alpha2().Strategies(namespace).Delete(name, nil) + if err != nil && !errors.IsNotFound(err) { + log.Error(err, "delete orphan strategy failed", "namespace", namespace, "name", service.Name) + return err + } + return nil } log.Error(err, "get service failed", "namespace", namespace, "name", name) @@ -264,9 +272,7 @@ func (v *VirtualServiceController) syncService(key string) error { subsets := destinationRule.Spec.Subsets if len(subsets) == 0 { // destination rule with no subsets, not possibly - err = fmt.Errorf("found destinationrule with no subsets for service %s", name) - log.Error(err, "found destinationrule with no subsets", "namespace", namespace, "name", appName) - return err + return nil } // fetch all strategies applied to service @@ -387,9 +393,9 @@ func (v *VirtualServiceController) syncService(key string) error { } if createVirtualService { - newVirtualService, err = v.virtualServiceClient.NetworkingV1alpha3().VirtualServices(namespace).Create(newVirtualService) + _, err = v.virtualServiceClient.NetworkingV1alpha3().VirtualServices(namespace).Create(newVirtualService) } else { - newVirtualService, err = v.virtualServiceClient.NetworkingV1alpha3().VirtualServices(namespace).Update(newVirtualService) + _, err = v.virtualServiceClient.NetworkingV1alpha3().VirtualServices(namespace).Update(newVirtualService) } if err != nil { diff --git a/pkg/models/devops/devops.go b/pkg/models/devops/devops.go index f91c5ef10..bad0c3f87 100644 --- a/pkg/models/devops/devops.go +++ b/pkg/models/devops/devops.go @@ -68,10 +68,11 @@ func SearchPipelines(req *http.Request) ([]byte, error) { } func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]byte, error) { - baseUrl := fmt.Sprintf(jenkins.Server+SearchPipelineRunUrl+req.URL.RawQuery, projectName, pipelineName) - log.Infof("Jenkins-url: " + baseUrl) + baseUrl := fmt.Sprintf(jenkins.Server+SearchPipelineRunUrl, projectName, pipelineName) - res, err := sendJenkinsRequest(baseUrl, req) + log.Info("Jenkins-url: " + baseUrl) + + res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req) if err != nil { log.Error(err) return nil, err @@ -82,7 +83,7 @@ func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([] func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -95,7 +96,7 @@ func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, r func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -106,35 +107,36 @@ func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId st return res, err } -func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) { +func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchStepLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) - resBody, err := sendJenkinsRequest(baseUrl, req) + resBody, header, err := jenkinsClient(baseUrl, req) if err != nil { log.Error(err) - return nil, err + return nil, nil, err } - return resBody, err + return resBody, header, err } -func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) { +func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetStepLogUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) - resBody, err := sendJenkinsRequest(baseUrl, req) + resBody, header, err := jenkinsClient(baseUrl, req) if err != nil { log.Error(err) - return nil, err + return nil, nil, err } - return resBody, err + return resBody, header, err + } func Validate(scmId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+ValidateUrl, scmId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) resBody, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -147,7 +149,7 @@ func Validate(scmId string, req *http.Request) ([]byte, error) { func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetSCMOrgUrl+req.URL.RawQuery, scmId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -160,7 +162,7 @@ func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) { func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetOrgRepoUrl+req.URL.RawQuery, scmId, organizationId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -173,7 +175,7 @@ func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error) func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+StopBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -186,7 +188,7 @@ func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+StopPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -199,7 +201,7 @@ func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([ func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+ReplayBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -212,7 +214,7 @@ func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, r func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -225,7 +227,7 @@ func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchRunLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -238,7 +240,7 @@ func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *h func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetRunLogUrl+req.URL.RawQuery, projectName, pipelineName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -251,7 +253,7 @@ func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]by func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -264,7 +266,7 @@ func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -276,10 +278,10 @@ func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([ } func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) { - baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchUrl+req.URL.RawQuery, projectName, pipelineName) - log.Infof("Jenkins-url: " + baseUrl) + baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchUrl, projectName, pipelineName) + log.Info("Jenkins-url: " + baseUrl) - res, err := sendJenkinsRequest(baseUrl, req) + res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req) if err != nil { log.Error(err) return nil, err @@ -290,7 +292,7 @@ func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte, func CheckBranchPipeline(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+CheckBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) resBody, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -303,7 +305,7 @@ func CheckBranchPipeline(projectName, pipelineName, branchName, runId, nodeId, s func CheckPipeline(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+CheckPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) resBody, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -316,7 +318,7 @@ func CheckPipeline(projectName, pipelineName, runId, nodeId, stepId string, req func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetConsoleLogUrl+req.URL.RawQuery, projectName, pipelineName) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) resBody, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -329,7 +331,7 @@ func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+ScanBranchUrl+req.URL.RawQuery, projectName, pipelineName) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) resBody, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -342,7 +344,7 @@ func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, er func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -355,7 +357,7 @@ func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.R func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+RunPipelineUrl+req.URL.RawQuery, projectName, pipelineName) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -368,7 +370,7 @@ func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e func GetBranchStepsStatus(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchStepsStatusUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -381,7 +383,7 @@ func GetBranchStepsStatus(projectName, pipelineName, branchName, runId, nodeId s func GetStepsStatus(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetStepsStatusUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -394,7 +396,7 @@ func GetStepsStatus(projectName, pipelineName, runId, nodeId string, req *http.R func GetCrumb(req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server + GetCrumbUrl) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -407,7 +409,7 @@ func GetCrumb(req *http.Request) ([]byte, error) { func CheckScriptCompile(req *http.Request) ([]byte, error) { baseUrl := jenkins.Server + CheckScriptCompileUrl - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) req.SetBasicAuth(jenkins.Requester.BasicAuth.Username, jenkins.Requester.BasicAuth.Password) resBody, err := sendJenkinsRequest(baseUrl, req) @@ -420,12 +422,19 @@ func CheckScriptCompile(req *http.Request) ([]byte, error) { } func CheckCron(req *http.Request) (*CheckCronRes, error) { - baseUrl := jenkins.Server + CheckCronUrl + req.URL.RawQuery - log.Infof("Jenkins-url: " + baseUrl) - req.SetBasicAuth(jenkins.Requester.BasicAuth.Username, jenkins.Requester.BasicAuth.Password) - var res = new(CheckCronRes) + newurl, err := url.Parse(jenkins.Server + CheckCronUrl + req.URL.RawQuery) - resp, err := http.Get(baseUrl) + reqJenkins := &http.Request{ + Method: http.MethodGet, + URL: newurl, + Header: http.Header{}, + } + var res = new(CheckCronRes) + client := &http.Client{Timeout: 30 * time.Second} + + reqJenkins.SetBasicAuth(jenkins.Requester.BasicAuth.Username, jenkins.Requester.BasicAuth.Password) + + resp, err := client.Do(reqJenkins) if err != nil { log.Error(err) return res, err @@ -446,7 +455,7 @@ func CheckCron(req *http.Request) (*CheckCronRes, error) { func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineRunUrl, projectName, pipelineName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -459,7 +468,7 @@ func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeUrl, projectName, pipelineName, branchName) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -472,7 +481,7 @@ func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.R func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -485,7 +494,7 @@ func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Requ func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -498,7 +507,7 @@ func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId str func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server+GetNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -511,7 +520,7 @@ func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Req func ToJenkinsfile(req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server + ToJenkinsfileUrl) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -524,7 +533,7 @@ func ToJenkinsfile(req *http.Request) ([]byte, error) { func ToJson(req *http.Request) ([]byte, error) { baseUrl := fmt.Sprintf(jenkins.Server + ToJsonUrl) - log.Infof("Jenkins-url: " + baseUrl) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -536,8 +545,8 @@ func ToJson(req *http.Request) ([]byte, error) { } func GetNotifyCommit(req *http.Request) ([]byte, error) { - baseUrl := fmt.Sprintf(jenkins.Server + GetNotifyCommitUrl + req.URL.RawQuery) - log.Infof("Jenkins-url: " + baseUrl) + baseUrl := fmt.Sprint(jenkins.Server, GetNotifyCommitUrl, req.URL.RawQuery) + log.Info("Jenkins-url: " + baseUrl) req.Method = "GET" res, err := sendJenkinsRequest(baseUrl, req) @@ -550,8 +559,8 @@ func GetNotifyCommit(req *http.Request) ([]byte, error) { } func GithubWebhook(req *http.Request) ([]byte, error) { - baseUrl := fmt.Sprintf(jenkins.Server + GithubWebhookUrl + req.URL.RawQuery) - log.Infof("Jenkins-url: " + baseUrl) + baseUrl := fmt.Sprint(jenkins.Server, GithubWebhookUrl, req.URL.RawQuery) + log.Info("Jenkins-url: " + baseUrl) res, err := sendJenkinsRequest(baseUrl, req) if err != nil { @@ -564,7 +573,7 @@ func GithubWebhook(req *http.Request) ([]byte, error) { func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]NodesDetail, error) { getNodesUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) - log.Infof("getNodesUrl: " + getNodesUrl) + log.Info("getNodesUrl: " + getNodesUrl) var wg sync.WaitGroup var nodesDetails []NodesDetail stepChan := make(chan *NodesStepsIndex, channelMaxCapacity) @@ -611,7 +620,7 @@ func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, r func GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]NodesDetail, error) { getNodesUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId) - log.Infof("getNodesUrl: " + getNodesUrl) + log.Info("getNodesUrl: " + getNodesUrl) var wg sync.WaitGroup var nodesDetails []NodesDetail stepChan := make(chan *NodesStepsIndex, channelMaxCapacity) @@ -658,10 +667,15 @@ func GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) // create jenkins request func sendJenkinsRequest(baseUrl string, req *http.Request) ([]byte, error) { + resBody, _, err := jenkinsClient(baseUrl, req) + return resBody, err +} + +func jenkinsClient(baseUrl string, req *http.Request) ([]byte, http.Header, error) { newReqUrl, err := url.Parse(baseUrl) if err != nil { log.Error(err) - return nil, err + return nil, nil, err } client := &http.Client{Timeout: 30 * time.Second} @@ -678,19 +692,22 @@ func sendJenkinsRequest(baseUrl string, req *http.Request) ([]byte, error) { resp, err := client.Do(newRequest) if err != nil { log.Error(err) - return nil, err + return nil, nil, err } - defer resp.Body.Close() resBody, _ := getRespBody(resp) + defer resp.Body.Close() + if resp.StatusCode >= http.StatusBadRequest { + log.Errorf("%+v", string(resBody)) jkerr := new(JkError) jkerr.Code = resp.StatusCode jkerr.Message = http.StatusText(resp.StatusCode) - return nil, jkerr + return nil, nil, jkerr } - return resBody, err + return resBody, resp.Header, nil + } // Decompress response.body of JenkinsAPIResponse diff --git a/pkg/models/devops/json.go b/pkg/models/devops/json.go index 3f746c819..8c14c3313 100644 --- a/pkg/models/devops/json.go +++ b/pkg/models/devops/json.go @@ -19,7 +19,7 @@ package devops // GetPipeline & SearchPipelines type Pipeline struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability." ` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -49,44 +49,44 @@ type Pipeline struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"queue,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - Disabled interface{} `json:"disabled,omitempty"` - DisplayName string `json:"displayName,omitempty"` - FullDisplayName string `json:"fullDisplayName,omitempty"` - FullName string `json:"fullName,omitempty"` - Name string `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Parameters interface{} `json:"parameters,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource."` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions."` + Disabled interface{} `json:"disabled,omitempty" description:"disable or not"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + FullDisplayName string `json:"fullDisplayName,omitempty" description:"full display name"` + FullName string `json:"fullName,omitempty" description:"full name"` + Name string `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization name"` + Parameters interface{} `json:"parameters,omitempty" description:"parameters of pipeline"` Permissions struct { - Create bool `json:"create,omitempty"` - Configure bool `json:"configure,omitempty"` - Read bool `json:"read,omitempty"` - Start bool `json:"start,omitempty"` - Stop bool `json:"stop,omitempty"` - } `json:"permissions,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - NumberOfFolders int `json:"numberOfFolders,omitempty"` - NumberOfPipelines int `json:"numberOfPipelines,omitempty"` - PipelineFolderNames []interface{} `json:"pipelineFolderNames,omitempty"` - WeatherScore int `json:"weatherScore,omitempty"` - BranchNames []string `json:"branchNames,omitempty"` - NumberOfFailingBranches int `json:"numberOfFailingBranches,omitempty"` - NumberOfFailingPullRequests int `json:"numberOfFailingPullRequests,omitempty"` - NumberOfSuccessfulBranches int `json:"numberOfSuccessfulBranches,omitempty"` - NumberOfSuccessfulPullRequests int `json:"numberOfSuccessfulPullRequests,omitempty"` + Create bool `json:"create,omitempty" description:"create action"` + Configure bool `json:"configure,omitempty" description:"configure action"` + Read bool `json:"read,omitempty" description:"read action"` + Start bool `json:"start,omitempty" description:"start action"` + Stop bool `json:"stop,omitempty" description:"stop action"` + } `json:"permissions,omitempty" description:"permissions"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time, unit is millis"` + NumberOfFolders int `json:"numberOfFolders,omitempty" description:"number of folders"` + NumberOfPipelines int `json:"numberOfPipelines,omitempty" description:"number of pipelines"` + PipelineFolderNames []interface{} `json:"pipelineFolderNames,omitempty" description:"pipeline folder names"` + WeatherScore int `json:"weatherScore,omitempty" description:"the score to description the result of pipeline"` + BranchNames []string `json:"branchNames,omitempty" description:"branch names"` + NumberOfFailingBranches int `json:"numberOfFailingBranches,omitempty" description:"number of failing branches"` + NumberOfFailingPullRequests int `json:"numberOfFailingPullRequests,omitempty" description:"number of failing pull requests"` + NumberOfSuccessfulBranches int `json:"numberOfSuccessfulBranches,omitempty" description:"number of successful pull requests"` + NumberOfSuccessfulPullRequests int `json:"numberOfSuccessfulPullRequests,omitempty" description:"number of successful pull requests"` ScmSource struct { - Class string `json:"_class,omitempty"` - APIURL interface{} `json:"apiUrl,omitempty"` - ID string `json:"id,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + APIURL interface{} `json:"apiUrl,omitempty" description:"api url"` + ID string `json:"id,omitempty" description:"scm source id"` } `json:"scmSource,omitempty"` - TotalNumberOfBranches int `json:"totalNumberOfBranches,omitempty"` - TotalNumberOfPullRequests int `json:"totalNumberOfPullRequests,omitempty"` + TotalNumberOfBranches int `json:"totalNumberOfBranches,omitempty" description:"total number of branches"` + TotalNumberOfPullRequests int `json:"totalNumberOfPullRequests,omitempty" description:"total number of pull requests"` } // GetPipeBranchRun & SearchPipelineRuns type BranchPipelineRun struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { PrevRun struct { Class string `json:"_class,omitempty"` @@ -132,45 +132,45 @@ type BranchPipelineRun struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"nextRun,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` - UserID string `json:"userId,omitempty"` - UserName string `json:"userName,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` + UserID string `json:"userId,omitempty" description:"user id"` + UserName string `json:"userName,omitempty" description:"user name"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - EnQueueTime string `json:"enQueueTime,omitempty"` - EndTime string `json:"endTime,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary string `json:"runSummary,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description of resource"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime string `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime string `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization name"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline name"` + Replayable bool `json:"replayable,omitempty" description:"replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary string `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"pipeline run state"` + Type string `json:"type,omitempty" description:"source type"` Branch struct { - IsPrimary bool `json:"isPrimary,omitempty"` - Issues []interface{} `json:"issues,omitempty"` - URL string `json:"url,omitempty"` + IsPrimary bool `json:"isPrimary,omitempty" description:"primary or not"` + Issues []interface{} `json:"issues,omitempty" description:"issues"` + URL string `json:"url,omitempty" description:"url"` } `json:"branch,omitempty"` - CommitID string `json:"commitId,omitempty"` - CommitURL interface{} `json:"commitUrl,omitempty"` - PullRequest interface{} `json:"pullRequest,omitempty"` + CommitID string `json:"commitId,omitempty" description:"commit id"` + CommitURL interface{} `json:"commitUrl,omitempty" description:"commit url "` + PullRequest interface{} `json:"pullRequest,omitempty" description:"pull request"` } // GetBranchPipeRunNodes type BranchPipelineRunNodes struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -184,27 +184,27 @@ type BranchPipelineRunNodes struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"steps,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - DisplayDescription interface{} `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"statue"` + Type string `json:"type,omitempty" description:"source type"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Edges []struct { - Class string `json:"_class,omitempty"` - ID string `json:"id,omitempty"` - Type string `json:"type,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ID string `json:"id,omitempty" description:"id"` + Type string `json:"type,omitempty" description:"source type"` } `json:"edges,omitempty"` - FirstParent interface{} `json:"firstParent,omitempty"` - Restartable bool `json:"restartable,omitempty"` + FirstParent interface{} `json:"firstParent,omitempty" description:"first parent resource"` + Restartable bool `json:"restartable,omitempty" description:"restartable or not"` Steps []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -224,27 +224,27 @@ type BranchPipelineRunNodes struct { } `json:"self,omitempty"` } `json:"_links,omitempty"` URLName string `json:"urlName,omitempty"` - } `json:"actions,omitempty"` - DisplayDescription interface{} `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + } `json:"actions,omitempty" description:"references the reachable path to this resource"` + DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty",description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"source state"` + Type string `json:"type,omitempty" description:"source type"` } `json:"steps,omitempty"` } // Validate type Validates struct { - CredentialID string `json:"credentialId,omitempty"` + CredentialID string `json:"credentialId,omitempty" description:"credential id"` } // GetSCMOrg type SCMOrg struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Repositories struct { Class string `json:"_class,omitempty"` @@ -254,57 +254,57 @@ type SCMOrg struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"self,omitempty"` - } `json:"_links,omitempty"` - Avatar string `json:"avatar,omitempty"` - JenkinsOrganizationPipeline bool `json:"jenkinsOrganizationPipeline,omitempty"` - Name string `json:"name,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Avatar string `json:"avatar,omitempty" description:"avatar url"` + JenkinsOrganizationPipeline bool `json:"jenkinsOrganizationPipeline,omitempty" description:"jenkins organization pipeline"` + Name string `json:"name,omitempty" description:"name "` } // GetOrgRepo type OrgRepo struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"self,omitempty"` - } `json:"_links,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` Repositories struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"self,omitempty"` - } `json:"_links,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` Items []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"self,omitempty"` - } `json:"_links,omitempty"` - DefaultBranch string `json:"defaultBranch,omitempty"` - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + DefaultBranch string `json:"defaultBranch,omitempty" description:"default branch"` + Description string `json:"description,omitempty" description:"description"` + Name string `json:"name,omitempty" description:"name"` Permissions struct { - Admin bool `json:"admin,omitempty"` - Push bool `json:"push,omitempty"` - Pull bool `json:"pull,omitempty"` + Admin bool `json:"admin,omitempty" description:"admin"` + Push bool `json:"push,omitempty" description:"push action"` + Pull bool `json:"pull,omitempty" description:"pull action"` } `json:"permissions,omitempty"` - Private bool `json:"private,omitempty"` - FullName string `json:"fullName,omitempty"` + Private bool `json:"private,omitempty" description:"private"` + FullName string `json:"fullName,omitempty" description:"full name"` } `json:"items,omitempty"` - LastPage interface{} `json:"lastPage,omitempty"` - NextPage interface{} `json:"nextPage,omitempty"` - PageSize int `json:"pageSize,omitempty"` + LastPage interface{} `json:"lastPage,omitempty" description:"last page"` + NextPage interface{} `json:"nextPage,omitempty" description:"next page"` + PageSize int `json:"pageSize,omitempty" description:"page size"` } `json:"repositories,omitempty"` } // StopPipeline type StopPipe struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Parent struct { Class string `json:"_class,omitempty"` @@ -342,43 +342,43 @@ type StopPipe struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"artifacts,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions."` + ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - EnQueueTime string `json:"enQueueTime,omitempty"` - EndTime string `json:"endTime,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary string `json:"runSummary,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime string `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime string `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline"` + Replayable bool `json:"replayable,omitempty" description:"replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary string `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"State"` + Type string `json:"type,omitempty" description:"type"` Branch struct { - IsPrimary bool `json:"isPrimary,omitempty"` - Issues []interface{} `json:"issues,omitempty"` - URL string `json:"url,omitempty"` + IsPrimary bool `json:"isPrimary,omitempty" description:"primary or not"` + Issues []interface{} `json:"issues,omitempty" description:"issues"` + URL string `json:"url,omitempty" description:"url"` } `json:"branch,omitempty"` - CommitID string `json:"commitId,omitempty"` - CommitURL interface{} `json:"commitUrl,omitempty"` - PullRequest interface{} `json:"pullRequest,omitempty"` + CommitID string `json:"commitId,omitempty" description:"commit id"` + CommitURL interface{} `json:"commitUrl,omitempty" description:"commit url"` + PullRequest interface{} `json:"pullRequest,omitempty" description:"pull request"` } // ReplayPipeline type ReplayPipe struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Parent struct { Class string `json:"_class,omitempty"` @@ -408,55 +408,55 @@ type ReplayPipe struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"artifacts,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty"` - CauseOfBlockage string `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions."` + ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage string `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` - UserID string `json:"userId,omitempty"` - UserName string `json:"userName,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` + UserID string `json:"userId,omitempty" description:"user id"` + UserName string `json:"userName,omitempty" description:"user name"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis interface{} `json:"durationInMillis,omitempty"` - EnQueueTime interface{} `json:"enQueueTime,omitempty"` - EndTime interface{} `json:"endTime,omitempty"` - EstimatedDurationInMillis interface{} `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary interface{} `json:"runSummary,omitempty"` - StartTime interface{} `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - QueueID string `json:"queueId,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description"` + DurationInMillis interface{} `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime interface{} `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime interface{} `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis interface{} `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time, unit is millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline"` + Replayable bool `json:"replayable,omitempty" description:"replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary interface{} `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime interface{} `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` + QueueID string `json:"queueId,omitempty" description:"queue id"` } // GetArtifacts type Artifacts struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"self,omitempty"` - } `json:"_links,omitempty"` - Downloadable bool `json:"downloadable,omitempty"` - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Path string `json:"path,omitempty"` - Size int `json:"size,omitempty"` - URL string `json:"url,omitempty"` // The url for Download artifacts + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Downloadable bool `json:"downloadable,omitempty" description:"downloadable or not"` + ID string `json:"id,omitempty" description:"id"` + Name string `json:"name,omitempty" description:"name"` + Path string `json:"path,omitempty" description:"path"` + Size int `json:"size,omitempty" description:"size"` + URL string `json:"url,omitempty" description:"The url for Download artifacts"` } // GetPipeBranch type PipeBranch struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -482,15 +482,15 @@ type PipeBranch struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"queue,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - Disabled bool `json:"disabled,omitempty"` - DisplayName string `json:"displayName,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - FullDisplayName string `json:"fullDisplayName,omitempty"` - FullName string `json:"fullName,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions."` + Disabled bool `json:"disabled,omitempty" description:"disable or not"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time, unit is millis"` + FullDisplayName string `json:"fullDisplayName,omitempty" description:"full display name"` + FullName string `json:"fullName,omitempty" description:"full name"` LatestRun struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { PrevRun struct { Class string `json:"_class,omitempty"` @@ -524,69 +524,69 @@ type PipeBranch struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"artifacts,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile string `json:"artifactsZipFile,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + ArtifactsZipFile string `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - EnQueueTime string `json:"enQueueTime,omitempty"` - EndTime string `json:"endTime,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary string `json:"runSummary,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime string `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime string `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline"` + Replayable bool `json:"replayable,omitempty" description:"replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary string `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime string `json:"startTime,omitempty" description:"start run"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` } `json:"latestRun,omitempty"` - Name string `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` + Name string `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` Parameters []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` DefaultParameterValue struct { - Class string `json:"_class,omitempty"` - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + Name string `json:"name,omitempty" description:"name"` + Value string `json:"value,omitempty" description:"value"` } `json:"defaultParameterValue,omitempty"` - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - Type string `json:"type,omitempty"` + Description string `json:"description,omitempty" description:"description"` + Name string `json:"name,omitempty" description:"name"` + Type string `json:"type,omitempty" description:"type"` } `json:"parameters,omitempty"` Permissions struct { - Create bool `json:"create,omitempty"` - Configure bool `json:"configure,omitempty"` - Read bool `json:"read,omitempty"` - Start bool `json:"start,omitempty"` - Stop bool `json:"stop,omitempty"` + Create bool `json:"create,omitempty" description:"create action"` + Configure bool `json:"configure,omitempty" description:"configure action"` + Read bool `json:"read,omitempty" description:"read action"` + Start bool `json:"start,omitempty" description:"start action"` + Stop bool `json:"stop,omitempty" description:"stop action"` } `json:"permissions,omitempty"` - WeatherScore int `json:"weatherScore,omitempty"` + WeatherScore int `json:"weatherScore,omitempty" description:"the score to description the result of pipeline"` Branch struct { - IsPrimary bool `json:"isPrimary,omitempty"` - Issues []interface{} `json:"issues,omitempty"` - URL string `json:"url,omitempty"` + IsPrimary bool `json:"isPrimary,omitempty" description:"primary or not"` + Issues []interface{} `json:"issues,omitempty" description:"issues"` + URL string `json:"url,omitempty" description:"url"` } `json:"branch,omitempty"` } // RunPipeline type RunPayload struct { Parameters []struct { - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` + Name string `json:"name,omitempty" description:"name"` + Value string `json:"value,omitempty" description:"value"` } `json:"parameters,omitempty"` } type QueuedBlueRun struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Parent struct { Class string `json:"_class,omitempty"` @@ -616,38 +616,38 @@ type QueuedBlueRun struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"artifacts,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty"` - CauseOfBlockage string `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage string `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` - UserID string `json:"userId,omitempty"` - UserName string `json:"userName,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` + UserID string `json:"userId,omitempty" description:"user id"` + UserName string `json:"userName,omitempty" description:"user name"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis interface{} `json:"durationInMillis,omitempty"` - EnQueueTime interface{} `json:"enQueueTime,omitempty"` - EndTime interface{} `json:"endTime,omitempty"` - EstimatedDurationInMillis interface{} `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary interface{} `json:"runSummary,omitempty"` - StartTime interface{} `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - QueueID string `json:"queueId,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description"` + DurationInMillis interface{} `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime interface{} `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime interface{} `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis interface{} `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline"` + Replayable bool `json:"replayable,omitempty" description:"replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary interface{} `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime interface{} `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` + QueueID string `json:"queueId,omitempty" description:"queue id"` } // GetNodeStatus type NodeStatus struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:""` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -661,27 +661,27 @@ type NodeStatus struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"steps,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - DisplayDescription interface{} `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Edges []struct { - Class string `json:"_class,omitempty"` - ID string `json:"id,omitempty"` - Type string `json:"type,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ID string `json:"id,omitempty" description:"id"` + Type string `json:"type,omitempty" description:"type"` } `json:"edges,omitempty"` - FirstParent interface{} `json:"firstParent,omitempty"` - Restartable bool `json:"restartable,omitempty"` + FirstParent interface{} `json:"firstParent,omitempty" description:"first parent"` + Restartable bool `json:"restartable,omitempty" description:"restartable or not"` Steps []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -691,63 +691,63 @@ type NodeStatus struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"actions,omitempty"` - } `json:"_links,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` Actions []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"references the reachable path to this resource"` Links struct { Self struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` - } `json:"self,omitempty"` - } `json:"_links,omitempty"` - URLName string `json:"urlName,omitempty"` + } `json:"self,omitempty" description:""` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + URLName string `json:"urlName,omitempty" description:"url name"` } `json:"actions,omitempty"` - DisplayDescription interface{} `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` } `json:"steps,omitempty"` } // CheckPipeline type CheckPlayload struct { - ID string `json:"id,omitempty"` + ID string `json:"id,omitempty" description:"id"` Parameters []struct { - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` + Name string `json:"name,omitempty" description:"name"` + Value string `json:"value,omitempty" description:"value"` } `json:"parameters,omitempty"` - Abort bool `json:"abort,omitempty"` + Abort bool `json:"abort,omitempty" description:"abort or not"` } // Getcrumb type Crumb struct { - Class string `json:"_class,omitempty"` - Crumb string `json:"crumb,omitempty"` - CrumbRequestField string `json:"crumbRequestField,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + Crumb string `json:"crumb,omitempty" description:"crumb data"` + CrumbRequestField string `json:"crumbRequestField,omitempty" description:"crumb request field"` } // CheckScriptCompile type CheckScript struct { - Column int `json:"column,omitempty"` - Line int `json:"line,omitempty"` - Message string `json:"message,omitempty"` - Status string `json:"status,omitempty"` + Column int `json:"column,omitempty" description:"column"` + Line int `json:"line,omitempty" description:"line"` + Message string `json:"message,omitempty" description:"message"` + Status string `json:"status,omitempty" description:"statue"` } // CheckCron type CheckCronRes struct { - Result string `json:"result,omitempty"` - Message string `json:"message,omitempty"` + Result string `json:"result,omitempty" description:"result"` + Message string `json:"message,omitempty" description:"message"` } // GetPipelineRun type PipelineRun struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { PrevRun struct { Class string `json:"_class,omitempty"` @@ -789,41 +789,41 @@ type PipelineRun struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"artifacts,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + ArtifactsZipFile interface{} `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` - UserID string `json:"userId,omitempty"` - UserName string `json:"userName,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` + UserID string `json:"userId,omitempty" description:"user id"` + UserName string `json:"userName,omitempty" description:"user name"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - EnQueueTime string `json:"enQueueTime,omitempty"` - EndTime string `json:"endTime,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary string `json:"runSummary,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - Branch interface{} `json:"branch,omitempty"` - CommitID interface{} `json:"commitId,omitempty"` - CommitURL interface{} `json:"commitUrl,omitempty"` - PullRequest interface{} `json:"pullRequest,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime string `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime string `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline"` + Replayable bool `json:"replayable,omitempty" description:"replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary string `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` + Branch interface{} `json:"branch,omitempty" description:"branch"` + CommitID interface{} `json:"commitId,omitempty" description:"commit id"` + CommitURL interface{} `json:"commitUrl,omitempty" description:"commit url"` + PullRequest interface{} `json:"pullRequest,omitempty" description:"pull request"` } // GetBranchPipeRun type BranchPipeline struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -849,15 +849,15 @@ type BranchPipeline struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"queue,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - Disabled bool `json:"disabled,omitempty"` - DisplayName string `json:"displayName,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - FullDisplayName string `json:"fullDisplayName,omitempty"` - FullName string `json:"fullName,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + Disabled bool `json:"disabled,omitempty" description:"disable or not"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + FullDisplayName string `json:"fullDisplayName,omitempty" description:"full display name"` + FullName string `json:"fullName,omitempty" description:"full name"` LatestRun struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { PrevRun struct { Class string `json:"_class,omitempty"` @@ -891,64 +891,64 @@ type BranchPipeline struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"artifacts,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - ArtifactsZipFile string `json:"artifactsZipFile,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + ArtifactsZipFile string `json:"artifactsZipFile,omitempty" description:"the artifacts zip file"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Causes []struct { - Class string `json:"_class,omitempty"` - ShortDescription string `json:"shortDescription,omitempty"` - UserID string `json:"userId,omitempty"` - UserName string `json:"userName,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ShortDescription string `json:"shortDescription,omitempty" description:"short description"` + UserID string `json:"userId,omitempty" description:"user id"` + UserName string `json:"userName,omitempty" description:"user name"` } `json:"causes,omitempty"` - ChangeSet []interface{} `json:"changeSet,omitempty"` - Description interface{} `json:"description,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - EnQueueTime string `json:"enQueueTime,omitempty"` - EndTime string `json:"endTime,omitempty"` - EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Name interface{} `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` - Pipeline string `json:"pipeline,omitempty"` - Replayable bool `json:"replayable,omitempty"` - Result string `json:"result,omitempty"` - RunSummary string `json:"runSummary,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + ChangeSet []interface{} `json:"changeSet,omitempty" description:"change set"` + Description interface{} `json:"description,omitempty" description:"description"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + EnQueueTime string `json:"enQueueTime,omitempty" description:"enqueue time"` + EndTime string `json:"endTime,omitempty" description:"end time"` + EstimatedDurationInMillis int `json:"estimatedDurationInMillis,omitempty" description:"estimated duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Name interface{} `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` + Pipeline string `json:"pipeline,omitempty" description:"pipeline"` + Replayable bool `json:"replayable,omitempty" description:"Replayable or not"` + Result string `json:"result,omitempty" description:"result"` + RunSummary string `json:"runSummary,omitempty" description:"pipeline run summary"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` } `json:"latestRun,omitempty"` - Name string `json:"name,omitempty"` - Organization string `json:"organization,omitempty"` + Name string `json:"name,omitempty" description:"name"` + Organization string `json:"organization,omitempty" description:"organization"` Parameters []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` DefaultParameterValue struct { - Class string `json:"_class,omitempty"` - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` - } `json:"defaultParameterValue,omitempty"` - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - Type string `json:"type,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + Name string `json:"name,omitempty" description:"name"` + Value string `json:"value,omitempty" description:"value"` + } `json:"defaultParameterValue,omitempty" description:""` + Description string `json:"description,omitempty" description:"description"` + Name string `json:"name,omitempty" description:"name"` + Type string `json:"type,omitempty" description:"type"` } `json:"parameters,omitempty"` Permissions struct { - Create bool `json:"create,omitempty"` - Configure bool `json:"configure,omitempty"` - Read bool `json:"read,omitempty"` - Start bool `json:"start,omitempty"` - Stop bool `json:"stop,omitempty"` + Create bool `json:"create,omitempty" description:"create action"` + Configure bool `json:"configure,omitempty" description:"configure action"` + Read bool `json:"read,omitempty" description:"read action"` + Start bool `json:"start,omitempty" description:"start action"` + Stop bool `json:"stop,omitempty" description:"stop action"` } `json:"permissions,omitempty"` - WeatherScore int `json:"weatherScore,omitempty"` + WeatherScore int `json:"weatherScore,omitempty" description:"the score to description the result of pipeline"` Branch struct { - IsPrimary bool `json:"isPrimary,omitempty"` - Issues []interface{} `json:"issues,omitempty"` - URL string `json:"url,omitempty"` + IsPrimary bool `json:"isPrimary,omitempty" description:"primary or not"` + Issues []interface{} `json:"issues,omitempty" description:"issues"` + URL string `json:"url,omitempty" description:"url"` } `json:"branch,omitempty"` } // GetPipelineRunNodes type PipelineRunNodes struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -962,26 +962,26 @@ type PipelineRunNodes struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"steps,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - DisplayDescription interface{} `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` - Edges []interface{} `json:"edges,omitempty"` - FirstParent interface{} `json:"firstParent,omitempty"` - Restartable bool `json:"restartable,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in mullis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause 0f blockage"` + Edges []interface{} `json:"edges,omitempty" description:"edges"` + FirstParent interface{} `json:"firstParent,omitempty" description:"first parent"` + Restartable bool `json:"restartable,omitempty" description:"restartable or not"` } // GetNodeSteps type NodeSteps struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -991,69 +991,69 @@ type NodeSteps struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"actions,omitempty"` - } `json:"_links,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` Actions []struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"self,omitempty"` - } `json:"_links,omitempty"` - URLName string `json:"urlName,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + URLName string `json:"urlName,omitempty" description:"url name"` } `json:"actions,omitempty"` - DisplayDescription string `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` + DisplayDescription string `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in mullis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start times"` + State string `json:"state,omitempty" description:"state"` + Type string `json:"type,omitempty" description:"type"` } // CheckScriptCompile type ReqScript struct { - Value string `json:"value,omitempty"` + Value string `json:"value,omitempty" description:"check value"` } // ToJenkinsfile requests type ReqJson struct { - Json string `json:"json,omitempty"` + Json string `json:"json,omitempty" description:"json data"` } // ToJenkinsfile response type ResJenkinsfile struct { - Status string `json:"status,omitempty"` + Status string `json:"status,omitempty" description:"status"` Data struct { - Result string `json:"result,omitempty"` - Jenkinsfile string `json:"jenkinsfile,omitempty"` + Result string `json:"result,omitempty" description:"result"` + Jenkinsfile string `json:"jenkinsfile,omitempty" description:"jenkinsfile"` Errors []struct { - Location []string `json:"location,omitempty"` - Error string `json:"error,omitempty"` + Location []string `json:"location,omitempty" description:"err location"` + Error string `json:"error,omitempty" description:"error message"` } `json:"errors,omitempty"` } `json:"data,omitempty"` } type ReqJenkinsfile struct { - Jenkinsfile string `json:"jenkinsfile,omitempty"` + Jenkinsfile string `json:"jenkinsfile,omitempty" description:"jenkinsfile"` } type ResJson struct { - Status string `json:"status,omitempty"` + Status string `json:"status,omitempty" description:"status"` Data struct { - Result string `json:"result,omitempty"` + Result string `json:"result,omitempty" description:"result"` JSON struct { Pipeline struct { - Stages []interface{} `json:"stages,omitempty"` + Stages []interface{} `json:"stages,omitempty" description:"stages"` Agent struct { - Type string `json:"type,omitempty"` + Type string `json:"type,omitempty" description:"type"` Arguments []struct { - Key string `json:"key,omitempty"` + Key string `json:"key,omitempty" description:"key"` Value struct { - IsLiteral bool `json:"isLiteral,omitempty"` - Value string `json:"value,omitempty"` + IsLiteral bool `json:"isLiteral,omitempty" description:"is literal or not"` + Value string `json:"value,omitempty" description:"value"` } `json:"value,omitempty"` } `json:"arguments,omitempty"` } `json:"agent,omitempty"` @@ -1063,7 +1063,7 @@ type ResJson struct { } type NodesDetail struct { - Class string `json:"_class,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` Links struct { Self struct { Class string `json:"_class,omitempty"` @@ -1077,29 +1077,29 @@ type NodesDetail struct { Class string `json:"_class,omitempty"` Href string `json:"href,omitempty"` } `json:"steps,omitempty"` - } `json:"_links,omitempty"` - Actions []interface{} `json:"actions,omitempty"` - DisplayDescription interface{} `json:"displayDescription,omitempty"` - DisplayName string `json:"displayName,omitempty"` - DurationInMillis int `json:"durationInMillis,omitempty"` - ID string `json:"id,omitempty"` - Input interface{} `json:"input,omitempty"` - Result string `json:"result,omitempty"` - StartTime string `json:"startTime,omitempty"` - State string `json:"state,omitempty"` - Type string `json:"type,omitempty"` - CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty"` + } `json:"_links,omitempty" description:"references the reachable path to this resource"` + Actions []interface{} `json:"actions,omitempty" description:"the list of actions"` + DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"` + DisplayName string `json:"displayName,omitempty" description:"display name"` + DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"` + ID string `json:"id,omitempty" description:"id"` + Input interface{} `json:"input,omitempty" description:"input"` + Result string `json:"result,omitempty" description:"result"` + StartTime string `json:"startTime,omitempty" description:"start time"` + State string `json:"state,omitempty" description:"statue"` + Type string `json:"type,omitempty" description:"type"` + CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"cause of blockage"` Edges []struct { - Class string `json:"_class,omitempty"` - ID string `json:"id,omitempty"` - Type string `json:"type,omitempty"` + Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."` + ID string `json:"id,omitempty" description:"id"` + Type string `json:"type,omitempty" description:"type"` } `json:"edges,omitempty"` - FirstParent interface{} `json:"firstParent,omitempty"` - Restartable bool `json:"restartable,omitempty"` - Steps []NodeSteps `json:"steps,omitempty"` + FirstParent interface{} `json:"firstParent,omitempty" description:"first parent"` + Restartable bool `json:"restartable,omitempty" description:"restartable or not"` + Steps []NodeSteps `json:"steps,omitempty" description:"steps"` } type NodesStepsIndex struct { - Id int `json:"id,omitempty"` - Steps []NodeSteps `json:"steps,omitempty"` + Id int `json:"id,omitempty" description:"id"` + Steps []NodeSteps `json:"steps,omitempty" description:"steps"` } diff --git a/pkg/models/devops/urlconfig.go b/pkg/models/devops/urlconfig.go index a6df50c5f..05a9355eb 100644 --- a/pkg/models/devops/urlconfig.go +++ b/pkg/models/devops/urlconfig.go @@ -19,43 +19,45 @@ package devops // Some apis for Jenkins. const ( - GetPipeBranchUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/?" + GetPipeBranchUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/?" GetBranchPipeUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/" - GetPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/" + GetPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/" SearchPipelineUrl = "/blue/rest/search/?" - RunBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/" - RunPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/" - GetPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/" - GetPipeBranchRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/" - SearchPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/?" - GetBranchPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/nodes/?" - GetPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/nodes/?" - GetBranchRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/log/?" - GetRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/log/?" - GetBranchStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/nodes/%s/steps/%s/log/?" - GetStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/nodes/%s/steps/%s/log/?" + RunBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/" + RunPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/" + GetPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/" + GetPipeBranchRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/" + SearchPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/?" + GetBranchPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/?" + GetPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/?" + GetBranchRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/log/?" + GetRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/log/?" + GetBranchStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/log/?" + GetStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/log/?" StopBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/stop/?" StopPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/stop/?" ReplayBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/replay/" ReplayPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/replay/" - GetBranchArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/artifacts/?" - GetArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/artifacts/?" - GetBranchStepsStatusUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/nodes/%s/steps/?" - GetStepsStatusUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/nodes/%s/steps/?" - CheckBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/" - CheckPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/" - GetBranchNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/nodes/%s/steps/?" - GetNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/nodes/%s/steps/?" - ValidateUrl = "/blue/rest/organizations/jenkins/scm/%s/validate" - GetSCMOrgUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/?" - GetOrgRepoUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/%s/repositories/?" - GetConsoleLogUrl = "/job/%s/job/%s/indexing/consoleText" - ScanBranchUrl = "/job/%s/job/%s/build?" - GetCrumbUrl = "/crumbIssuer/api/json/" - CheckScriptCompileUrl = "/job/init-job/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile" - CheckCronUrl = "/job/init-job/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?" - ToJenkinsfileUrl = "/pipeline-model-converter/toJenkinsfile" - ToJsonUrl = "/pipeline-model-converter/toJson" - GetNotifyCommitUrl = "/git/notifyCommit/?" - GithubWebhookUrl = "/github-webhook/" + GetBranchArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/artifacts/?" + GetArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/artifacts/?" + GetBranchStepsStatusUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/?" + + GetStepsStatusUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/?" + + CheckBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/" + CheckPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/" + GetBranchNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/?" + GetNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/?" + ValidateUrl = "/blue/rest/organizations/jenkins/scm/%s/validate" + GetSCMOrgUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/?" + GetOrgRepoUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/%s/repositories/?" + GetConsoleLogUrl = "/job/%s/job/%s/indexing/consoleText" + ScanBranchUrl = "/job/%s/job/%s/build?" + GetCrumbUrl = "/crumbIssuer/api/json/" + CheckScriptCompileUrl = "/job/init-job/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile" + CheckCronUrl = "/job/init-job/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?" + ToJenkinsfileUrl = "/pipeline-model-converter/toJenkinsfile" + ToJsonUrl = "/pipeline-model-converter/toJson" + GetNotifyCommitUrl = "/git/notifyCommit/?" + GithubWebhookUrl = "/github-webhook/" ) diff --git a/pkg/models/iam/im.go b/pkg/models/iam/im.go index ea8757214..0ab9cae4e 100644 --- a/pkg/models/iam/im.go +++ b/pkg/models/iam/im.go @@ -284,7 +284,7 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi defer conn.Close() - pageControl := ldap.NewControlPaging(80) + pageControl := ldap.NewControlPaging(1000) users := make([]models.User, 0) diff --git a/pkg/models/iam/policy/policy.go b/pkg/models/iam/policy/policy.go index 109bb6f23..bce92c8f6 100644 --- a/pkg/models/iam/policy/policy.go +++ b/pkg/models/iam/policy/policy.go @@ -905,7 +905,7 @@ var ( Rules: []v1.PolicyRule{ { Verbs: []string{"get", "list"}, - APIGroups: []string{"resources.kubesphere.io"}, + APIGroups: []string{"resources.kubesphere.io", "app.k8s.io"}, Resources: []string{"applications"}, }, { Verbs: []string{"get", "list"}, @@ -927,7 +927,7 @@ var ( Rules: []v1.PolicyRule{ { Verbs: []string{"create", "update", "patch"}, - APIGroups: []string{"resources.kubesphere.io"}, + APIGroups: []string{"resources.kubesphere.io", "app.k8s.io"}, Resources: []string{"applications"}, }, { Verbs: []string{"create", "update", "patch"}, @@ -940,7 +940,7 @@ var ( Rules: []v1.PolicyRule{ { Verbs: []string{"delete"}, - APIGroups: []string{"resources.kubesphere.io"}, + APIGroups: []string{"resources.kubesphere.io", "app.k8s.io"}, Resources: []string{"applications"}, }, { diff --git a/pkg/models/metrics/metricsruleconst.go b/pkg/models/metrics/metricsruleconst.go index e3d103a4d..449d2f2bc 100644 --- a/pkg/models/metrics/metricsruleconst.go +++ b/pkg/models/metrics/metricsruleconst.go @@ -400,10 +400,10 @@ var RulePromQLTmplMap = MetricMap{ "cluster_disk_read_throughput": "sum(node:data_volume_throughput_bytes_read:sum)", "cluster_disk_write_throughput": "sum(node:data_volume_throughput_bytes_written:sum)", - "cluster_disk_size_usage": `sum(max((node_filesystem_size_bytes{device=~"/dev/.+", job="node-exporter"} - node_filesystem_avail_bytes{device=~"/dev/.+", job="node-exporter"}) * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:) by (node))`, + "cluster_disk_size_usage": `sum(max(node_filesystem_size_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"} - node_filesystem_avail_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"}) by (device, instance))`, "cluster_disk_size_utilisation": `cluster:disk_utilization:ratio`, - "cluster_disk_size_capacity": `sum(max(node_filesystem_size_bytes{device=~"/dev/.+", job="node-exporter"} * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:) by (node))`, - "cluster_disk_size_available": `sum(max(node_filesystem_avail_bytes{device=~"/dev/.+", job="node-exporter"} * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:) by (node))`, + "cluster_disk_size_capacity": `sum(max(node_filesystem_size_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"}) by (device, instance))`, + "cluster_disk_size_available": `sum(max(node_filesystem_avail_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"}) by (device, instance))`, "cluster_disk_inode_total": `sum(node:node_inodes_total:)`, "cluster_disk_inode_usage": `sum(node:node_inodes_total:) - sum(node:node_inodes_free:)`, @@ -481,9 +481,9 @@ var RulePromQLTmplMap = MetricMap{ "node_disk_read_throughput": "node:data_volume_throughput_bytes_read:sum", "node_disk_write_throughput": "node:data_volume_throughput_bytes_written:sum", - "node_disk_size_capacity": `max(node_filesystem_size_bytes{device=~"/dev/.+", job="node-exporter"} * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:$1) by (node)`, + "node_disk_size_capacity": `sum(max(node_filesystem_size_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"} * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:$1) by (device, node)) by (node)`, "node_disk_size_available": `node:disk_space_available:$1`, - "node_disk_size_usage": `max((node_filesystem_size_bytes{device=~"/dev/.+", job="node-exporter"} - node_filesystem_avail_bytes{device=~"/dev/.+", job="node-exporter"}) * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:$1) by (node)`, + "node_disk_size_usage": `sum(max((node_filesystem_size_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"} - node_filesystem_avail_bytes{device=~"/dev/[vsh]d.+", job="node-exporter"}) * on (namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:$1) by (device, node)) by (node)`, "node_disk_size_utilisation": `node:disk_space_utilization:ratio$1`, "node_disk_inode_total": `node:node_inodes_total:$1`, diff --git a/pkg/models/routers/routers.go b/pkg/models/routers/routers.go index 2c93ef139..4cf156170 100644 --- a/pkg/models/routers/routers.go +++ b/pkg/models/routers/routers.go @@ -112,6 +112,10 @@ func getMasterNodeIp() string { func addLoadBalancerIp(service *corev1.Service) { + if service == nil { + return + } + // append selected node ip as loadbalancer ingress ip if service.Spec.Type != corev1.ServiceTypeLoadBalancer && len(service.Status.LoadBalancer.Ingress) == 0 { rip := getMasterNodeIp() diff --git a/pkg/simple/client/elasticsearch/esclient.go b/pkg/simple/client/elasticsearch/esclient.go index 896b1a2da..0e44fbac5 100644 --- a/pkg/simple/client/elasticsearch/esclient.go +++ b/pkg/simple/client/elasticsearch/esclient.go @@ -137,12 +137,9 @@ type ContainerHighLightField struct { type EmptyField struct { } -// The aggs object holds two aggregations to be computed by Elasticsearch -// ContainterAgg is a cardinality aggregation to calculate the count of distinct containers -// StartTimeAgg is a top hits aggregation to retrieve the first record +// StatisticsAggs, the struct for `aggs` of type Request, holds a cardinality aggregation for distinct container counting type StatisticsAggs struct { ContainerAgg ContainerAgg `json:"containers"` - StartTimeAgg StartTimeAgg `json:"starttime"` } type ContainerAgg struct { @@ -153,23 +150,6 @@ type AggField struct { Field string `json:"field"` } -type StartTimeAgg struct { - TopHits TopHits `json:"top_hits"` -} - -type TopHits struct { - Sort []TopHitsSort `json:"sort"` - Size int `json:"size"` -} - -type TopHitsSort struct { - Order TopHitsSortOrder `json:"time"` -} - -type TopHitsSortOrder struct { - Type string `json:"order"` -} - type HistogramAggs struct { HistogramAgg HistogramAgg `json:"histogram"` } @@ -263,8 +243,7 @@ func createQueryRequest(param QueryParameters) (int, []byte, error) { if param.Operation == "statistics" { operation = OperationStatistics containerAgg := AggField{"kubernetes.docker_id.keyword"} - startTimeAgg := TopHits{[]TopHitsSort{{TopHitsSortOrder{"asc"}}}, 1} - statisticAggs := StatisticsAggs{ContainerAgg{containerAgg}, StartTimeAgg{startTimeAgg}} + statisticAggs := StatisticsAggs{ContainerAgg{containerAgg}} request.Aggs = statisticAggs request.Size = 0 } else if param.Operation == "histogram" { @@ -369,20 +348,15 @@ type ReadResult struct { Records []LogRecord `json:"records,omitempty"` } -// The aggregations object represents the return from an aggregation (see StatisticsAggs type) +// StatisticsResponseAggregations, the struct for `aggregations` of type Reponse, holds return results from the aggregation StatisticsAggs type StatisticsResponseAggregations struct { - ContainerCount ContainerCount `json:"containers"` - StartTime StartTimeTopHit `json:"starttime"` + ContainerCount ContainerCount `json:"containers"` } type ContainerCount struct { Value int64 `json:"value"` } -type StartTimeTopHit struct { - Hits Hits `json:"hits"` -} - type HistogramAggregations struct { HistogramAggregation HistogramAggregation `json:"histogram"` } @@ -404,7 +378,6 @@ type HistogramRecord struct { type StatisticsResult struct { Containers int64 `json:"containers"` Logs int64 `json:"logs"` - StartTime int64 `json:"starttime"` } type HistogramResult struct { @@ -468,13 +441,14 @@ func parseQueryResult(operation int, param QueryParameters, body []byte, query [ if response.Status != 0 { //Elastic error, eg, es_rejected_execute_exception queryResult.Status = response.Status + glog.Errorln("The query failed with no response") return &queryResult } if response.Shards.Successful != response.Shards.Total { //Elastic some shards error - queryResult.Status = http.StatusInternalServerError - return &queryResult + glog.Warningf("Not all shards succeed, successful shards: %d, skipped shards: %d, failed shards: %d", + response.Shards.Successful, response.Shards.Skipped, response.Shards.Failed) } switch operation { @@ -504,8 +478,7 @@ func parseQueryResult(operation int, param QueryParameters, body []byte, query [ queryResult.Status = http.StatusInternalServerError return &queryResult } - queryResult.Statistics = &StatisticsResult{Containers: statisticsResponse.ContainerCount.Value, - Logs: statisticsResponse.StartTime.Hits.Total, StartTime: statisticsResponse.StartTime.Hits.Hits[0].Sort[0]} + queryResult.Statistics = &StatisticsResult{Containers: statisticsResponse.ContainerCount.Value, Logs: response.Hits.Total} case OperationHistogram: var histogramResult HistogramResult @@ -574,14 +547,10 @@ func stubResult() *QueryResult { func Query(param QueryParameters) *QueryResult { var queryResult *QueryResult - //queryResult = stubResult() - //return queryResult - client := &http.Client{} operation, query, err := createQueryRequest(param) if err != nil { - //fmt.Println("Create query error ", err.Error()) queryResult = new(QueryResult) queryResult.Status = http.StatusNotFound return queryResult @@ -595,6 +564,7 @@ func Query(param QueryParameters) *QueryResult { } url := fmt.Sprintf("http://%s:%s/%s*/_search", es.Host, es.Port, es.Index) + request, err := http.NewRequest("GET", url, bytes.NewBuffer(query)) if err != nil { glog.Errorln(err) diff --git a/pkg/simple/client/kubesphere/kubesphereclient.go b/pkg/simple/client/kubesphere/kubesphereclient.go index e5e6c9867..f116f3201 100644 --- a/pkg/simple/client/kubesphere/kubesphereclient.go +++ b/pkg/simple/client/kubesphere/kubesphereclient.go @@ -27,7 +27,6 @@ import ( "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models/devops" - "log" "net/http" "strings" "sync" @@ -84,20 +83,22 @@ func (c client) CreateGroup(group *models.Group) (*models.Group, error) { req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/kapis/iam.kubesphere.io/v1alpha2/groups", accountAPIServer), bytes.NewReader(data)) if err != nil { + glog.Error(err) return nil, err } req.Header.Add("Content-Type", "application/json") - log.Println(req.Method, req.URL, string(data)) resp, err := c.client.Do(req) if err != nil { + glog.Error(err) return nil, err } defer resp.Body.Close() data, err = ioutil.ReadAll(resp.Body) if err != nil { + glog.Error(err) return nil, err } @@ -108,6 +109,7 @@ func (c client) CreateGroup(group *models.Group) (*models.Group, error) { err = json.Unmarshal(data, group) if err != nil { + glog.Error(err) return nil, err } @@ -118,20 +120,18 @@ func (c client) UpdateGroup(group *models.Group) (*models.Group, error) { data, err := json.Marshal(group) if err != nil { + glog.Error(err) return nil, err } req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/kapis/iam.kubesphere.io/v1alpha2/groups/%s", accountAPIServer, group.Name), bytes.NewReader(data)) if err != nil { + glog.Error(err) return nil, err } req.Header.Add("Content-Type", "application/json") - if err != nil { - return nil, err - } - log.Println(req.Method, req.URL, string(data)) resp, err := c.client.Do(req) if err != nil { @@ -141,6 +141,7 @@ func (c client) UpdateGroup(group *models.Group) (*models.Group, error) { data, err = ioutil.ReadAll(resp.Body) if err != nil { + glog.Error(err) return nil, err } @@ -151,6 +152,7 @@ func (c client) UpdateGroup(group *models.Group) (*models.Group, error) { err = json.Unmarshal(data, group) if err != nil { + glog.Error(err) return nil, err } @@ -161,19 +163,21 @@ func (c client) DeleteGroup(name string) error { req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/kapis/iam.kubesphere.io/v1alpha2/groups/%s", accountAPIServer, name), nil) if err != nil { + glog.Error(err) return err } - log.Println(req.Method, req.URL) resp, err := c.client.Do(req) if err != nil { + glog.Error(err) return err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { + glog.Error(err) return err } @@ -188,18 +192,20 @@ func (c client) DescribeGroup(name string) (*models.Group, error) { req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/kapis/iam.kubesphere.io/v1alpha2/groups/%s", accountAPIServer, name), nil) if err != nil { + glog.Error(err) return nil, err } - log.Println(req.Method, req.URL) resp, err := c.client.Do(req) if err != nil { + glog.Error(err) return nil, err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { + glog.Error(err) return nil, err } @@ -211,6 +217,7 @@ func (c client) DescribeGroup(name string) (*models.Group, error) { err = json.Unmarshal(data, &group) if err != nil { + glog.Error(err) return nil, err } @@ -224,19 +231,17 @@ func (c client) ListUsers() (*models.PageableResponse, error) { return nil, err } req.Header.Add("Authorization", accountAPIServer) - if err != nil { - return nil, err - } - log.Println(req.Method, req.URL) resp, err := c.client.Do(req) if err != nil { + glog.Error(err) return nil, err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { + glog.Error(err) return nil, err } @@ -248,6 +253,7 @@ func (c client) ListUsers() (*models.PageableResponse, error) { err = json.Unmarshal(data, &result) if err != nil { + glog.Error(err) return nil, err } diff --git a/pkg/simple/client/openpitrix/openpitrixclient.go b/pkg/simple/client/openpitrix/openpitrixclient.go index 6d97b3df0..5456f22de 100644 --- a/pkg/simple/client/openpitrix/openpitrixclient.go +++ b/pkg/simple/client/openpitrix/openpitrixclient.go @@ -22,9 +22,11 @@ import ( "encoding/json" "flag" "fmt" + "github.com/golang/glog" "io/ioutil" - "log" + "kubesphere.io/kubesphere/pkg/utils/sliceutil" "net/http" + "strings" "sync" ) @@ -48,6 +50,10 @@ type Interface interface { CreateRuntime(runtime *RunTime) error DeleteRuntime(runtimeId string) error } +type cluster struct { + Status string `json:"status"` + ClusterId string `json:"cluster_id"` +} type Error struct { status int @@ -89,54 +95,174 @@ func (c client) CreateRuntime(runtime *RunTime) error { req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", openpitrixProxyToken) - log.Println(req.Method, req.URL, openpitrixProxyToken, string(data)) resp, err := c.client.Do(req) if err != nil { + glog.Error(err) return err } defer resp.Body.Close() data, err = ioutil.ReadAll(resp.Body) if err != nil { + glog.Error(err) return err } if resp.StatusCode > http.StatusOK { - return Error{resp.StatusCode, string(data)} + err = Error{resp.StatusCode, string(data)} + glog.Error(err) + return err } return nil } +func (c client) deleteClusters(clusters []cluster) error { + clusterId := make([]string, 0) + + for _, cluster := range clusters { + if cluster.Status != "deleted" && cluster.Status != "deleting" && !sliceutil.HasString(clusterId, cluster.ClusterId) { + clusterId = append(clusterId, cluster.ClusterId) + } + } + + if len(clusterId) == 0 { + return nil + } + + deleteRequest := struct { + ClusterId []string `json:"cluster_id"` + }{ + ClusterId: clusterId, + } + data, _ := json.Marshal(deleteRequest) + req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/clusters/delete", openpitrixAPIServer), bytes.NewReader(data)) + + if err != nil { + return err + } + req.Header.Add("Authorization", openpitrixProxyToken) + + resp, err := c.client.Do(req) + if err != nil { + glog.Error(err) + return err + } + + defer resp.Body.Close() + data, err = ioutil.ReadAll(resp.Body) + + if err != nil { + glog.Error(err) + return err + } + + if resp.StatusCode > http.StatusOK { + err = Error{resp.StatusCode, string(data)} + glog.Error(err) + return err + } + + return nil +} + +func (c client) listClusters(runtimeId string) ([]cluster, error) { + limit := 200 + offset := 0 + clusters := make([]cluster, 0) + for { + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v1/clusters?runtime_id=%s&limit=%d&offset=%d", openpitrixAPIServer, runtimeId, limit, offset), nil) + + if err != nil { + glog.Error(err) + return nil, err + } + + req.Header.Add("Authorization", openpitrixProxyToken) + + resp, err := c.client.Do(req) + + if err != nil { + glog.Error(err) + return nil, err + } + + data, err := ioutil.ReadAll(resp.Body) + + if err != nil { + glog.Error(err) + return nil, err + } + + resp.Body.Close() + + if resp.StatusCode > http.StatusOK { + err = Error{resp.StatusCode, string(data)} + glog.Error(err) + return nil, err + } + listClusterResponse := struct { + TotalCount int `json:"total_count"` + ClusterSet []cluster `json:"cluster_set"` + }{} + err = json.Unmarshal(data, &listClusterResponse) + + if err != nil { + glog.Error(err) + return nil, err + } + + clusters = append(clusters, listClusterResponse.ClusterSet...) + + if listClusterResponse.TotalCount <= limit+offset { + break + } + + offset += limit + } + + return clusters, nil +} + func (c client) DeleteRuntime(runtimeId string) error { - data := []byte(fmt.Sprintf(`{"runtime_id":"%s"}`, runtimeId)) - req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/v1/runtimes", openpitrixAPIServer), bytes.NewReader(data)) + clusters, err := c.listClusters(runtimeId) if err != nil { + glog.Error(err) return err } - req.Header.Add("Authorization", openpitrixProxyToken) - if err != nil { - return err - } - log.Println(req.Method, req.URL) - resp, err := c.client.Do(req) + err = c.deleteClusters(clusters) if err != nil { + glog.Error(err) return err } - defer resp.Body.Close() - data, err = ioutil.ReadAll(resp.Body) - - if err != nil { - return err - } - - if resp.StatusCode > http.StatusOK { - return Error{resp.StatusCode, string(data)} - } return nil } + +func IsNotFound(err error) bool { + if e, ok := err.(Error); ok { + if e.status == http.StatusNotFound { + return true + } + if strings.Contains(e.message, "not exist") { + return true + } + if strings.Contains(e.message, "not found") { + return true + } + } + return false +} + +func IsDeleted(err error) bool { + if e, ok := err.(Error); ok { + if strings.Contains(e.message, "is [deleted]") { + return true + } + } + return false +} diff --git a/vendor/github.com/kubernetes-sigs/application/pkg/genericreconciler/genericreconciler.go b/vendor/github.com/kubernetes-sigs/application/pkg/genericreconciler/genericreconciler.go index c143c03bd..7cf7f5bea 100644 --- a/vendor/github.com/kubernetes-sigs/application/pkg/genericreconciler/genericreconciler.go +++ b/vendor/github.com/kubernetes-sigs/application/pkg/genericreconciler/genericreconciler.go @@ -71,7 +71,6 @@ func (gr *Reconciler) observe(observables ...resource.Observable) (*resource.Obj types.NamespacedName{Name: name, Namespace: namespace}, obs.Obj.(runtime.Object)) if err == nil { - log.Printf(" >>get: %s", otype+"/"+namespace+"/"+name) resources = append(resources, resource.Object{Obj: obs.Obj}) } else { log.Printf(" >>>ERR get: %s", otype+"/"+namespace+"/"+name) @@ -147,11 +146,9 @@ func (gr *Reconciler) ReconcileCR(namespacedname types.NamespacedName, handle cr err := gr.Get(context.TODO(), namespacedname, rsrc.(runtime.Object)) if err == nil { o := rsrc.(metav1.Object) - log.Printf("%s Validating spec\n", name) err = rsrc.Validate() status = rsrc.NewStatus() if err == nil { - log.Printf("%s Applying defaults\n", name) rsrc.ApplyDefaults() components := rsrc.Components() for _, component := range components { @@ -230,8 +227,8 @@ func (gr *Reconciler) ObserveAndMutate(crname string, c component.Component, sta // FinalizeComponent is a function that finalizes component func (gr *Reconciler) FinalizeComponent(crname string, c component.Component, status interface{}, aggregated *resource.ObjectBag) error { cname := crname + "(cmpnt:" + c.Name + ")" - log.Printf("%s { finalizing component\n", cname) - defer log.Printf("%s } finalizing component\n", cname) + log.Printf("%s finalizing component\n", cname) + defer log.Printf("%s finalizing component completed", cname) expected, observed, err := gr.ObserveAndMutate(crname, c, status, false, aggregated) @@ -249,8 +246,8 @@ func (gr *Reconciler) ReconcileComponent(crname string, c component.Component, s var reconciled *resource.ObjectBag = new(resource.ObjectBag) cname := crname + "(cmpnt:" + c.Name + ")" - log.Printf("%s { reconciling component\n", cname) - defer log.Printf("%s } reconciling component\n", cname) + log.Printf("%s reconciling component\n", cname) + defer log.Printf("%s reconciling component completed\n", cname) expected, observed, err := gr.ObserveAndMutate(crname, c, status, true, aggregated) @@ -270,17 +267,8 @@ func (gr *Reconciler) ReconcileComponent(crname string, c component.Component, s errs = handleErrorArr("", crname, err, errs) } else { aggregated.Add(expected.Items()...) - log.Printf("%s Expected Resources:\n", cname) - for _, e := range expected.Items() { - log.Printf("%s exp: %s/%s/%s\n", cname, e.Obj.GetNamespace(), reflect.TypeOf(e.Obj).String(), e.Obj.GetName()) - } - log.Printf("%s Observed Resources:\n", cname) - for _, e := range observed.Items() { - log.Printf("%s obs: %s/%s/%s\n", cname, e.Obj.GetNamespace(), reflect.TypeOf(e.Obj).String(), e.Obj.GetName()) - } - - log.Printf("%s Reconciling Resources:\n", cname) } + for _, e := range expected.Items() { seen := false eNamespace := e.Obj.GetNamespace() @@ -298,11 +286,7 @@ func (gr *Reconciler) ReconcileComponent(crname string, c component.Component, s if e.Lifecycle == resource.LifecycleManaged && (specDiffers(e.Obj, o.Obj) && c.Differs(e.Obj, o.Obj) || injectOwnerRefs(e.Obj, c.OwnerRef)) { if err := gr.Update(context.TODO(), e.Obj.(runtime.Object).DeepCopyObject()); err != nil { errs = handleErrorArr("update", eRsrcInfo, err, errs) - } else { - log.Printf("%s update: %s\n", cname, eRsrcInfo) } - } else { - log.Printf("%s nochange: %s\n", cname, eRsrcInfo) } reconciled.Add(o) seen = true @@ -315,7 +299,6 @@ func (gr *Reconciler) ReconcileComponent(crname string, c component.Component, s if err := gr.Create(context.TODO(), e.Obj.(runtime.Object)); err != nil { errs = handleErrorArr("Create", cname, err, errs) } else { - log.Printf("%s +create: %s\n", cname, eRsrcInfo) reconciled.Add(e) } } else { @@ -325,31 +308,6 @@ func (gr *Reconciler) ReconcileComponent(crname string, c component.Component, s } } - // delete(observed - expected) - for _, o := range observed.Items() { - seen := false - oNamespace := o.Obj.GetNamespace() - oName := o.Obj.GetName() - oKind := reflect.TypeOf(o.Obj).String() - oRsrcInfo := oKind + "/" + oNamespace + "/" + oName - for _, e := range expected.Items() { - if (e.Obj.GetName() == oName) && - (e.Obj.GetNamespace() == oNamespace) && - (reflect.TypeOf(o.Obj).String() == oKind) { - seen = true - break - } - } - // rsrc is in observed but not in expected - delete - if !seen { - if err := gr.Delete(context.TODO(), o.Obj.(runtime.Object)); err != nil { - errs = handleErrorArr("delete", oRsrcInfo, err, errs) - } else { - log.Printf("%s -delete: %s\n", cname, oRsrcInfo) - } - } - } - err = utilerrors.NewAggregate(errs) c.UpdateComponentStatus(c.CR, status, reconciled, err) return err