Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ 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.19

replace github.com/zeropsio/zerops-go => ../zerops-go

require (
github.com/charmbracelet/bubbles v0.20.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ 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.19 h1:C4A96tc4pqlPHfv9ebn3O/8ggE3+FOWXLFomkfovcpI=
github.com/zeropsio/zerops-go v1.0.19/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=
Expand Down
18 changes: 9 additions & 9 deletions src/cmd/projectList_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,36 @@ import (
)

// TestProjectListCommand checks that `zcli project list` walks GetUserInfo →
// org filtering (ACTIVE only) → PostProjectSearch and renders a table that
// 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")

orgId := "00000000-0000-0000-0000-0000000000aa"

// 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{{
"id": "00000000-0000-0000-0000-000000000001",
"clientId": "00000000-0000-0000-0000-0000000000aa",
"clientId": orgId,
"userId": "00000000-0000-0000-0000-000000000002",
"status": "ACTIVE",
"roleCode": "ADMIN",
"client": map[string]any{
"id": "00000000-0000-0000-0000-0000000000aa",
"id": orgId,
"accountName": "Acme Org",
},
}},
})

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/"+orgId+"/project", 200, map[string]any{
"list": []map[string]any{{
"id": "00000000-0000-0000-0000-0000000000bb",
"clientId": "00000000-0000-0000-0000-0000000000aa",
"clientId": orgId,
"name": "demo-project",
"mode": "LIGHT",
"status": "ACTIVE",
Expand All @@ -47,6 +46,7 @@ func TestProjectListCommand(t *testing.T) {
"tagList": []string{},
"description": nil,
}},
"totalCount": 1,
})

res := f.Run("project", "list")
Expand Down
11 changes: 5 additions & 6 deletions src/cmd/serviceCreate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ import (
"github.com/zeropsio/zcli/src/uxBlock/styles"
"github.com/zeropsio/zcli/src/uxHelpers"
"github.com/zeropsio/zcli/src/yamlReader"
"github.com/zeropsio/zerops-go/apiError"
"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"
)

Expand All @@ -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", "NON_HA", "Service mode [HA, NON_HA]").
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").
Expand All @@ -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 mode != "HA" && mode != "NON_HA" {
return errors.Errorf("Invalid --mode, expected one of [HA, NON_HA], got %s", mode)
}

envFile, err := readServiceEnvFile(cmdData)
Expand Down Expand Up @@ -102,7 +101,7 @@ func serviceCreateCmd() *cmdBuilder.Cmd {
postService := entity.PostService{
ProjectId: project.Id,
Name: types.NewString(name),
Mode: enum.ServiceStackModeEnum(mode),
Mode: types.NewString(mode),
EnvFile: envFile,
StartWithoutCode: types.NewBool(startWithoutCode),
SshIsolation: types.NewStringNull(cmdData.Params.GetString("ssh-isolation")),
Expand Down
3 changes: 1 addition & 2 deletions src/cmdBuilder/scopeService.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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: types.NewString("NON_HA"),
// Location: location.Id.LocationIdNull(),
},
)
Expand Down
111 changes: 45 additions & 66 deletions src/entity/repository/appVersion.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,39 @@ package repository

import (
"context"
"sort"

"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)
response, err := restApiClient.GetServiceStackAppVersion(
ctx,
path.ServiceStackId{Id: service.Id},
query.ListServiceStackAppVersions{},
)
if err != nil {
return nil, err
}

resOutput, err := response.Output()
versionList, 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))
appVersions := make([]entity.AppVersion, 0, len(versionList.List))
for _, v := range versionList.List {
if v.Build != nil {
appVersions = append(appVersions, appVersionFromListOutput(v))
}
}

return appVersions, nil
Expand All @@ -56,59 +45,49 @@ func GetLatestAppVersionByService(
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{},
)
if err != nil {
return nil, err
}
resOutput, err := response.Output()

versionList, 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))
appVersions := make([]entity.AppVersion, 0, len(versionList.List))
for _, v := range versionList.List {
if v.Build != nil {
appVersions = append(appVersions, appVersionFromListOutput(v))
}
}

sort.Slice(appVersions, func(i, j int) bool {
return appVersions[i].Sequence.Native() > appVersions[j].Sequence.Native()
})

if len(appVersions) > 1 {
appVersions = appVersions[:1]
}

return appVersions, nil
}

func appVersionFromEsSearch(esAppVersion output.EsAppVersion) entity.AppVersion {
func appVersionFromListOutput(av 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: av.Id,
OrgId: av.ClientId,
ProjectId: av.ProjectId,
ServiceId: av.ServiceStackId,
Source: av.Source,
Sequence: av.Sequence,
Status: av.Status,
Created: av.Created,
LastUpdate: av.LastUpdate,
Build: av.Build,
}
}
53 changes: 20 additions & 33 deletions src/entity/repository/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ 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/input/path"
"github.com/zeropsio/zerops-go/dto/input/query"
"github.com/zeropsio/zerops-go/dto/output"
)

Expand All @@ -14,48 +16,33 @@ func GetAllContainers(
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)
response, err := restApiClient.GetServiceStackContainer(
ctx,
path.ServiceStackId{Id: service.Id},
query.ListServiceStackContainers{},
)
if err != nil {
return nil, err
}

resOutput, err := response.Output()
containerList, 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
return gn.TransformSlice(containerList.List, containerFromListOutput), nil
}

func containerFromEsSearch(esContainer output.EsContainer) entity.Container {
func containerFromListOutput(container output.Container) 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,
Id: container.Id,
OrgId: container.ClientId,
ProjectId: container.ProjectId,
ServiceId: container.ServiceStackId,
Status: gn.Ptr(container.Status),
Number: container.Number,
Name: container.Name,
Hostname: container.Hostname,
Created: container.Created,
}
}
Loading