Skip to content

Commit

Permalink
Merge pull request #76 from ninech/project-display-name
Browse files Browse the repository at this point in the history
Add project display name support
  • Loading branch information
ctrox authored Feb 6, 2024
2 parents 44df2a1 + 0dca615 commit cd36c2b
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 19 deletions.
9 changes: 6 additions & 3 deletions create/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

type projectCmd struct {
Name string `arg:"" default:"" help:"Name of the project. A random name is generated if omitted."`
DisplayName string `default:"" help:"Display Name of the project."`
Wait bool `default:"true" help:"Wait until the project was fully created."`
WaitTimeout time.Duration `default:"10m" help:"Duration to wait for project getting ready. Only relevant if wait is set."`
}
Expand All @@ -27,7 +28,7 @@ func (proj *projectCmd) Run(ctx context.Context, client *api.Client) error {
return err
}

p := newProject(proj.Name, cfg.Organization)
p := newProject(proj.Name, cfg.Organization, proj.DisplayName)
fmt.Printf("Creating new project %s for organization %s\n", p.Name, cfg.Organization)
c := newCreator(client, p, strings.ToLower(management.ProjectKind))
ctx, cancel := context.WithTimeout(ctx, proj.WaitTimeout)
Expand All @@ -47,7 +48,7 @@ func (proj *projectCmd) Run(ctx context.Context, client *api.Client) error {
})
}

