From 3d11687d2ae64b6ec2d56efe8ef85600b256a015 Mon Sep 17 00:00:00 2001 From: runzexia Date: Mon, 13 May 2019 17:56:39 +0800 Subject: [PATCH] delete all devops project when delete ws Signed-off-by: runzexia --- .../workspace/workspace_controller.go | 39 ++++++++++ pkg/models/devops/project.go | 5 ++ .../client/kubesphere/kubesphereclient.go | 72 ++++++++++++++++++- 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/pkg/controller/workspace/workspace_controller.go b/pkg/controller/workspace/workspace_controller.go index 72d3a5ee0..b1f6dff19 100644 --- a/pkg/controller/workspace/workspace_controller.go +++ b/pkg/controller/workspace/workspace_controller.go @@ -43,6 +43,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" + "sync" ) const ( @@ -137,6 +138,10 @@ func (r *ReconcileWorkspace) Reconcile(request reconcile.Request) (reconcile.Res return reconcile.Result{}, err } + if err := r.deleteDevOpsProjects(instance); err != nil { + return reconcile.Result{}, err + } + // remove our finalizer from the list and update it. instance.ObjectMeta.Finalizers = sliceutil.RemoveString(instance.ObjectMeta.Finalizers, func(item string) bool { return item == finalizer @@ -327,6 +332,40 @@ func (r *ReconcileWorkspace) deleteGroup(instance *tenantv1alpha1.Workspace) err return nil } +func (r *ReconcileWorkspace) deleteDevOpsProjects(instance *tenantv1alpha1.Workspace) error { + var wg sync.WaitGroup + + log.Info("Delete DevOps Projects") + for { + errChan := make(chan error, 10) + projects, err := r.ksclient.ListWorkspaceDevOpsProjects(instance.Name) + if err != nil { + log.Error(err, "Failed to Get Workspace's DevOps Projects", "ws", instance.Name) + return err + } + if projects.TotalCount == 0 { + return nil + } + for _, project := range projects.Items { + wg.Add(1) + go func(workspace, devops string) { + err := r.ksclient.DeleteWorkspaceDevOpsProjects(workspace, devops) + errChan <- err + wg.Done() + }(instance.Name, project.ProjectId) + } + wg.Wait() + close(errChan) + for err := range errChan { + if err != nil { + log.Error(err, "delete devops project error") + return err + } + } + + } +} + func (r *ReconcileWorkspace) createWorkspaceRoleBindings(instance *tenantv1alpha1.Workspace) error { adminRoleBinding := &rbac.ClusterRoleBinding{} diff --git a/pkg/models/devops/project.go b/pkg/models/devops/project.go index e62271499..37111f3e5 100644 --- a/pkg/models/devops/project.go +++ b/pkg/models/devops/project.go @@ -31,6 +31,11 @@ const ( DevOpsProjectCreateTimeColumn = "project.create_time" ) +type PageableDevOpsProject struct { + Items []*DevOpsProject `json:"items"` + TotalCount int `json:"total_count"` +} + type DevOpsProject struct { ProjectId string `json:"project_id" db:"project_id"` Name string `json:"name"` diff --git a/pkg/simple/client/kubesphere/kubesphereclient.go b/pkg/simple/client/kubesphere/kubesphereclient.go index f7040e2da..f5880525a 100644 --- a/pkg/simple/client/kubesphere/kubesphereclient.go +++ b/pkg/simple/client/kubesphere/kubesphereclient.go @@ -23,7 +23,9 @@ import ( "flag" "fmt" "io/ioutil" + "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/models" + "kubesphere.io/kubesphere/pkg/models/devops" "log" "net/http" "strings" @@ -32,7 +34,7 @@ import ( var ( accountAPIServer string - devopsAPIServer string + ksAPIServer string once sync.Once c client ) @@ -43,6 +45,8 @@ type Interface interface { DescribeGroup(name string) (*models.Group, error) DeleteGroup(name string) error ListUsers() (*models.PageableResponse, error) + ListWorkspaceDevOpsProjects(workspace string) (*devops.PageableDevOpsProject, error) + DeleteWorkspaceDevOpsProjects(workspace, devops string) error } type client struct { @@ -51,6 +55,7 @@ type client struct { func init() { flag.StringVar(&accountAPIServer, "ks-account-api-server", "http://ks-account.kubesphere-system.svc", "kubesphere account api server") + flag.StringVar(&ksAPIServer, "ks-api-server", "http://ks-apiserver.kubesphere-system.svc", "kubesphere api server") } func Client() Interface { @@ -248,6 +253,71 @@ func (c client) ListUsers() (*models.PageableResponse, error) { return &result, nil } +func (c client) ListWorkspaceDevOpsProjects(workspace string) (*devops.PageableDevOpsProject, error) { + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/kapis/tenant.kubesphere.io/v1alpha2/workspaces/%s/devops", ksAPIServer, workspace), nil) + + if err != nil { + return nil, err + } + req.Header.Add(constants.UserNameHeader, constants.AdminUserName) + if err != nil { + return nil, err + } + log.Println(req.Method, req.URL) + resp, err := c.client.Do(req) + + if err != nil { + return nil, err + } + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + + if err != nil { + return nil, err + } + if resp.StatusCode > http.StatusOK { + return nil, Error{resp.StatusCode, string(data)} + } + + var result devops.PageableDevOpsProject + err = json.Unmarshal(data, &result) + + if err != nil { + return nil, err + } + return &result, nil + +} + +func (c client) DeleteWorkspaceDevOpsProjects(workspace, devops string) error { + req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/kapis/tenant.kubesphere.io/v1alpha2/workspaces/%s/devops/%s", ksAPIServer, workspace, devops), nil) + + if err != nil { + return err + } + req.Header.Add(constants.UserNameHeader, constants.AdminUserName) + if err != nil { + return err + } + log.Println(req.Method, req.URL) + resp, err := c.client.Do(req) + + if err != nil { + 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 {