diff --git a/flytectl/clierrors/errors.go b/flytectl/clierrors/errors.go index 44e7368c05..4f22acf5af 100644 --- a/flytectl/clierrors/errors.go +++ b/flytectl/clierrors/errors.go @@ -3,8 +3,9 @@ package clierrors var ( ErrInvalidStateUpdate = "Invalid state passed. Specify either activate or archive\n" - ErrProjectNotPassed = "Project not passed\n" - ErrFailedProjectUpdate = "Project %v failed to get updated to %v state due to %v\n" + ErrProjectNotPassed = "Project not passed\n" + ErrProjectNameNotPassed = "project name is required flag" + ErrFailedProjectUpdate = "Project %v failed to get updated due to %v\n" ErrLPNotPassed = "Launch plan name not passed\n" ErrLPVersionNotPassed = "Launch plan version not passed\n" //nolint diff --git a/flytectl/cmd/config/subcommand/project/configproject_flags.go b/flytectl/cmd/config/subcommand/project/configproject_flags.go new file mode 100755 index 0000000000..e0e1c75f08 --- /dev/null +++ b/flytectl/cmd/config/subcommand/project/configproject_flags.go @@ -0,0 +1,64 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package project + +import ( + "encoding/json" + "reflect" + + "fmt" + + "github.com/spf13/pflag" +) + +// If v is a pointer, it will get its element value or the zero value of the element type. +// If v is not a pointer, it will return it as is. +func (ConfigProject) elemValueOrNil(v interface{}) interface{} { + if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr { + if reflect.ValueOf(v).IsNil() { + return reflect.Zero(t.Elem()).Interface() + } else { + return reflect.ValueOf(v).Interface() + } + } else if v == nil { + return reflect.Zero(t).Interface() + } + + return v +} + +func (ConfigProject) mustJsonMarshal(v interface{}) string { + raw, err := json.Marshal(v) + if err != nil { + panic(err) + } + + return string(raw) +} + +func (ConfigProject) mustMarshalJSON(v json.Marshaler) string { + raw, err := v.MarshalJSON() + if err != nil { + panic(err) + } + + return string(raw) +} + +// GetPFlagSet will return strongly types pflags for all fields in ConfigProject and its nested types. The format of the +// flags is json-name.json-sub-name... etc. +func (cfg ConfigProject) GetPFlagSet(prefix string) *pflag.FlagSet { + cmdFlags := pflag.NewFlagSet("ConfigProject", pflag.ExitOnError) + cmdFlags.StringVar(&DefaultProjectConfig.ID, fmt.Sprintf("%v%v", prefix, "id"), DefaultProjectConfig.ID, "id for the project specified as argument.") + cmdFlags.BoolVar(&DefaultProjectConfig.ActivateProject, fmt.Sprintf("%v%v", prefix, "activateProject"), DefaultProjectConfig.ActivateProject, "(Deprecated) Activates the project specified as argument. Only used in update") + cmdFlags.BoolVar(&DefaultProjectConfig.ArchiveProject, fmt.Sprintf("%v%v", prefix, "archiveProject"), DefaultProjectConfig.ArchiveProject, "(Deprecated) Archives the project specified as argument. Only used in update") + cmdFlags.BoolVar(&DefaultProjectConfig.Activate, fmt.Sprintf("%v%v", prefix, "activate"), DefaultProjectConfig.Activate, "Activates the project specified as argument. Only used in update") + cmdFlags.BoolVar(&DefaultProjectConfig.Archive, fmt.Sprintf("%v%v", prefix, "archive"), DefaultProjectConfig.Archive, "Archives the project specified as argument. Only used in update") + cmdFlags.StringVar(&DefaultProjectConfig.Name, fmt.Sprintf("%v%v", prefix, "name"), DefaultProjectConfig.Name, "name for the project specified as argument.") + cmdFlags.BoolVar(&DefaultProjectConfig.DryRun, fmt.Sprintf("%v%v", prefix, "dryRun"), DefaultProjectConfig.DryRun, "execute command without making any modifications.") + cmdFlags.StringVar(&DefaultProjectConfig.Description, fmt.Sprintf("%v%v", prefix, "description"), DefaultProjectConfig.Description, "description for the project specified as argument.") + cmdFlags.StringToStringVar(&DefaultProjectConfig.Labels, fmt.Sprintf("%v%v", prefix, "labels"), DefaultProjectConfig.Labels, "labels for the project specified as argument.") + cmdFlags.StringVar(&DefaultProjectConfig.File, fmt.Sprintf("%v%v", prefix, "file"), DefaultProjectConfig.File, "file for the project definition.") + return cmdFlags +} diff --git a/flytectl/cmd/create/projectconfig_flags_test.go b/flytectl/cmd/config/subcommand/project/configproject_flags_test.go similarity index 57% rename from flytectl/cmd/create/projectconfig_flags_test.go rename to flytectl/cmd/config/subcommand/project/configproject_flags_test.go index e05f201be8..abe5e1e627 100755 --- a/flytectl/cmd/create/projectconfig_flags_test.go +++ b/flytectl/cmd/config/subcommand/project/configproject_flags_test.go @@ -1,7 +1,7 @@ // Code generated by go generate; DO NOT EDIT. // This file was generated by robots. -package create +package project import ( "encoding/json" @@ -14,22 +14,22 @@ import ( "github.com/stretchr/testify/assert" ) -var dereferencableKindsProjectConfig = map[reflect.Kind]struct{}{ +var dereferencableKindsConfigProject = map[reflect.Kind]struct{}{ reflect.Array: {}, reflect.Chan: {}, reflect.Map: {}, reflect.Ptr: {}, reflect.Slice: {}, } // Checks if t is a kind that can be dereferenced to get its underlying type. -func canGetElementProjectConfig(t reflect.Kind) bool { - _, exists := dereferencableKindsProjectConfig[t] +func canGetElementConfigProject(t reflect.Kind) bool { + _, exists := dereferencableKindsConfigProject[t] return exists } // This decoder hook tests types for json unmarshaling capability. If implemented, it uses json unmarshal to build the // object. Otherwise, it'll just pass on the original data. -func jsonUnmarshalerHookProjectConfig(_, to reflect.Type, data interface{}) (interface{}, error) { +func jsonUnmarshalerHookConfigProject(_, to reflect.Type, data interface{}) (interface{}, error) { unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() if to.Implements(unmarshalerType) || reflect.PtrTo(to).Implements(unmarshalerType) || - (canGetElementProjectConfig(to.Kind()) && to.Elem().Implements(unmarshalerType)) { + (canGetElementConfigProject(to.Kind()) && to.Elem().Implements(unmarshalerType)) { raw, err := json.Marshal(data) if err != nil { @@ -50,7 +50,7 @@ func jsonUnmarshalerHookProjectConfig(_, to reflect.Type, data interface{}) (int return data, nil } -func decode_ProjectConfig(input, result interface{}) error { +func decode_ConfigProject(input, result interface{}) error { config := &mapstructure.DecoderConfig{ TagName: "json", WeaklyTypedInput: true, @@ -58,7 +58,7 @@ func decode_ProjectConfig(input, result interface{}) error { DecodeHook: mapstructure.ComposeDecodeHookFunc( mapstructure.StringToTimeDurationHookFunc(), mapstructure.StringToSliceHookFunc(","), - jsonUnmarshalerHookProjectConfig, + jsonUnmarshalerHookConfigProject, ), } @@ -70,7 +70,7 @@ func decode_ProjectConfig(input, result interface{}) error { return decoder.Decode(input) } -func join_ProjectConfig(arr interface{}, sep string) string { +func join_ConfigProject(arr interface{}, sep string) string { listValue := reflect.ValueOf(arr) strs := make([]string, 0, listValue.Len()) for i := 0; i < listValue.Len(); i++ { @@ -80,22 +80,22 @@ func join_ProjectConfig(arr interface{}, sep string) string { return strings.Join(strs, sep) } -func testDecodeJson_ProjectConfig(t *testing.T, val, result interface{}) { - assert.NoError(t, decode_ProjectConfig(val, result)) +func testDecodeJson_ConfigProject(t *testing.T, val, result interface{}) { + assert.NoError(t, decode_ConfigProject(val, result)) } -func testDecodeRaw_ProjectConfig(t *testing.T, vStringSlice, result interface{}) { - assert.NoError(t, decode_ProjectConfig(vStringSlice, result)) +func testDecodeRaw_ConfigProject(t *testing.T, vStringSlice, result interface{}) { + assert.NoError(t, decode_ConfigProject(vStringSlice, result)) } -func TestProjectConfig_GetPFlagSet(t *testing.T) { - val := ProjectConfig{} +func TestConfigProject_GetPFlagSet(t *testing.T) { + val := ConfigProject{} cmdFlags := val.GetPFlagSet("") assert.True(t, cmdFlags.HasFlags()) } -func TestProjectConfig_SetFlags(t *testing.T) { - actual := ProjectConfig{} +func TestConfigProject_SetFlags(t *testing.T) { + actual := ConfigProject{} cmdFlags := actual.GetPFlagSet("") assert.True(t, cmdFlags.HasFlags()) @@ -106,7 +106,63 @@ func TestProjectConfig_SetFlags(t *testing.T) { cmdFlags.Set("id", testValue) if vString, err := cmdFlags.GetString("id"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vString), &actual.ID) + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vString), &actual.ID) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) + t.Run("Test_activateProject", func(t *testing.T) { + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("activateProject", testValue) + if vBool, err := cmdFlags.GetBool("activateProject"); err == nil { + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vBool), &actual.ActivateProject) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) + t.Run("Test_archiveProject", func(t *testing.T) { + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("archiveProject", testValue) + if vBool, err := cmdFlags.GetBool("archiveProject"); err == nil { + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vBool), &actual.ArchiveProject) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) + t.Run("Test_activate", func(t *testing.T) { + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("activate", testValue) + if vBool, err := cmdFlags.GetBool("activate"); err == nil { + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vBool), &actual.Activate) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) + t.Run("Test_archive", func(t *testing.T) { + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("archive", testValue) + if vBool, err := cmdFlags.GetBool("archive"); err == nil { + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vBool), &actual.Archive) } else { assert.FailNow(t, err.Error()) @@ -120,21 +176,21 @@ func TestProjectConfig_SetFlags(t *testing.T) { cmdFlags.Set("name", testValue) if vString, err := cmdFlags.GetString("name"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vString), &actual.Name) + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vString), &actual.Name) } else { assert.FailNow(t, err.Error()) } }) }) - t.Run("Test_file", func(t *testing.T) { + t.Run("Test_dryRun", func(t *testing.T) { t.Run("Override", func(t *testing.T) { testValue := "1" - cmdFlags.Set("file", testValue) - if vString, err := cmdFlags.GetString("file"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vString), &actual.File) + cmdFlags.Set("dryRun", testValue) + if vBool, err := cmdFlags.GetBool("dryRun"); err == nil { + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vBool), &actual.DryRun) } else { assert.FailNow(t, err.Error()) @@ -148,7 +204,7 @@ func TestProjectConfig_SetFlags(t *testing.T) { cmdFlags.Set("description", testValue) if vString, err := cmdFlags.GetString("description"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vString), &actual.Description) + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vString), &actual.Description) } else { assert.FailNow(t, err.Error()) @@ -162,21 +218,21 @@ func TestProjectConfig_SetFlags(t *testing.T) { cmdFlags.Set("labels", testValue) if vStringToString, err := cmdFlags.GetStringToString("labels"); err == nil { - testDecodeRaw_ProjectConfig(t, vStringToString, &actual.Labels) + testDecodeRaw_ConfigProject(t, vStringToString, &actual.Labels) } else { assert.FailNow(t, err.Error()) } }) }) - t.Run("Test_dryRun", func(t *testing.T) { + t.Run("Test_file", func(t *testing.T) { t.Run("Override", func(t *testing.T) { testValue := "1" - cmdFlags.Set("dryRun", testValue) - if vBool, err := cmdFlags.GetBool("dryRun"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vBool), &actual.DryRun) + cmdFlags.Set("file", testValue) + if vString, err := cmdFlags.GetString("file"); err == nil { + testDecodeJson_ConfigProject(t, fmt.Sprintf("%v", vString), &actual.File) } else { assert.FailNow(t, err.Error()) diff --git a/flytectl/cmd/config/subcommand/project/project_config.go b/flytectl/cmd/config/subcommand/project/project_config.go index 8692a746cd..87b9d190ed 100644 --- a/flytectl/cmd/config/subcommand/project/project_config.go +++ b/flytectl/cmd/config/subcommand/project/project_config.go @@ -1,7 +1,14 @@ package project import ( + "fmt" + "io/ioutil" + + "github.com/flyteorg/flytectl/clierrors" + "github.com/flyteorg/flytectl/pkg/filters" + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" + "gopkg.in/yaml.v2" ) //go:generate pflags Config --default-var DefaultConfig --bind-default-var @@ -11,7 +18,75 @@ var ( } ) -// Config +// Config holds the flag for get project type Config struct { Filter filters.Filters `json:"filter" pflag:","` } + +//go:generate pflags ConfigProject --default-var DefaultProjectConfig --bind-default-var + +// ConfigProject hold configuration for project update flags. +type ConfigProject struct { + ID string `json:"id" pflag:",id for the project specified as argument."` + ActivateProject bool `json:"activateProject" pflag:",(Deprecated) Activates the project specified as argument. Only used in update"` + ArchiveProject bool `json:"archiveProject" pflag:",(Deprecated) Archives the project specified as argument. Only used in update"` + Activate bool `json:"activate" pflag:",Activates the project specified as argument. Only used in update"` + Archive bool `json:"archive" pflag:",Archives the project specified as argument. Only used in update"` + Name string `json:"name" pflag:",name for the project specified as argument."` + DryRun bool `json:"dryRun" pflag:",execute command without making any modifications."` + Description string `json:"description" pflag:",description for the project specified as argument."` + Labels map[string]string `json:"labels" pflag:",labels for the project specified as argument."` + File string `json:"file" pflag:",file for the project definition."` +} + +var DefaultProjectConfig = &ConfigProject{ + Description: "", + Labels: map[string]string{}, +} + +//GetProjectSpec return project spec from a file/flags +func (c *ConfigProject) GetProjectSpec(id string) (*admin.Project, error) { + projectSpec := admin.Project{} + if len(c.File) > 0 { + yamlFile, err := ioutil.ReadFile(c.File) + if err != nil { + return nil, err + } + err = yaml.Unmarshal(yamlFile, &projectSpec) + if err != nil { + return nil, err + } + return &projectSpec, nil + } + + projectSpec.Id = id + projectSpec.Name = c.Name + projectSpec.Description = c.Description + projectSpec.Labels = &admin.Labels{ + Values: c.Labels, + } + return &projectSpec, nil +} + +//MapToAdminState return project spec from a file/flags +func (c *ConfigProject) MapToAdminState() (admin.Project_ProjectState, error) { + if c.ActivateProject { + c.Activate = c.ActivateProject + } + if c.ArchiveProject { + c.Archive = c.ArchiveProject + } + + activate := c.Activate + archive := c.Archive + + if activate || archive { + if activate == archive { + return admin.Project_ACTIVE, fmt.Errorf(clierrors.ErrInvalidStateUpdate) + } + if archive { + return admin.Project_ARCHIVED, nil + } + } + return admin.Project_ACTIVE, nil +} diff --git a/flytectl/cmd/config/subcommand/project/project_config_test.go b/flytectl/cmd/config/subcommand/project/project_config_test.go new file mode 100644 index 0000000000..fdad3cc33a --- /dev/null +++ b/flytectl/cmd/config/subcommand/project/project_config_test.go @@ -0,0 +1,27 @@ +package project + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetProjectSpec(t *testing.T) { + t.Run("Successful get project spec", func(t *testing.T) { + c := &ConfigProject{ + Name: "flytesnacks", + } + response, err := c.GetProjectSpec("flytesnacks") + assert.Nil(t, err) + assert.NotNil(t, response) + }) + t.Run("Successful get request spec from file", func(t *testing.T) { + c := &ConfigProject{ + File: "testdata/project.yaml", + } + response, err := c.GetProjectSpec("flytesnacks") + assert.Nil(t, err) + assert.Equal(t, "flytesnacks", response.Name) + assert.Equal(t, "flytesnacks test", response.Description) + }) +} diff --git a/flytectl/cmd/config/subcommand/project/testdata/project.yaml b/flytectl/cmd/config/subcommand/project/testdata/project.yaml new file mode 100644 index 0000000000..8b5fd32841 --- /dev/null +++ b/flytectl/cmd/config/subcommand/project/testdata/project.yaml @@ -0,0 +1,14 @@ +description: flytesnacks test +domains: + - id: development + name: development + - id: staging + name: staging + - id: production + name: production +id: flytesnacks +labels: + values: + team: flytesnacks +name: flytesnacks + diff --git a/flytectl/cmd/config/subcommand/project/testdata/project_error.yaml b/flytectl/cmd/config/subcommand/project/testdata/project_error.yaml new file mode 100644 index 0000000000..0b7088ec63 --- /dev/null +++ b/flytectl/cmd/config/subcommand/project/testdata/project_error.yaml @@ -0,0 +1 @@ +Data diff --git a/flytectl/cmd/create/create.go b/flytectl/cmd/create/create.go index 54ad53cf22..20cbefb54e 100644 --- a/flytectl/cmd/create/create.go +++ b/flytectl/cmd/create/create.go @@ -1,6 +1,7 @@ package create import ( + "github.com/flyteorg/flytectl/cmd/config/subcommand/project" cmdcore "github.com/flyteorg/flytectl/cmd/core" "github.com/spf13/cobra" @@ -25,7 +26,7 @@ func RemoteCreateCommand() *cobra.Command { Long: createCmdLong, } createResourcesFuncs := map[string]cmdcore.CommandEntry{ - "project": {CmdFunc: createProjectsCommand, Aliases: []string{"projects"}, ProjectDomainNotRequired: true, PFlagProvider: projectConfig, Short: projectShort, + "project": {CmdFunc: createProjectsCommand, Aliases: []string{"projects"}, ProjectDomainNotRequired: true, PFlagProvider: project.DefaultProjectConfig, Short: projectShort, Long: projectLong}, "execution": {CmdFunc: createExecutionCommand, Aliases: []string{"executions"}, ProjectDomainNotRequired: false, PFlagProvider: executionConfig, Short: executionShort, Long: executionLong}, diff --git a/flytectl/cmd/create/project.go b/flytectl/cmd/create/project.go index dec5a7322d..9cc2ecf68a 100644 --- a/flytectl/cmd/create/project.go +++ b/flytectl/cmd/create/project.go @@ -3,10 +3,12 @@ package create import ( "context" "fmt" - "io/ioutil" + "github.com/flyteorg/flytectl/clierrors" + "github.com/flyteorg/flytectl/cmd/config" + + "github.com/flyteorg/flytectl/cmd/config/subcommand/project" "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" - "gopkg.in/yaml.v2" cmdCore "github.com/flyteorg/flytectl/cmd/core" "github.com/flyteorg/flytestdlib/logger" @@ -31,65 +33,34 @@ Create a project by definition file. Note: The name shouldn't contain any whites id: "project-unique-id" name: "Name" labels: - app: flyte + values: + app: flyte description: "Some description for the project" ` ) -//go:generate pflags ProjectConfig --default-var projectConfig --bind-default-var - -// ProjectConfig Config hold configuration for project create flags. -type ProjectConfig struct { - ID string `json:"id" pflag:",id for the project specified as argument."` - Name string `json:"name" pflag:",name for the project specified as argument."` - File string `json:"file" pflag:",file for the project definition."` - Description string `json:"description" pflag:",description for the project specified as argument."` - Labels map[string]string `json:"labels" pflag:",labels for the project specified as argument."` - DryRun bool `json:"dryRun" pflag:",execute command without making any modifications."` -} - -var ( - projectConfig = &ProjectConfig{ - Description: "", - Labels: map[string]string{}, - } -) - func createProjectsCommand(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error { - project := projectDefinition{} - if projectConfig.File != "" { - yamlFile, err := ioutil.ReadFile(projectConfig.File) - if err != nil { - return err - } - err = yaml.Unmarshal(yamlFile, &project) - if err != nil { - return err - } - } else { - project.ID = projectConfig.ID - project.Name = projectConfig.Name - project.Description = projectConfig.Description - project.Labels = projectConfig.Labels + projectSpec, err := project.DefaultProjectConfig.GetProjectSpec(config.GetConfig().Project) + if err != nil { + return err } - if project.ID == "" { - return fmt.Errorf("project ID is required flag") + if projectSpec.Id == "" { + return fmt.Errorf(clierrors.ErrProjectNotPassed) } - if project.Name == "" { - return fmt.Errorf("project name is required flag") + if projectSpec.Name == "" { + return fmt.Errorf(clierrors.ErrProjectNameNotPassed) } - if projectConfig.DryRun { + + if project.DefaultProjectConfig.DryRun { logger.Debugf(ctx, "skipping RegisterProject request (DryRun)") } else { _, err := cmdCtx.AdminClient().RegisterProject(ctx, &admin.ProjectRegisterRequest{ Project: &admin.Project{ - Id: project.ID, - Name: project.Name, - Description: project.Description, - Labels: &admin.Labels{ - Values: project.Labels, - }, + Id: projectSpec.Id, + Name: projectSpec.Name, + Description: projectSpec.Description, + Labels: projectSpec.Labels, }, }) if err != nil { diff --git a/flytectl/cmd/create/project_test.go b/flytectl/cmd/create/project_test.go index 8f4bb309b0..ef55e5b365 100644 --- a/flytectl/cmd/create/project_test.go +++ b/flytectl/cmd/create/project_test.go @@ -1,9 +1,14 @@ package create import ( + "errors" "fmt" "testing" + "github.com/flyteorg/flytectl/clierrors" + + "github.com/flyteorg/flytectl/cmd/config/subcommand/project" + "github.com/flyteorg/flytectl/cmd/testutils" "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" @@ -31,19 +36,19 @@ func createProjectSetup() { }, }, } - projectConfig.ID = "" - projectConfig.Name = "" - projectConfig.Labels = map[string]string{} - projectConfig.Description = "" + project.DefaultProjectConfig.ID = "" + project.DefaultProjectConfig.Name = "" + project.DefaultProjectConfig.Labels = map[string]string{} + project.DefaultProjectConfig.Description = "" } func TestCreateProjectFunc(t *testing.T) { setup() createProjectSetup() defer tearDownAndVerify(t, "project Created successfully") - projectConfig.ID = projectValue - projectConfig.Name = projectValue - projectConfig.Labels = map[string]string{} - projectConfig.Description = "" + project.DefaultProjectConfig.ID = projectValue + project.DefaultProjectConfig.Name = projectValue + project.DefaultProjectConfig.Labels = map[string]string{} + project.DefaultProjectConfig.Description = "" mockClient.OnRegisterProjectMatch(ctx, projectRegisterRequest).Return(nil, nil) err := createProjectsCommand(ctx, args, cmdCtx) assert.Nil(t, err) @@ -54,11 +59,10 @@ func TestEmptyProjectID(t *testing.T) { setup() createProjectSetup() defer tearDownAndVerify(t, "") - projectConfig.Name = projectValue - projectConfig.Labels = map[string]string{} + project.DefaultProjectConfig = &project.ConfigProject{} mockClient.OnRegisterProjectMatch(ctx, projectRegisterRequest).Return(nil, nil) err := createProjectsCommand(ctx, args, cmdCtx) - assert.Equal(t, fmt.Errorf("project ID is required flag"), err) + assert.Equal(t, errors.New(clierrors.ErrProjectNameNotPassed), err) mockClient.AssertNotCalled(t, "RegisterProject", ctx, mock.Anything) } @@ -66,9 +70,9 @@ func TestEmptyProjectName(t *testing.T) { setup() createProjectSetup() defer tearDownAndVerify(t, "") - projectConfig.ID = projectValue - projectConfig.Labels = map[string]string{} - projectConfig.Description = "" + project.DefaultProjectConfig.ID = projectValue + project.DefaultProjectConfig.Labels = map[string]string{} + project.DefaultProjectConfig.Description = "" mockClient.OnRegisterProjectMatch(ctx, projectRegisterRequest).Return(nil, nil) err := createProjectsCommand(ctx, args, cmdCtx) assert.Equal(t, fmt.Errorf("project name is required flag"), err) diff --git a/flytectl/cmd/create/projectconfig_flags.go b/flytectl/cmd/create/projectconfig_flags.go deleted file mode 100755 index b9e0c0607c..0000000000 --- a/flytectl/cmd/create/projectconfig_flags.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots. - -package create - -import ( - "encoding/json" - "reflect" - - "fmt" - - "github.com/spf13/pflag" -) - -// If v is a pointer, it will get its element value or the zero value of the element type. -// If v is not a pointer, it will return it as is. -func (ProjectConfig) elemValueOrNil(v interface{}) interface{} { - if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr { - if reflect.ValueOf(v).IsNil() { - return reflect.Zero(t.Elem()).Interface() - } else { - return reflect.ValueOf(v).Interface() - } - } else if v == nil { - return reflect.Zero(t).Interface() - } - - return v -} - -func (ProjectConfig) mustJsonMarshal(v interface{}) string { - raw, err := json.Marshal(v) - if err != nil { - panic(err) - } - - return string(raw) -} - -func (ProjectConfig) mustMarshalJSON(v json.Marshaler) string { - raw, err := v.MarshalJSON() - if err != nil { - panic(err) - } - - return string(raw) -} - -// GetPFlagSet will return strongly types pflags for all fields in ProjectConfig and its nested types. The format of the -// flags is json-name.json-sub-name... etc. -func (cfg ProjectConfig) GetPFlagSet(prefix string) *pflag.FlagSet { - cmdFlags := pflag.NewFlagSet("ProjectConfig", pflag.ExitOnError) - cmdFlags.StringVar(&projectConfig.ID, fmt.Sprintf("%v%v", prefix, "id"), projectConfig.ID, "id for the project specified as argument.") - cmdFlags.StringVar(&projectConfig.Name, fmt.Sprintf("%v%v", prefix, "name"), projectConfig.Name, "name for the project specified as argument.") - cmdFlags.StringVar(&projectConfig.File, fmt.Sprintf("%v%v", prefix, "file"), projectConfig.File, "file for the project definition.") - cmdFlags.StringVar(&projectConfig.Description, fmt.Sprintf("%v%v", prefix, "description"), projectConfig.Description, "description for the project specified as argument.") - cmdFlags.StringToStringVar(&projectConfig.Labels, fmt.Sprintf("%v%v", prefix, "labels"), projectConfig.Labels, "labels for the project specified as argument.") - cmdFlags.BoolVar(&projectConfig.DryRun, fmt.Sprintf("%v%v", prefix, "dryRun"), projectConfig.DryRun, "execute command without making any modifications.") - return cmdFlags -} diff --git a/flytectl/cmd/create/type.go b/flytectl/cmd/create/type.go deleted file mode 100644 index 61709eb6ef..0000000000 --- a/flytectl/cmd/create/type.go +++ /dev/null @@ -1,8 +0,0 @@ -package create - -type projectDefinition struct { - ID string `yaml:"id"` - Name string `yaml:"name"` - Description string `yaml:"description"` - Labels map[string]string `yaml:"labels"` -} diff --git a/flytectl/cmd/get/project.go b/flytectl/cmd/get/project.go index 8855b020b2..03f1826059 100644 --- a/flytectl/cmd/get/project.go +++ b/flytectl/cmd/get/project.go @@ -82,10 +82,10 @@ func getProjectsFunc(ctx context.Context, args []string, cmdCtx cmdCore.CommandC } if len(args) == 1 { - name := args[0] + id := args[0] logger.Debugf(ctx, "Retrieved %v projects", len(projects.Projects)) for _, v := range projects.Projects { - if v.Name == name { + if v.Id == id { err := adminPrinter.Print(config.GetConfig().MustOutputFormat(), projectColumns, v) if err != nil { return err diff --git a/flytectl/cmd/update/project.go b/flytectl/cmd/update/project.go index 330afe395c..fd5ff592ff 100644 --- a/flytectl/cmd/update/project.go +++ b/flytectl/cmd/update/project.go @@ -4,23 +4,14 @@ import ( "context" "fmt" - "github.com/flyteorg/flytectl/clierrors" - "github.com/flyteorg/flytectl/cmd/config" + + "github.com/flyteorg/flytectl/clierrors" + "github.com/flyteorg/flytectl/cmd/config/subcommand/project" cmdCore "github.com/flyteorg/flytectl/cmd/core" - "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" "github.com/flyteorg/flytestdlib/logger" ) -//go:generate pflags ProjectConfig --default-var DefaultProjectConfig --bind-default-var - -// Config hold configuration for project update flags. -type ProjectConfig struct { - ActivateProject bool `json:"activateProject" pflag:",Activates the project specified as argument."` - ArchiveProject bool `json:"archiveProject" pflag:",Archives the project specified as argument."` - DryRun bool `json:"dryRun" pflag:",execute command without making any modifications."` -} - const ( projectShort = "Update project resources" projectLong = ` @@ -28,65 +19,96 @@ Updates the project according to the flags passed. Allows you to archive or acti Activate project flytesnacks: :: - flytectl update project -p flytesnacks --activateProject + flytectl update project -p flytesnacks --activate Archive project flytesnacks: :: - flytectl update project -p flytesnacks --archiveProject + flytectl update project -p flytesnacks --archive Incorrect usage when passing both archive and activate: :: - flytectl update project flytesnacks --archiveProject --activateProject + flytectl update project -p flytesnacks --archiveProject --activate Incorrect usage when passing unknown-project: +:: + + flytectl update project unknown-project --archive + +project ID is required flag + :: flytectl update project unknown-project --archiveProject -Incorrect usage when passing valid project using -p option: +Update projects.(project/projects can be used interchangeably in these commands) + +:: + + flytectl update project -p flytesnacks --description "flytesnacks description" --labels app=flyte + +Update a project by definition file. Note: The name shouldn't contain any whitespace characters. +:: + + flytectl update project --file project.yaml + +.. code-block:: yaml + id: "project-unique-id" + name: "Name" + labels: + values: + app: flyte + description: "Some description for the project" + +Update a project state by definition file. Note: The name shouldn't contain any whitespace characters. :: - flytectl update project unknown-project --archiveProject -p known-project + flytectl update project --file project.yaml --archive + +.. code-block:: yaml + + id: "project-unique-id" + name: "Name" + labels: + values: + app: flyte + description: "Some description for the project" Usage ` ) -var DefaultProjectConfig = &ProjectConfig{} - func updateProjectsFunc(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error { - id := config.GetConfig().Project - if id == "" { - fmt.Printf(clierrors.ErrProjectNotPassed) - return nil + projectSpec, err := project.DefaultProjectConfig.GetProjectSpec(config.GetConfig().Project) + if err != nil { + return err + } + if projectSpec.Id == "" { + return fmt.Errorf(clierrors.ErrProjectNotPassed) } - archiveProject := DefaultProjectConfig.ArchiveProject - activateProject := DefaultProjectConfig.ActivateProject - if activateProject == archiveProject { - return fmt.Errorf(clierrors.ErrInvalidStateUpdate) + if projectSpec.Name == "" { + return fmt.Errorf(clierrors.ErrProjectNameNotPassed) } - projectState := admin.Project_ACTIVE - if archiveProject { - projectState = admin.Project_ARCHIVED + + state, err := project.DefaultProjectConfig.MapToAdminState() + if err != nil { + return err } - if DefaultProjectConfig.DryRun { + projectSpec.State = state + if project.DefaultProjectConfig.DryRun { logger.Infof(ctx, "skipping UpdateProject request (dryRun)") } else { - _, err := cmdCtx.AdminClient().UpdateProject(ctx, &admin.Project{ - Id: id, - State: projectState, - }) + _, err := cmdCtx.AdminClient().UpdateProject(ctx, projectSpec) if err != nil { - fmt.Printf(clierrors.ErrFailedProjectUpdate, id, projectState, err) + fmt.Printf(clierrors.ErrFailedProjectUpdate, projectSpec.Id, err) return err } } - fmt.Printf("Project %v updated to %v state\n", id, projectState) + fmt.Printf("Project %v updated\n", projectSpec.Id) return nil } diff --git a/flytectl/cmd/update/project_test.go b/flytectl/cmd/update/project_test.go index 9db9f8cf46..b6b16702b6 100644 --- a/flytectl/cmd/update/project_test.go +++ b/flytectl/cmd/update/project_test.go @@ -5,6 +5,8 @@ import ( "fmt" "testing" + "github.com/flyteorg/flytectl/cmd/config/subcommand/project" + "github.com/flyteorg/flytectl/clierrors" "github.com/flyteorg/flytectl/cmd/config" u "github.com/flyteorg/flytectl/cmd/testutils" @@ -37,75 +39,107 @@ func modifyProjectFlags(archiveProject *bool, newArchiveVal bool, activateProjec func TestActivateProjectFunc(t *testing.T) { setup() updateProjectSetup() - modifyProjectFlags(&(DefaultProjectConfig.ArchiveProject), false, &(DefaultProjectConfig.ActivateProject), true) + config.GetConfig().Project = projectValue + project.DefaultProjectConfig.Name = projectValue + modifyProjectFlags(&(project.DefaultProjectConfig.ArchiveProject), false, &(project.DefaultProjectConfig.ActivateProject), true) + projectUpdateRequest = &admin.Project{ + Id: projectValue, + Name: projectValue, + Labels: &admin.Labels{ + Values: map[string]string{}, + }, + State: admin.Project_ACTIVE, + } mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) err = updateProjectsFunc(ctx, args, cmdCtx) assert.Nil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) - tearDownAndVerify(t, "Project dummyProject updated to ACTIVE state\n") + tearDownAndVerify(t, "Project dummyProject updated\n") } func TestActivateProjectFuncWithError(t *testing.T) { setup() updateProjectSetup() - modifyProjectFlags(&(DefaultProjectConfig.ArchiveProject), false, &(DefaultProjectConfig.ActivateProject), true) + config.GetConfig().Project = projectValue + project.DefaultProjectConfig.Name = projectValue + modifyProjectFlags(&(project.DefaultProjectConfig.ArchiveProject), false, &(project.DefaultProjectConfig.ActivateProject), true) + projectUpdateRequest = &admin.Project{ + Id: projectValue, + Name: projectValue, + Labels: &admin.Labels{ + Values: map[string]string{}, + }, + State: admin.Project_ACTIVE, + } mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, errors.New("Error Updating Project")) err = updateProjectsFunc(ctx, args, cmdCtx) assert.NotNil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) - tearDownAndVerify(t, "Project dummyProject failed to get updated to ACTIVE state due to Error Updating Project\n") + tearDownAndVerify(t, "Project dummyProject failed to get updated due to Error Updating Project\n") } func TestArchiveProjectFunc(t *testing.T) { setup() updateProjectSetup() - modifyProjectFlags(&(DefaultProjectConfig.ArchiveProject), true, &(DefaultProjectConfig.ActivateProject), false) + config.GetConfig().Project = projectValue + project.DefaultProjectConfig = &project.ConfigProject{} + project.DefaultProjectConfig.Name = projectValue + modifyProjectFlags(&(project.DefaultProjectConfig.ArchiveProject), true, &(project.DefaultProjectConfig.ActivateProject), false) projectUpdateRequest = &admin.Project{ - Id: projectValue, + Id: projectValue, + Name: projectValue, + Labels: &admin.Labels{ + Values: nil, + }, State: admin.Project_ARCHIVED, } mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) err = updateProjectsFunc(ctx, args, cmdCtx) assert.Nil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) - tearDownAndVerify(t, "Project dummyProject updated to ARCHIVED state\n") + tearDownAndVerify(t, "Project dummyProject updated\n") } func TestArchiveProjectFuncWithError(t *testing.T) { setup() updateProjectSetup() - modifyProjectFlags(&(DefaultProjectConfig.ArchiveProject), true, &(DefaultProjectConfig.ActivateProject), false) + project.DefaultProjectConfig.Name = projectValue + project.DefaultProjectConfig.Labels = map[string]string{} + modifyProjectFlags(&(project.DefaultProjectConfig.ArchiveProject), true, &(project.DefaultProjectConfig.ActivateProject), false) projectUpdateRequest = &admin.Project{ - Id: projectValue, + Id: projectValue, + Name: projectValue, + Labels: &admin.Labels{ + Values: map[string]string{}, + }, State: admin.Project_ARCHIVED, } mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, errors.New("Error Updating Project")) err = updateProjectsFunc(ctx, args, cmdCtx) assert.NotNil(t, err) mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest) - tearDownAndVerify(t, "Project dummyProject failed to get updated to ARCHIVED state due to Error Updating Project\n") + tearDownAndVerify(t, "Project dummyProject failed to get updated"+ + " due to Error Updating Project\n") } func TestEmptyProjectInput(t *testing.T) { setup() updateProjectSetup() config.GetConfig().Project = "" - modifyProjectFlags(&(DefaultProjectConfig.ArchiveProject), false, &(DefaultProjectConfig.ActivateProject), true) - mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) + modifyProjectFlags(&(project.DefaultProjectConfig.ArchiveProject), false, &(project.DefaultProjectConfig.ActivateProject), true) err = updateProjectsFunc(ctx, args, cmdCtx) - assert.Nil(t, err) - mockClient.AssertNotCalled(t, "UpdateProject", ctx, projectUpdateRequest) - tearDownAndVerify(t, "Project not passed") + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf(clierrors.ErrProjectNotPassed), err) } func TestInvalidInput(t *testing.T) { setup() updateProjectSetup() - modifyProjectFlags(&(DefaultProjectConfig.ArchiveProject), false, &(DefaultProjectConfig.ActivateProject), false) - mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil) + config.GetConfig().Project = projectValue + project.DefaultProjectConfig.Name = projectValue + modifyProjectFlags(&(project.DefaultProjectConfig.ArchiveProject), true, &(project.DefaultProjectConfig.ActivateProject), true) err = updateProjectsFunc(ctx, args, cmdCtx) assert.NotNil(t, err) assert.Equal(t, fmt.Errorf(clierrors.ErrInvalidStateUpdate), err) - mockClient.AssertNotCalled(t, "UpdateProject", ctx, projectUpdateRequest) tearDownAndVerify(t, "") } diff --git a/flytectl/cmd/update/projectconfig_flags.go b/flytectl/cmd/update/projectconfig_flags.go deleted file mode 100755 index 9c700f5e7c..0000000000 --- a/flytectl/cmd/update/projectconfig_flags.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots. - -package update - -import ( - "encoding/json" - "reflect" - - "fmt" - - "github.com/spf13/pflag" -) - -// If v is a pointer, it will get its element value or the zero value of the element type. -// If v is not a pointer, it will return it as is. -func (ProjectConfig) elemValueOrNil(v interface{}) interface{} { - if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr { - if reflect.ValueOf(v).IsNil() { - return reflect.Zero(t.Elem()).Interface() - } else { - return reflect.ValueOf(v).Interface() - } - } else if v == nil { - return reflect.Zero(t).Interface() - } - - return v -} - -func (ProjectConfig) mustJsonMarshal(v interface{}) string { - raw, err := json.Marshal(v) - if err != nil { - panic(err) - } - - return string(raw) -} - -func (ProjectConfig) mustMarshalJSON(v json.Marshaler) string { - raw, err := v.MarshalJSON() - if err != nil { - panic(err) - } - - return string(raw) -} - -// GetPFlagSet will return strongly types pflags for all fields in ProjectConfig and its nested types. The format of the -// flags is json-name.json-sub-name... etc. -func (cfg ProjectConfig) GetPFlagSet(prefix string) *pflag.FlagSet { - cmdFlags := pflag.NewFlagSet("ProjectConfig", pflag.ExitOnError) - cmdFlags.BoolVar(&DefaultProjectConfig.ActivateProject, fmt.Sprintf("%v%v", prefix, "activateProject"), DefaultProjectConfig.ActivateProject, "Activates the project specified as argument.") - cmdFlags.BoolVar(&DefaultProjectConfig.ArchiveProject, fmt.Sprintf("%v%v", prefix, "archiveProject"), DefaultProjectConfig.ArchiveProject, "Archives the project specified as argument.") - cmdFlags.BoolVar(&DefaultProjectConfig.DryRun, fmt.Sprintf("%v%v", prefix, "dryRun"), DefaultProjectConfig.DryRun, "execute command without making any modifications.") - return cmdFlags -} diff --git a/flytectl/cmd/update/projectconfig_flags_test.go b/flytectl/cmd/update/projectconfig_flags_test.go deleted file mode 100755 index cfcf48b4c4..0000000000 --- a/flytectl/cmd/update/projectconfig_flags_test.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots. - -package update - -import ( - "encoding/json" - "fmt" - "reflect" - "strings" - "testing" - - "github.com/mitchellh/mapstructure" - "github.com/stretchr/testify/assert" -) - -var dereferencableKindsProjectConfig = map[reflect.Kind]struct{}{ - reflect.Array: {}, reflect.Chan: {}, reflect.Map: {}, reflect.Ptr: {}, reflect.Slice: {}, -} - -// Checks if t is a kind that can be dereferenced to get its underlying type. -func canGetElementProjectConfig(t reflect.Kind) bool { - _, exists := dereferencableKindsProjectConfig[t] - return exists -} - -// This decoder hook tests types for json unmarshaling capability. If implemented, it uses json unmarshal to build the -// object. Otherwise, it'll just pass on the original data. -func jsonUnmarshalerHookProjectConfig(_, to reflect.Type, data interface{}) (interface{}, error) { - unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() - if to.Implements(unmarshalerType) || reflect.PtrTo(to).Implements(unmarshalerType) || - (canGetElementProjectConfig(to.Kind()) && to.Elem().Implements(unmarshalerType)) { - - raw, err := json.Marshal(data) - if err != nil { - fmt.Printf("Failed to marshal Data: %v. Error: %v. Skipping jsonUnmarshalHook", data, err) - return data, nil - } - - res := reflect.New(to).Interface() - err = json.Unmarshal(raw, &res) - if err != nil { - fmt.Printf("Failed to umarshal Data: %v. Error: %v. Skipping jsonUnmarshalHook", data, err) - return data, nil - } - - return res, nil - } - - return data, nil -} - -func decode_ProjectConfig(input, result interface{}) error { - config := &mapstructure.DecoderConfig{ - TagName: "json", - WeaklyTypedInput: true, - Result: result, - DecodeHook: mapstructure.ComposeDecodeHookFunc( - mapstructure.StringToTimeDurationHookFunc(), - mapstructure.StringToSliceHookFunc(","), - jsonUnmarshalerHookProjectConfig, - ), - } - - decoder, err := mapstructure.NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -func join_ProjectConfig(arr interface{}, sep string) string { - listValue := reflect.ValueOf(arr) - strs := make([]string, 0, listValue.Len()) - for i := 0; i < listValue.Len(); i++ { - strs = append(strs, fmt.Sprintf("%v", listValue.Index(i))) - } - - return strings.Join(strs, sep) -} - -func testDecodeJson_ProjectConfig(t *testing.T, val, result interface{}) { - assert.NoError(t, decode_ProjectConfig(val, result)) -} - -func testDecodeRaw_ProjectConfig(t *testing.T, vStringSlice, result interface{}) { - assert.NoError(t, decode_ProjectConfig(vStringSlice, result)) -} - -func TestProjectConfig_GetPFlagSet(t *testing.T) { - val := ProjectConfig{} - cmdFlags := val.GetPFlagSet("") - assert.True(t, cmdFlags.HasFlags()) -} - -func TestProjectConfig_SetFlags(t *testing.T) { - actual := ProjectConfig{} - cmdFlags := actual.GetPFlagSet("") - assert.True(t, cmdFlags.HasFlags()) - - t.Run("Test_activateProject", func(t *testing.T) { - - t.Run("Override", func(t *testing.T) { - testValue := "1" - - cmdFlags.Set("activateProject", testValue) - if vBool, err := cmdFlags.GetBool("activateProject"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vBool), &actual.ActivateProject) - - } else { - assert.FailNow(t, err.Error()) - } - }) - }) - t.Run("Test_archiveProject", func(t *testing.T) { - - t.Run("Override", func(t *testing.T) { - testValue := "1" - - cmdFlags.Set("archiveProject", testValue) - if vBool, err := cmdFlags.GetBool("archiveProject"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vBool), &actual.ArchiveProject) - - } else { - assert.FailNow(t, err.Error()) - } - }) - }) - t.Run("Test_dryRun", func(t *testing.T) { - - t.Run("Override", func(t *testing.T) { - testValue := "1" - - cmdFlags.Set("dryRun", testValue) - if vBool, err := cmdFlags.GetBool("dryRun"); err == nil { - testDecodeJson_ProjectConfig(t, fmt.Sprintf("%v", vBool), &actual.DryRun) - - } else { - assert.FailNow(t, err.Error()) - } - }) - }) -} diff --git a/flytectl/cmd/update/update.go b/flytectl/cmd/update/update.go index 57a391b2a6..ef1c2b66a8 100644 --- a/flytectl/cmd/update/update.go +++ b/flytectl/cmd/update/update.go @@ -7,6 +7,7 @@ import ( "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" "github.com/flyteorg/flytectl/cmd/config/subcommand/launchplan" pluginoverride "github.com/flyteorg/flytectl/cmd/config/subcommand/plugin_override" + "github.com/flyteorg/flytectl/cmd/config/subcommand/project" "github.com/flyteorg/flytectl/cmd/config/subcommand/taskresourceattribute" "github.com/flyteorg/flytectl/cmd/config/subcommand/workflowexecutionconfig" cmdCore "github.com/flyteorg/flytectl/cmd/core" @@ -40,7 +41,7 @@ func CreateUpdateCommand() *cobra.Command { Short: updateLPShort, Long: updateLPLong}, "launchplan-meta": {CmdFunc: updateLPMetaFunc, Aliases: []string{}, ProjectDomainNotRequired: false, PFlagProvider: namedEntityConfig, Short: updateLPMetaShort, Long: updateLPMetaLong}, - "project": {CmdFunc: updateProjectsFunc, Aliases: []string{}, ProjectDomainNotRequired: true, PFlagProvider: DefaultProjectConfig, + "project": {CmdFunc: updateProjectsFunc, Aliases: []string{}, ProjectDomainNotRequired: true, PFlagProvider: project.DefaultProjectConfig, Short: projectShort, Long: projectLong}, "execution": {CmdFunc: updateExecutionFunc, Aliases: []string{}, ProjectDomainNotRequired: false, PFlagProvider: execution.UConfig, Short: updateExecutionShort, Long: updateExecutionLong}, diff --git a/flytectl/doc-requirements.txt b/flytectl/doc-requirements.txt index 549d2907c6..f0ff7cad16 100644 --- a/flytectl/doc-requirements.txt +++ b/flytectl/doc-requirements.txt @@ -23,7 +23,7 @@ docutils==0.17.1 # via # sphinx # sphinx-panels -git+https://github.com/flyteorg/furo@main +furo @ git+https://github.com/flyteorg/furo@main # via -r doc-requirements.in idna==3.3 # via requests diff --git a/flytectl/pkg/util/util.go b/flytectl/pkg/util/util.go index 9dbc7e7c62..31c01db225 100644 --- a/flytectl/pkg/util/util.go +++ b/flytectl/pkg/util/util.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "net/http" + "os" "strings"