From 9e252e9a309a48a1b7a344b9122797667265d6a2 Mon Sep 17 00:00:00 2001 From: Dominic Wong Date: Mon, 7 Feb 2022 16:45:27 +0000 Subject: [PATCH] Delete data endpoints (#364) --- app/handler/google.go | 43 ++++++++++++++++++++++++--- app/main.go | 5 +++- function/handler/google.go | 61 +++++++++++++++++++++++++++++--------- function/main.go | 5 +++- url/handler/url.go | 35 ++++++++++++++++++++++ url/main.go | 6 ++-- 6 files changed, 133 insertions(+), 22 deletions(-) diff --git a/app/handler/google.go b/app/handler/google.go index e47576f..1c041e0 100644 --- a/app/handler/google.go +++ b/app/handler/google.go @@ -19,6 +19,8 @@ import ( "github.com/micro/micro/v3/service/store" "github.com/micro/services/app/domain" pb "github.com/micro/services/app/proto" + pauth "github.com/micro/services/pkg/auth" + adminpb "github.com/micro/services/pkg/service/proto" "github.com/micro/services/pkg/tenant" "github.com/teris-io/shortid" ) @@ -555,7 +557,6 @@ func (e *GoogleApp) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.D if !ok { id = "micro" } - // read the app for the owner key := OwnerKey + id + "/" + req.Name recs, err := store.Read(key) @@ -575,11 +576,16 @@ func (e *GoogleApp) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.D return err } + return e.deleteApp(ctx, id, srv) +} + +func (e *GoogleApp) deleteApp(ctx context.Context, tenantID string, srv *pb.Service) error { + // check the status switch srv.Status { case domain.StatusUpdating, domain.StatusDeploying, domain.StatusDeleting: - log.Errorf("Won't delete: % is %s", req.Name, srv.Status) - return errors.BadRequest("app.delete", "% status: %s", req.Name, srv.Status) + log.Errorf("Won't delete: % is %s", srv.Name, srv.Status) + return errors.BadRequest("app.delete", "% status: %s", srv.Name, srv.Status) } // delete from the db @@ -587,7 +593,7 @@ func (e *GoogleApp) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.D // service key ServiceKey + srv.Id, // owner key - OwnerKey + id + "/" + req.Name, + OwnerKey + tenantID + "/" + srv.Name, } // set the delete status @@ -623,6 +629,35 @@ func (e *GoogleApp) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.D return nil } +func (e *GoogleApp) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, response *adminpb.DeleteDataResponse) error { + method := "admin.DeleteData" + _, err := pauth.VerifyMicroAdmin(ctx, method) + if err != nil { + return err + } + + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things + return errors.BadRequest(method, "Missing tenant ID") + } + + prefix := OwnerKey + request.TenantId + "/" + + recs, err := store.Read(prefix, store.ReadPrefix()) + if err != nil { + return err + } + + for _, rec := range recs { + var srv pb.Service + if err := rec.Decode(&srv); err != nil { + return err + } + e.deleteApp(ctx, request.TenantId, &srv) + } + log.Infof("Deleted %d functions for %s", len(recs), request.TenantId) + return nil +} + func (e *GoogleApp) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { log.Info("Received App.List request") diff --git a/app/main.go b/app/main.go index a689ba3..47cd66b 100644 --- a/app/main.go +++ b/app/main.go @@ -5,6 +5,7 @@ import ( "github.com/micro/micro/v3/service/logger" "github.com/micro/services/app/handler" pb "github.com/micro/services/app/proto" + admin "github.com/micro/services/pkg/service/proto" ) func main() { @@ -14,8 +15,10 @@ func main() { service.Version("latest"), ) + h := handler.New() // Register handler - pb.RegisterAppHandler(srv.Server(), handler.New()) + pb.RegisterAppHandler(srv.Server(), h) + admin.RegisterAdminHandler(srv.Server(), h) // Run service if err := srv.Run(); err != nil { diff --git a/function/handler/google.go b/function/handler/google.go index befbc7f..e749c49 100644 --- a/function/handler/google.go +++ b/function/handler/google.go @@ -19,6 +19,8 @@ import ( "github.com/micro/micro/v3/service/runtime/source/git" "github.com/micro/micro/v3/service/store" function "github.com/micro/services/function/proto" + pauth "github.com/micro/services/pkg/auth" + adminpb "github.com/micro/services/pkg/service/proto" "github.com/micro/services/pkg/tenant" "github.com/teris-io/shortid" ) @@ -626,24 +628,26 @@ func (e *GoogleFunction) Delete(ctx context.Context, req *function.DeleteRequest } // async delete - go func() { - cmd := exec.Command("gcloud", "functions", "delete", "--quiet", "--project", e.project, "--region", fn.Region, fn.Id) - outp, err := cmd.CombinedOutput() - if err != nil && !strings.Contains(string(outp), "does not exist") { - log.Error(fmt.Errorf(string(outp))) - return - } - - // delete the owner key - store.Delete(key) - - // delete the global key - store.Delete(FunctionKey + fn.Id) - }() + go e.deleteFunction(fn, key) return nil } +func (e *GoogleFunction) deleteFunction(fn *function.Func, key string) { + cmd := exec.Command("gcloud", "functions", "delete", "--quiet", "--project", e.project, "--region", fn.Region, fn.Id) + outp, err := cmd.CombinedOutput() + if err != nil && !strings.Contains(string(outp), "does not exist") { + log.Error(fmt.Errorf(string(outp))) + return + } + + // delete the owner key + store.Delete(key) + + // delete the global key + store.Delete(FunctionKey + fn.Id) +} + func (e *GoogleFunction) List(ctx context.Context, req *function.ListRequest, rsp *function.ListResponse) error { log.Info("Received Function.List request") @@ -797,3 +801,32 @@ func (e *GoogleFunction) Regions(ctx context.Context, req *function.RegionsReque rsp.Regions = GoogleRegions return nil } + +func (e *GoogleFunction) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, response *adminpb.DeleteDataResponse) error { + method := "admin.DeleteData" + _, err := pauth.VerifyMicroAdmin(ctx, method) + if err != nil { + return err + } + + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things + return errors.BadRequest(method, "Missing tenant ID") + } + + prefix := OwnerKey + request.TenantId + "/" + + recs, err := store.Read(prefix, store.ReadPrefix()) + if err != nil { + return err + } + + for _, rec := range recs { + var fn function.Func + if err := rec.Decode(&fn); err != nil { + return err + } + e.deleteFunction(&fn, rec.Key) + } + log.Infof("Deleted %d functions for %s", len(recs), request.TenantId) + return nil +} diff --git a/function/main.go b/function/main.go index 504661e..0a0f2ec 100644 --- a/function/main.go +++ b/function/main.go @@ -5,6 +5,7 @@ import ( "github.com/micro/micro/v3/service/logger" "github.com/micro/services/function/handler" pb "github.com/micro/services/function/proto" + admin "github.com/micro/services/pkg/service/proto" ) func main() { @@ -14,8 +15,10 @@ func main() { service.Version("latest"), ) + h := handler.NewFunction() // Register handler - pb.RegisterFunctionHandler(srv.Server(), handler.NewFunction()) + pb.RegisterFunctionHandler(srv.Server(), h) + admin.RegisterAdminHandler(srv.Server(), h) // Run service if err := srv.Run(); err != nil { diff --git a/url/handler/url.go b/url/handler/url.go index ed23a59..590b53e 100644 --- a/url/handler/url.go +++ b/url/handler/url.go @@ -7,7 +7,10 @@ import ( "github.com/micro/micro/v3/service/config" "github.com/micro/micro/v3/service/errors" + "github.com/micro/micro/v3/service/logger" "github.com/micro/micro/v3/service/store" + pauth "github.com/micro/services/pkg/auth" + adminpb "github.com/micro/services/pkg/service/proto" "github.com/micro/services/pkg/tenant" url "github.com/micro/services/url/proto" cache "github.com/patrickmn/go-cache" @@ -135,3 +138,35 @@ func (e *Url) Proxy(ctx context.Context, req *url.ProxyRequest, rsp *url.ProxyRe return nil } + +func (e *Url) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, response *adminpb.DeleteDataResponse) error { + method := "admin.DeleteData" + _, err := pauth.VerifyMicroAdmin(ctx, method) + if err != nil { + return err + } + + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things + return errors.BadRequest(method, "Missing tenant ID") + } + + prefix := "urlOwner/" + request.TenantId + "/" + + keys, err := store.List(store.ListPrefix(prefix)) + if err != nil { + return err + } + + for _, key := range keys { + id := strings.TrimPrefix(key, prefix) + if err := store.Delete("url/" + id); err != nil { + return err + } + if err := store.Delete(key); err != nil { + return err + } + } + logger.Infof("Deleted %d objects from S3 for %s", len(keys), request.TenantId) + + return nil +} diff --git a/url/main.go b/url/main.go index 42865a1..31e1421 100644 --- a/url/main.go +++ b/url/main.go @@ -1,6 +1,7 @@ package main import ( + admin "github.com/micro/services/pkg/service/proto" "github.com/micro/services/pkg/tracing" "github.com/micro/services/url/handler" pb "github.com/micro/services/url/proto" @@ -15,9 +16,10 @@ func main() { service.Name("url"), service.Version("latest"), ) - + h := handler.NewUrl() // Register handler - pb.RegisterUrlHandler(srv.Server(), handler.NewUrl()) + pb.RegisterUrlHandler(srv.Server(), h) + admin.RegisterAdminHandler(srv.Server(), h) traceCloser := tracing.SetupOpentracing("url") defer traceCloser.Close()