func newProject(name, project string) *management.Project {
func newProject(name, project, displayName string) *management.Project {
return &management.Project{
ObjectMeta: metav1.ObjectMeta{
Name: getName(name),
Expand All @@ -57,6 +58,8 @@ func newProject(name, project string) *management.Project {
Kind: management.ProjectKind,
APIVersion: management.SchemeGroupVersion.String(),
},
Spec: management.ProjectSpec{},
Spec: management.ProjectSpec{
DisplayName: displayName,
},
}
}
1 change: 1 addition & 0 deletions create/project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func TestProjects(t *testing.T) {

cmd := projectCmd{
Name: projectName,
DisplayName: "Some Display Name",
Wait: false,
WaitTimeout: time.Second,
}
Expand Down
9 changes: 7 additions & 2 deletions get/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

management "github.com/ninech/apis/management/v1alpha1"
"github.com/ninech/nctl/api"
"github.com/ninech/nctl/api/util"
"github.com/ninech/nctl/internal/format"
)

Expand Down Expand Up @@ -60,11 +61,15 @@ func printProject(projects []management.Project, get Cmd, out io.Writer, header
// for projects
if header {
get.AllProjects = false
get.writeHeader(w, "NAME")
get.writeHeader(w, "NAME", "DISPLAY NAME")
}

for _, proj := range projects {
get.writeTabRow(w, "", proj.Name)
displayName := proj.Spec.DisplayName
if len(displayName) == 0 {
displayName = util.NoneText
}
get.writeTabRow(w, "", proj.Name, displayName)
}

return w.Flush()
Expand Down
36 changes: 23 additions & 13 deletions get/project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,38 @@ func TestProject(t *testing.T) {

for name, testCase := range map[string]struct {
projects []client.Object
displayNames []string
name string
outputFormat output
allProjects bool
output string
}{
"projects exist, full format": {
projects: test.Projects(organization, "dev", "staging", "prod"),
displayNames: []string{"Development", "", "Production"},
outputFormat: full,
output: `NAME
dev
prod
staging
output: `NAME DISPLAY NAME
dev Development
prod Production
staging <none>
`,
},
"projects exist, no header format": {
projects: test.Projects(organization, "dev", "staging", "prod"),
outputFormat: noHeader,
output: `dev
prod
staging
output: `dev <none>
prod <none>
staging <none>
`,
},
"projects exist and allProjects is set": {
projects: test.Projects(organization, "dev", "staging", "prod"),
outputFormat: full,
allProjects: true,
output: `NAME
dev
prod
staging
output: `NAME DISPLAY NAME
dev <none>
prod <none>
staging <none>
`,
},
"no projects exist": {
Expand All @@ -69,8 +71,8 @@ staging
projects: test.Projects(organization, "dev", "staging"),
name: "dev",
outputFormat: full,
output: `NAME
dev
output: `NAME DISPLAY NAME
dev <none>
`,
},
"specific project requested, but does not exist": {
Expand Down Expand Up @@ -99,6 +101,14 @@ dev
t.Fatal(err)
}

projects := testCase.projects
for i, proj := range projects {
if len(projects) != len(testCase.displayNames) {
break
}
proj.(*management.Project).Spec.DisplayName = testCase.displayNames[i]
}

client := fake.NewClientBuilder().
WithScheme(scheme).
WithIndex(&management.Project{}, "metadata.name", func(o client.Object) []string {
Expand Down
53 changes: 53 additions & 0 deletions update/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package update

import (
"context"
"fmt"

"github.com/crossplane/crossplane-runtime/pkg/resource"
management "github.com/ninech/apis/management/v1alpha1"
"github.com/ninech/nctl/api"
"github.com/ninech/nctl/auth"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type projectCmd struct {
Name string `arg:"" default:"" help:"Name of the project to update."`
DisplayName *string `default:"" help:"Display Name of the project."`
}

func (cmd *projectCmd) Run(ctx context.Context, client *api.Client) error {
cfg, err := auth.ReadConfig(client.KubeconfigPath, client.KubeconfigContext)
if err != nil {
if auth.IsConfigNotFoundError(err) {
return auth.ReloginNeeded(err)
}
return err
}

project := &management.Project{
ObjectMeta: metav1.ObjectMeta{
Name: cmd.Name,
Namespace: cfg.Organization,
},
}

upd := newUpdater(client, project, management.ProjectKind, func(current resource.Managed) error {
project, ok := current.(*management.Project)
if !ok {
return fmt.Errorf("resource is of type %T, expected %T", current, management.Project{})
}

cmd.applyUpdates(project)

return nil
})

return upd.Update(ctx)
}

func (cmd *projectCmd) applyUpdates(project *management.Project) {
if cmd.DisplayName != nil {
project.Spec.DisplayName = *cmd.DisplayName
}
}
81 changes: 81 additions & 0 deletions update/project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package update

import (
"context"
"os"
"testing"

management "github.com/ninech/apis/management/v1alpha1"
"github.com/ninech/nctl/api"
"github.com/ninech/nctl/internal/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
)

func TestProject(t *testing.T) {
const (
projectName = "some-project"
organization = "org"
)
existingProject := &management.Project{
ObjectMeta: metav1.ObjectMeta{
Name: projectName,
Namespace: organization,
},
Spec: management.ProjectSpec{},
}

cases := map[string]struct {
orig *management.Project
project string
cmd projectCmd
checkProject func(t *testing.T, cmd projectCmd, orig, updated *management.Project)
}{
"all fields update": {
orig: existingProject,
project: projectName,
cmd: projectCmd{
Name: projectName,
DisplayName: ptr.To("some display name"),
},
checkProject: func(t *testing.T, cmd projectCmd, orig, updated *management.Project) {
assert.Equal(t, *cmd.DisplayName, updated.Spec.DisplayName)
},
},
}

for name, tc := range cases {
tc := tc

t.Run(name, func(t *testing.T) {
apiClient, err := test.SetupClient(tc.orig)
if err != nil {
t.Fatal(err)
}
apiClient.Project = tc.project

ctx := context.Background()

// we create a kubeconfig which does not contain a nctl config
// extension
kubeconfig, err := test.CreateTestKubeconfig(apiClient, organization)
require.NoError(t, err)
defer os.Remove(kubeconfig)

if err := tc.cmd.Run(ctx, apiClient); err != nil {
t.Fatal(err)
}

updated := &management.Project{}
if err := apiClient.Get(ctx, api.ObjectName(tc.orig), updated); err != nil {
t.Fatal(err)
}

if tc.checkProject != nil {
tc.checkProject(t, tc.cmd, tc.orig, updated)
}
})
}
}
3 changes: 2 additions & 1 deletion update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
type Cmd struct {
Application applicationCmd `cmd:"" group:"deplo.io" name:"application" aliases:"app" help:"Update an existing deplo.io Application. (Beta - requires access)"`
Config configCmd `cmd:"" group:"deplo.io" name:"config" help:"Update an existing deplo.io Project Configuration. (Beta - requires access)"`
Project projectCmd `cmd:"" group:"management.nine.ch" name:"project" help:"Update an existing Project"`
}

type updater struct {
Expand All @@ -27,7 +28,7 @@ func newUpdater(client *api.Client, mg resource.Managed, kind string, f updateFu
}

func (u *updater) Update(ctx context.Context) error {
if err := u.client.Get(ctx, u.client.Name(u.mg.GetName()), u.mg); err != nil {
if err := u.client.Get(ctx, api.ObjectName(u.mg), u.mg); err != nil {
return err
}

Expand Down

0 comments on commit cd36c2b

Please sign in to comment.