From 2db2a5636bc3c1313482621b33086642bb09383b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Pavl=C3=AD=C4=8Dek?= Date: Fri, 4 Sep 2026 11:43:26 +0200 Subject: [PATCH] z0 - make zcli essearch free --- go.mod | 16 ++-- go.sum | 30 +++---- src/cmd/projectList_integration_test.go | 22 +++-- src/cmd/serviceCreate.go | 9 +-- src/cmd/serviceLog.go | 2 +- src/cmdBuilder/scopeService.go | 3 +- src/entity/repository/appVersion.go | 103 +++++------------------- src/entity/repository/container.go | 61 -------------- src/entity/repository/org.go | 44 ++++++---- src/entity/repository/process.go | 56 ------------- src/entity/repository/project.go | 58 +++++++------ src/entity/repository/service.go | 64 ++++++--------- src/entity/service.go | 20 ++++- 13 files changed, 157 insertions(+), 331 deletions(-) delete mode 100644 src/entity/repository/container.go diff --git a/go.mod b/go.mod index 71bf5e72..7179716b 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/zeropsio/zcli go 1.26 -require github.com/zeropsio/zerops-go v1.0.18 +require github.com/zeropsio/zerops-go v1.0.23 require ( github.com/charmbracelet/bubbles v0.20.0 @@ -22,9 +22,9 @@ require ( github.com/spf13/viper v1.20.0 github.com/stretchr/testify v1.10.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/mod v0.26.0 - golang.org/x/term v0.28.0 - golang.org/x/text v0.28.0 + golang.org/x/mod v0.35.0 + golang.org/x/term v0.43.0 + golang.org/x/text v0.37.0 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 gopkg.in/yaml.v3 v3.0.1 ) @@ -42,7 +42,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect - github.com/go-viper/mapstructure/v2 v2.2.1 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-localereader v0.0.1 // indirect @@ -61,8 +61,8 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect + golang.org/x/crypto v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.45.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index db6b9758..f6f51bdb 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,8 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/ github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -113,29 +115,29 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zeropsio/zerops-go v1.0.18 h1:UZMbyfg1ZEgLmDeBTTvyfH5v02juf6TMjAL0ZoTWGgA= -github.com/zeropsio/zerops-go v1.0.18/go.mod h1:SY4o+4jAIrsDTwWACooogf1OyY1jNK8NqWBe9KFcjAA= +github.com/zeropsio/zerops-go v1.0.23 h1:BtGSONtULSlcwjfF3t3ytq4t2BuFEFc6u+7Dy5/R5Qk= +github.com/zeropsio/zerops-go v1.0.23/go.mod h1:SY4o+4jAIrsDTwWACooogf1OyY1jNK8NqWBe9KFcjAA= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= -golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -148,17 +150,17 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= diff --git a/src/cmd/projectList_integration_test.go b/src/cmd/projectList_integration_test.go index 333c95a1..594eeea5 100644 --- a/src/cmd/projectList_integration_test.go +++ b/src/cmd/projectList_integration_test.go @@ -7,19 +7,17 @@ import ( "github.com/stretchr/testify/require" ) -// TestProjectListCommand checks that `zcli project list` walks GetUserInfo → -// org filtering (ACTIVE only) → PostProjectSearch and renders a table that +// TestProjectListCommand checks that `zcli project list` walks GetUserClientList → +// org filtering (ACTIVE only) → GetClientProject and renders a table that // contains the project id, name, and org name. func TestProjectListCommand(t *testing.T) { f := newFixture(t) f.SeedLogin("test-token") - // GetAllOrgs reads UserAuthorize.clientUserList. Only ACTIVE clients are - // queried for projects. - f.HandleJSON("/api/rest/public/user/info", 200, map[string]any{ - "email": "tester@example.com", - "fullName": "Test User", - "clientUserList": []map[string]any{{ + // GetAllOrgs lists the user's active client memberships. + f.HandleJSON("/api/rest/public/user/client-list", 200, map[string]any{ + "total": 1, + "list": []map[string]any{{ "id": "00000000-0000-0000-0000-000000000001", "clientId": "00000000-0000-0000-0000-0000000000aa", "userId": "00000000-0000-0000-0000-000000000002", @@ -32,11 +30,9 @@ func TestProjectListCommand(t *testing.T) { }}, }) - f.HandleJSON("/api/rest/public/project/search", 200, map[string]any{ - "limit": 50, - "offset": 0, - "totalHits": 1, - "items": []map[string]any{{ + f.HandleJSON("/api/rest/public/client/00000000-0000-0000-0000-0000000000aa/project", 200, map[string]any{ + "total": 1, + "list": []map[string]any{{ "id": "00000000-0000-0000-0000-0000000000bb", "clientId": "00000000-0000-0000-0000-0000000000aa", "name": "demo-project", diff --git a/src/cmd/serviceCreate.go b/src/cmd/serviceCreate.go index dfc2bc87..8bf1b0e8 100644 --- a/src/cmd/serviceCreate.go +++ b/src/cmd/serviceCreate.go @@ -23,7 +23,6 @@ import ( "github.com/zeropsio/zerops-go/apiError" "github.com/zeropsio/zerops-go/errorCode" "github.com/zeropsio/zerops-go/types" - "github.com/zeropsio/zerops-go/types/enum" "github.com/zeropsio/zerops-go/types/stringId" ) @@ -37,7 +36,7 @@ func serviceCreateCmd() *cmdBuilder.Cmd { StringFlag("zerops-yaml-path", "", i18n.T(i18n.ZeropsYamlLocation)). StringFlag("working-dir", "./", i18n.T(i18n.BuildWorkingDir)). StringFlag("name", "", "Service name"). - StringFlag("mode", enumDefaultForFlag(enum.ServiceStackModeEnumNonHa), "Service mode "+enumValuesForFlag(enum.ServiceStackModeEnumAllPublic())). + StringFlag("mode", enumDefaultForFlag(entity.ServiceModeNonHa), "Service mode "+enumValuesForFlag(entity.ServiceModeAll())). StringFlag("out", "", "Output format of command, using golang's text/template engine. Entity fields: "+formatAllowedTemplateFields(entity.ServiceFields)). StringFlag("env-file", "", "File with envs (will be set as secrets, runtime envs can be defined in zerops.yml). Max file size is "+units.ByteCountIEC(maxEnvFileSize)). StringFlag("env-isolation", "service", "Env isolation rule [service, none] for more info see docs https://docs.zerops.io/features/env-variables#isolation-modes"). @@ -57,8 +56,8 @@ func serviceCreateCmd() *cmdBuilder.Cmd { mode := cmdData.Params.GetString("mode") mode = strings.ToUpper(mode) - if !enum.ServiceStackModeEnum(mode).Is(enum.ServiceStackModeEnumAllPublic()...) { - return errors.Errorf("Invalid --mode, expected one of %s, got %s", enum.ServiceStackModeEnumAllPublic(), mode) + if !entity.ServiceMode(mode).Is(entity.ServiceModeAll()...) { + return errors.Errorf("Invalid --mode, expected one of %s, got %s", entity.ServiceModeAll(), mode) } envFile, err := readServiceEnvFile(cmdData) @@ -102,7 +101,7 @@ func serviceCreateCmd() *cmdBuilder.Cmd { postService := entity.PostService{ ProjectId: project.Id, Name: types.NewString(name), - Mode: enum.ServiceStackModeEnum(mode), + Mode: entity.ServiceMode(mode), EnvFile: envFile, StartWithoutCode: types.NewBool(startWithoutCode), SshIsolation: types.NewStringNull(cmdData.Params.GetString("ssh-isolation")), diff --git a/src/cmd/serviceLog.go b/src/cmd/serviceLog.go index 8c27fea7..f7685f24 100644 --- a/src/cmd/serviceLog.go +++ b/src/cmd/serviceLog.go @@ -42,7 +42,7 @@ func serviceLogCmd() *cmdBuilder.Cmd { ) serviceId := service.Id - if cmdData.Params.GetBool("showBuildLogs") { + if cmdData.Params.GetBool("show-build-logs") { appVersions, err := repository.GetLatestAppVersionByService(ctx, cmdData.RestApiClient, service) if err != nil { return err diff --git a/src/cmdBuilder/scopeService.go b/src/cmdBuilder/scopeService.go index 17ae7d0a..8fc7393e 100644 --- a/src/cmdBuilder/scopeService.go +++ b/src/cmdBuilder/scopeService.go @@ -18,7 +18,6 @@ import ( "github.com/zeropsio/zerops-go/apiError" "github.com/zeropsio/zerops-go/errorCode" "github.com/zeropsio/zerops-go/types" - "github.com/zeropsio/zerops-go/types/enum" "github.com/zeropsio/zerops-go/types/uuid" ) @@ -199,7 +198,7 @@ func createNewService(ctx context.Context, project entity.Project, cmdData *Logg entity.PostService{ ProjectId: project.Id, Name: types.NewString(name), - Mode: enum.ServiceStackModeEnumNonHa, + Mode: entity.ServiceModeNonHa, // Location: location.Id.LocationIdNull(), }, ) diff --git a/src/entity/repository/appVersion.go b/src/entity/repository/appVersion.go index ce8e9640..35801c85 100644 --- a/src/entity/repository/appVersion.go +++ b/src/entity/repository/appVersion.go @@ -5,83 +5,22 @@ import ( "github.com/zeropsio/zcli/src/entity" "github.com/zeropsio/zcli/src/zeropsRestApiClient" - "github.com/zeropsio/zerops-go/dto/input/body" + "github.com/zeropsio/zerops-go/dto/input/path" + "github.com/zeropsio/zerops-go/dto/input/query" "github.com/zeropsio/zerops-go/dto/output" "github.com/zeropsio/zerops-go/types" ) -func GetAllAppVersionByService( - ctx context.Context, - restApiClient *zeropsRestApiClient.Handler, - service entity.Service, -) ([]entity.AppVersion, error) { - esFilter := body.EsFilter{ - Search: []body.EsSearchItem{ - { - Name: "clientId", - Operator: "eq", - Value: service.OrgId.TypedString(), - }, { - Name: "serviceStackId", - Operator: "eq", - Value: service.Id.TypedString(), - }, { - Name: "build.serviceStackId", - Operator: "ne", - Value: "", - }, - }, - } - - response, err := restApiClient.PostAppVersionSearch(ctx, esFilter) - if err != nil { - return nil, err - } - - resOutput, err := response.Output() - if err != nil { - return nil, err - } - - appVersions := make([]entity.AppVersion, 0, len(resOutput.Items)) - for _, appVersion := range resOutput.Items { - appVersions = append(appVersions, appVersionFromEsSearch(appVersion)) - } - - return appVersions, nil -} - func GetLatestAppVersionByService( ctx context.Context, restApiClient *zeropsRestApiClient.Handler, service entity.Service, ) ([]entity.AppVersion, error) { - esFilter := body.EsFilter{ - Search: []body.EsSearchItem{ - { - Name: "clientId", - Operator: "eq", - Value: service.OrgId.TypedString(), - }, { - Name: "serviceStackId", - Operator: "eq", - Value: service.Id.TypedString(), - }, { - Name: "build.serviceStackId", - Operator: "ne", - Value: "", - }, - }, - Sort: []body.EsSortItem{ - { - Name: "sequence", - Ascending: types.NewBoolNull(false), - }, - }, - Limit: types.NewIntNull(1), - } - - response, err := restApiClient.PostAppVersionSearch(ctx, esFilter) + response, err := restApiClient.GetServiceStackAppVersion(ctx, path.ServiceStackId{Id: service.Id}, query.ListServiceStackAppVersions{ + Limit: types.NewIntNull(1), + HasBuild: types.NewBoolNull(true), + Sort: types.NewStringArrayNull(types.StringArray{"-sequence"}), + }) if err != nil { return nil, err } @@ -90,25 +29,25 @@ func GetLatestAppVersionByService( return nil, err } - appVersions := make([]entity.AppVersion, 0, len(resOutput.Items)) - for _, appVersion := range resOutput.Items { - appVersions = append(appVersions, appVersionFromEsSearch(appVersion)) + appVersions := make([]entity.AppVersion, 0, len(resOutput.List)) + for _, appVersion := range resOutput.List { + appVersions = append(appVersions, appVersionFromApiOutput(appVersion)) } return appVersions, nil } -func appVersionFromEsSearch(esAppVersion output.EsAppVersion) entity.AppVersion { +func appVersionFromApiOutput(appVersion output.GetAppVersion) entity.AppVersion { return entity.AppVersion{ - Id: esAppVersion.Id, - OrgId: esAppVersion.ClientId, - ProjectId: esAppVersion.ProjectId, - ServiceId: esAppVersion.ServiceStackId, - Source: esAppVersion.Source, - Sequence: esAppVersion.Sequence, - Status: esAppVersion.Status, - Created: esAppVersion.Created, - LastUpdate: esAppVersion.LastUpdate, - Build: esAppVersion.Build, + Id: appVersion.Id, + OrgId: appVersion.ClientId, + ProjectId: appVersion.ProjectId, + ServiceId: appVersion.ServiceStackId, + Source: appVersion.Source, + Sequence: appVersion.Sequence, + Status: appVersion.Status, + Created: appVersion.Created, + LastUpdate: appVersion.LastUpdate, + Build: appVersion.Build, } } diff --git a/src/entity/repository/container.go b/src/entity/repository/container.go deleted file mode 100644 index a34a3483..00000000 --- a/src/entity/repository/container.go +++ /dev/null @@ -1,61 +0,0 @@ -package repository - -import ( - "context" - - "github.com/zeropsio/zcli/src/entity" - "github.com/zeropsio/zcli/src/zeropsRestApiClient" - "github.com/zeropsio/zerops-go/dto/input/body" - "github.com/zeropsio/zerops-go/dto/output" -) - -func GetAllContainers( - ctx context.Context, - restApiClient *zeropsRestApiClient.Handler, - service entity.Service, -) ([]entity.Container, error) { - esFilter := body.EsFilter{ - Search: []body.EsSearchItem{ - { - Name: "clientId", - Operator: "eq", - Value: service.OrgId.TypedString(), - }, { - Name: "serviceStackId", - Operator: "eq", - Value: service.Id.TypedString(), - }, - }, - } - - response, err := restApiClient.PostContainerSearch(ctx, esFilter) - if err != nil { - return nil, err - } - - resOutput, err := response.Output() - if err != nil { - return nil, err - } - - containers := make([]entity.Container, 0, len(resOutput.Items)) - for _, container := range resOutput.Items { - containers = append(containers, containerFromEsSearch(container)) - } - - return containers, nil -} - -func containerFromEsSearch(esContainer output.EsContainer) entity.Container { - return entity.Container{ - Id: esContainer.Id, - OrgId: esContainer.ClientId, - ProjectId: esContainer.ProjectId, - ServiceId: esContainer.ServiceStackId, - Status: esContainer.Status, - Number: esContainer.Number, - Name: esContainer.Name, - Hostname: esContainer.Hostname, - Created: esContainer.Created, - } -} diff --git a/src/entity/repository/org.go b/src/entity/repository/org.go index ba209aed..669a1f36 100644 --- a/src/entity/repository/org.go +++ b/src/entity/repository/org.go @@ -7,7 +7,9 @@ import ( "github.com/zeropsio/zcli/src/entity" "github.com/zeropsio/zcli/src/gn" "github.com/zeropsio/zcli/src/zeropsRestApiClient" + "github.com/zeropsio/zerops-go/dto/input/query" "github.com/zeropsio/zerops-go/dto/output" + "github.com/zeropsio/zerops-go/types" "github.com/zeropsio/zerops-go/types/uuid" ) @@ -15,19 +17,29 @@ func GetAllOrgs( ctx context.Context, restApiClient *zeropsRestApiClient.Handler, ) ([]entity.Org, error) { - response, err := restApiClient.GetUserInfo(ctx) - if err != nil { - return nil, err - } + var orgs []entity.Org + for offset := 0; ; { + response, err := restApiClient.GetUserClientList(ctx, query.ListUserClients{ + Limit: types.NewIntNull(listPageLimit), + Offset: types.NewIntNull(offset), + }) + if err != nil { + return nil, err + } - resOutput, err := response.Output() - if err != nil { - return nil, err - } + resOutput, err := response.Output() + if err != nil { + return nil, err + } + + for _, client := range resOutput.List { + orgs = append(orgs, orgFromClientUser(client)) + } - orgs := make([]entity.Org, 0, len(resOutput.ClientUserList)) - for _, client := range resOutput.ClientUserList { - orgs = append(orgs, orgFromEsSearch(client)) + offset += len(resOutput.List) + if len(resOutput.List) == 0 || offset >= resOutput.Total.Native() { + break + } } return orgs, nil @@ -51,11 +63,11 @@ func GetOrgById( return org, nil } -func orgFromEsSearch(esClientUser output.ClientUserExtraWithClientLight) entity.Org { +func orgFromClientUser(clientUser output.ClientUserExtraWithClientLight) entity.Org { return entity.Org{ - Id: esClientUser.ClientId, - Name: esClientUser.Client.AccountName, - Status: esClientUser.Status, - Role: esClientUser.RoleCode, + Id: clientUser.ClientId, + Name: clientUser.Client.AccountName, + Status: clientUser.Status, + Role: clientUser.RoleCode, } } diff --git a/src/entity/repository/process.go b/src/entity/repository/process.go index deb3d6e9..6acf076b 100644 --- a/src/entity/repository/process.go +++ b/src/entity/repository/process.go @@ -1,66 +1,10 @@ package repository import ( - "context" - "github.com/zeropsio/zcli/src/entity" - "github.com/zeropsio/zcli/src/gn" - "github.com/zeropsio/zcli/src/zeropsRestApiClient" - "github.com/zeropsio/zerops-go/dto/input/body" "github.com/zeropsio/zerops-go/dto/output" - "github.com/zeropsio/zerops-go/types" - "github.com/zeropsio/zerops-go/types/uuid" ) -func GetProcessByActionNameAndProjectId( - ctx context.Context, - restApiClient *zeropsRestApiClient.Handler, - orgId uuid.ClientId, - projectId uuid.ProjectId, - actionName types.String, -) ([]entity.Process, error) { - search, err := restApiClient.PostProcessSearch(ctx, body.EsFilter{ - Search: body.EsFilterSearch{ - { - Name: "clientId", - Operator: "eq", - Value: orgId.TypedString(), - }, - { - Name: "projectId", - Operator: "eq", - Value: projectId.TypedString(), - }, - { - Name: "actionName", - Operator: "eq", - Value: actionName, - }, - }, - }) - if err != nil { - return nil, err - } - response, err := search.Output() - if err != nil { - return nil, err - } - return gn.TransformSlice(response.Items, processFromEsSearch), nil -} - -func processFromEsSearch(esProcess output.EsProcess) entity.Process { - return entity.Process{ - Id: esProcess.Id, - OrgId: esProcess.ClientId, - ProjectId: esProcess.ProjectId, - ServiceId: esProcess.ServiceStackId, - ActionName: esProcess.ActionName, - Status: esProcess.Status, - Sequence: esProcess.Sequence, - } -} - -//nolint:unused func processFromApiOutput(process output.Process) entity.Process { return entity.Process{ Id: process.Id, diff --git a/src/entity/repository/project.go b/src/entity/repository/project.go index 5df1f686..341d6258 100644 --- a/src/entity/repository/project.go +++ b/src/entity/repository/project.go @@ -7,11 +7,15 @@ import ( "github.com/zeropsio/zcli/src/zeropsRestApiClient" "github.com/zeropsio/zerops-go/dto/input/body" "github.com/zeropsio/zerops-go/dto/input/path" + "github.com/zeropsio/zerops-go/dto/input/query" "github.com/zeropsio/zerops-go/dto/output" "github.com/zeropsio/zerops-go/types" "github.com/zeropsio/zerops-go/types/uuid" ) +// listPageLimit matches the API's maximum page size, so paged fetch-all loops need as few round trips as possible. +const listPageLimit = 100 + func GetProjectById( ctx context.Context, restApiClient *zeropsRestApiClient.Handler, @@ -45,27 +49,27 @@ func GetAllProjects( if !org.Status.IsActive() { continue } - esFilter := body.EsFilter{ - Search: []body.EsSearchItem{ - { - Name: "clientId", - Operator: "eq", - Value: org.Id.TypedString(), - }, - }, - } + for offset := 0; ; { + response, err := restApiClient.GetClientProject(ctx, path.ClientId{Id: org.Id}, query.ListClientProjects{ + Limit: types.NewIntNull(listPageLimit), + Offset: types.NewIntNull(offset), + }) + if err != nil { + return nil, err + } + projectsResponse, err := response.Output() + if err != nil { + return nil, err + } - response, err := restApiClient.PostProjectSearch(ctx, esFilter) - if err != nil { - return nil, err - } - projectsResponse, err := response.Output() - if err != nil { - return nil, err - } + for _, project := range projectsResponse.List { + projects = append(projects, projectFromApiOutputWithOrg(org, project)) + } - for _, project := range projectsResponse.Items { - projects = append(projects, projectFromEsSearch(org, project)) + offset += len(projectsResponse.List) + if len(projectsResponse.List) == 0 || offset >= projectsResponse.Total.Native() { + break + } } } @@ -99,18 +103,10 @@ func PostProject( return projectFromApiOutput(project), nil } -func projectFromEsSearch(org entity.Org, esProject output.EsProject) entity.Project { - description, _ := esProject.Description.Get() - - return entity.Project{ - Id: esProject.Id, - Name: esProject.Name, - Mode: esProject.Mode, - OrgId: org.Id, - OrgName: org.Name, - Description: description, - Status: esProject.Status, - } +func projectFromApiOutputWithOrg(org entity.Org, project output.Project) entity.Project { + out := projectFromApiOutput(project) + out.OrgName = org.Name + return out } func projectFromApiOutput(project output.Project) entity.Project { diff --git a/src/entity/repository/service.go b/src/entity/repository/service.go index 72596547..f1265a70 100644 --- a/src/entity/repository/service.go +++ b/src/entity/repository/service.go @@ -10,6 +10,7 @@ import ( "github.com/zeropsio/zerops-go/apiError" "github.com/zeropsio/zerops-go/dto/input/body" "github.com/zeropsio/zerops-go/dto/input/path" + "github.com/zeropsio/zerops-go/dto/input/query" "github.com/zeropsio/zerops-go/dto/output" "github.com/zeropsio/zerops-go/errorCode" "github.com/zeropsio/zerops-go/types" @@ -92,35 +93,29 @@ func GetNonSystemServicesByProject( restApiClient *zeropsRestApiClient.Handler, project entity.Project, ) ([]entity.Service, error) { - esFilter := body.EsFilter{ - Search: []body.EsSearchItem{ - { - Name: "projectId", - Operator: "eq", - Value: project.Id.TypedString(), - }, - { - Name: "clientId", - Operator: "eq", - Value: project.OrgId.TypedString(), - }, - }, - } + var services []entity.Service + for offset := 0; ; { + servicesResponse, err := restApiClient.GetProjectServiceStack(ctx, path.ProjectId{Id: project.Id}, query.ListProjectServiceStacks{ + Limit: types.NewIntNull(listPageLimit), + Offset: types.NewIntNull(offset), + IsSystem: types.NewBoolNull(false), + }) + if err != nil { + return nil, err + } - servicesResponse, err := restApiClient.PostServiceStackSearch(ctx, esFilter) - if err != nil { - return nil, err - } + servicesOutput, err := servicesResponse.Output() + if err != nil { + return nil, err + } - servicesOutput, err := servicesResponse.Output() - if err != nil { - return nil, err - } + for _, service := range servicesOutput.List { + services = append(services, serviceFromApiOutput(service)) + } - services := make([]entity.Service, 0, len(servicesOutput.Items)) - for _, service := range servicesOutput.Items { - if !service.IsSystem { - services = append(services, serviceFromEsSearch(service)) + offset += len(servicesOutput.List) + if len(servicesOutput.List) == 0 || offset >= servicesOutput.Total.Native() { + break } } @@ -134,14 +129,14 @@ func PostGenericService( ) (entity.Process, entity.Service, error) { postBody := body.PostStandardServiceStack{ Name: post.Name, - Mode: &post.Mode, + Mode: types.NewStringNull(string(post.Mode)), UserDataEnvFile: post.EnvFile, StartWithoutCode: types.NewBoolNull(post.StartWithoutCode.Native()), EnvIsolation: post.EnvIsolation, SshIsolation: post.SshIsolation, Location: post.Location, } - response, err := restApiClient.PostProjectServiceStack( + response, err := restApiClient.PostProjectServiceStackOld( ctx, path.ServiceStackServiceStackTypeVersionId{ Id: post.ProjectId, @@ -160,19 +155,6 @@ func PostGenericService( return processFromApiOutput(serviceStackProcess.Process), serviceFromApiPostOutput(serviceStackProcess), nil } -func serviceFromEsSearch(esServiceStack output.EsServiceStack) entity.Service { - return entity.Service{ - Id: esServiceStack.Id, - ProjectId: esServiceStack.ProjectId, - OrgId: esServiceStack.ClientId, - Name: esServiceStack.Name, - Status: esServiceStack.Status, - ServiceTypeId: esServiceStack.ServiceStackTypeId, - ServiceTypeCategory: esServiceStack.ServiceStackTypeInfo.ServiceStackTypeCategory, - ServiceStackTypeVersionName: esServiceStack.ServiceStackTypeInfo.ServiceStackTypeVersionName, - } -} - func serviceFromApiOutput(service output.ServiceStack) entity.Service { return entity.Service{ Id: service.Id, diff --git a/src/entity/service.go b/src/entity/service.go index ac8b9535..fc5e2fde 100644 --- a/src/entity/service.go +++ b/src/entity/service.go @@ -1,6 +1,8 @@ package entity import ( + "slices" + "github.com/zeropsio/zerops-go/types" "github.com/zeropsio/zerops-go/types/enum" "github.com/zeropsio/zerops-go/types/stringId" @@ -20,10 +22,26 @@ type Service struct { var ServiceFields = entityTemplateFields[Service]() +// ServiceMode mirrors the ServiceStackModeEnum the SDK dropped when the platform deprecated serviceStack.mode to a plain string. +type ServiceMode string + +const ( + ServiceModeHa ServiceMode = "HA" + ServiceModeNonHa ServiceMode = "NON_HA" +) + +func ServiceModeAll() []ServiceMode { + return []ServiceMode{ServiceModeHa, ServiceModeNonHa} +} + +func (m ServiceMode) Is(values ...ServiceMode) bool { + return slices.Contains(values, m) +} + type PostService struct { ProjectId uuid.ProjectId Name types.String - Mode enum.ServiceStackModeEnum + Mode ServiceMode EnvFile types.TextNull StartWithoutCode types.Bool SshIsolation types.StringNull