diff --git a/cmd/config/subcommand/executionqueueattribute/attrdeleteconfig_flags.go b/cmd/config/subcommand/executionqueueattribute/attrdeleteconfig_flags.go new file mode 100755 index 0000000000..15852717de --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/attrdeleteconfig_flags.go @@ -0,0 +1,46 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package executionqueueattribute + +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 (AttrDeleteConfig) 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 (AttrDeleteConfig) 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 AttrDeleteConfig and its nested types. The format of the +// flags is json-name.json-sub-name... etc. +func (cfg AttrDeleteConfig) GetPFlagSet(prefix string) *pflag.FlagSet { + cmdFlags := pflag.NewFlagSet("AttrDeleteConfig", pflag.ExitOnError) + cmdFlags.StringVar(&(DefaultDelConfig.AttrFile), fmt.Sprintf("%v%v", prefix, "attrFile"), DefaultDelConfig.AttrFile, "attribute file name to be used for delete attribute for the resource type.") + return cmdFlags +} diff --git a/cmd/config/subcommand/executionqueueattribute/attrdeleteconfig_flags_test.go b/cmd/config/subcommand/executionqueueattribute/attrdeleteconfig_flags_test.go new file mode 100755 index 0000000000..d42fa0c9c7 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/attrdeleteconfig_flags_test.go @@ -0,0 +1,124 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package executionqueueattribute + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "testing" + + "github.com/mitchellh/mapstructure" + "github.com/stretchr/testify/assert" +) + +var dereferencableKindsAttrDeleteConfig = 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 canGetElementAttrDeleteConfig(t reflect.Kind) bool { + _, exists := dereferencableKindsAttrDeleteConfig[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 jsonUnmarshalerHookAttrDeleteConfig(_, to reflect.Type, data interface{}) (interface{}, error) { + unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + if to.Implements(unmarshalerType) || reflect.PtrTo(to).Implements(unmarshalerType) || + (canGetElementAttrDeleteConfig(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_AttrDeleteConfig(input, result interface{}) error { + config := &mapstructure.DecoderConfig{ + TagName: "json", + WeaklyTypedInput: true, + Result: result, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + jsonUnmarshalerHookAttrDeleteConfig, + ), + } + + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +func join_AttrDeleteConfig(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_AttrDeleteConfig(t *testing.T, val, result interface{}) { + assert.NoError(t, decode_AttrDeleteConfig(val, result)) +} + +func testDecodeSlice_AttrDeleteConfig(t *testing.T, vStringSlice, result interface{}) { + assert.NoError(t, decode_AttrDeleteConfig(vStringSlice, result)) +} + +func TestAttrDeleteConfig_GetPFlagSet(t *testing.T) { + val := AttrDeleteConfig{} + cmdFlags := val.GetPFlagSet("") + assert.True(t, cmdFlags.HasFlags()) +} + +func TestAttrDeleteConfig_SetFlags(t *testing.T) { + actual := AttrDeleteConfig{} + cmdFlags := actual.GetPFlagSet("") + assert.True(t, cmdFlags.HasFlags()) + + t.Run("Test_attrFile", func(t *testing.T) { + t.Run("DefaultValue", func(t *testing.T) { + // Test that default value is set properly + if vString, err := cmdFlags.GetString("attrFile"); err == nil { + assert.Equal(t, string(DefaultDelConfig.AttrFile), vString) + } else { + assert.FailNow(t, err.Error()) + } + }) + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("attrFile", testValue) + if vString, err := cmdFlags.GetString("attrFile"); err == nil { + testDecodeJson_AttrDeleteConfig(t, fmt.Sprintf("%v", vString), &actual.AttrFile) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) +} diff --git a/cmd/config/subcommand/executionqueueattribute/attrfetchconfig_flags.go b/cmd/config/subcommand/executionqueueattribute/attrfetchconfig_flags.go new file mode 100755 index 0000000000..0eed381d70 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/attrfetchconfig_flags.go @@ -0,0 +1,46 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package executionqueueattribute + +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 (AttrFetchConfig) 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 (AttrFetchConfig) 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 AttrFetchConfig and its nested types. The format of the +// flags is json-name.json-sub-name... etc. +func (cfg AttrFetchConfig) GetPFlagSet(prefix string) *pflag.FlagSet { + cmdFlags := pflag.NewFlagSet("AttrFetchConfig", pflag.ExitOnError) + cmdFlags.StringVar(&(DefaultFetchConfig.AttrFile), fmt.Sprintf("%v%v", prefix, "attrFile"), DefaultFetchConfig.AttrFile, "attribute file name to be used for generating attribute for the resource type.") + return cmdFlags +} diff --git a/cmd/config/subcommand/executionqueueattribute/attrfetchconfig_flags_test.go b/cmd/config/subcommand/executionqueueattribute/attrfetchconfig_flags_test.go new file mode 100755 index 0000000000..449b82faae --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/attrfetchconfig_flags_test.go @@ -0,0 +1,124 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package executionqueueattribute + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "testing" + + "github.com/mitchellh/mapstructure" + "github.com/stretchr/testify/assert" +) + +var dereferencableKindsAttrFetchConfig = 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 canGetElementAttrFetchConfig(t reflect.Kind) bool { + _, exists := dereferencableKindsAttrFetchConfig[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 jsonUnmarshalerHookAttrFetchConfig(_, to reflect.Type, data interface{}) (interface{}, error) { + unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + if to.Implements(unmarshalerType) || reflect.PtrTo(to).Implements(unmarshalerType) || + (canGetElementAttrFetchConfig(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_AttrFetchConfig(input, result interface{}) error { + config := &mapstructure.DecoderConfig{ + TagName: "json", + WeaklyTypedInput: true, + Result: result, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + jsonUnmarshalerHookAttrFetchConfig, + ), + } + + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +func join_AttrFetchConfig(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_AttrFetchConfig(t *testing.T, val, result interface{}) { + assert.NoError(t, decode_AttrFetchConfig(val, result)) +} + +func testDecodeSlice_AttrFetchConfig(t *testing.T, vStringSlice, result interface{}) { + assert.NoError(t, decode_AttrFetchConfig(vStringSlice, result)) +} + +func TestAttrFetchConfig_GetPFlagSet(t *testing.T) { + val := AttrFetchConfig{} + cmdFlags := val.GetPFlagSet("") + assert.True(t, cmdFlags.HasFlags()) +} + +func TestAttrFetchConfig_SetFlags(t *testing.T) { + actual := AttrFetchConfig{} + cmdFlags := actual.GetPFlagSet("") + assert.True(t, cmdFlags.HasFlags()) + + t.Run("Test_attrFile", func(t *testing.T) { + t.Run("DefaultValue", func(t *testing.T) { + // Test that default value is set properly + if vString, err := cmdFlags.GetString("attrFile"); err == nil { + assert.Equal(t, string(DefaultFetchConfig.AttrFile), vString) + } else { + assert.FailNow(t, err.Error()) + } + }) + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("attrFile", testValue) + if vString, err := cmdFlags.GetString("attrFile"); err == nil { + testDecodeJson_AttrFetchConfig(t, fmt.Sprintf("%v", vString), &actual.AttrFile) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) +} diff --git a/cmd/config/subcommand/executionqueueattribute/attrupdateconfig_flags.go b/cmd/config/subcommand/executionqueueattribute/attrupdateconfig_flags.go new file mode 100755 index 0000000000..c858ca34c8 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/attrupdateconfig_flags.go @@ -0,0 +1,46 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package executionqueueattribute + +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 (AttrUpdateConfig) 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 (AttrUpdateConfig) 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 AttrUpdateConfig and its nested types. The format of the +// flags is json-name.json-sub-name... etc. +func (cfg AttrUpdateConfig) GetPFlagSet(prefix string) *pflag.FlagSet { + cmdFlags := pflag.NewFlagSet("AttrUpdateConfig", pflag.ExitOnError) + cmdFlags.StringVar(&(DefaultUpdateConfig.AttrFile), fmt.Sprintf("%v%v", prefix, "attrFile"), DefaultUpdateConfig.AttrFile, "attribute file name to be used for updating attribute for the resource type.") + return cmdFlags +} diff --git a/cmd/config/subcommand/executionqueueattribute/attrupdateconfig_flags_test.go b/cmd/config/subcommand/executionqueueattribute/attrupdateconfig_flags_test.go new file mode 100755 index 0000000000..dbe6642165 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/attrupdateconfig_flags_test.go @@ -0,0 +1,124 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package executionqueueattribute + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "testing" + + "github.com/mitchellh/mapstructure" + "github.com/stretchr/testify/assert" +) + +var dereferencableKindsAttrUpdateConfig = 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 canGetElementAttrUpdateConfig(t reflect.Kind) bool { + _, exists := dereferencableKindsAttrUpdateConfig[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 jsonUnmarshalerHookAttrUpdateConfig(_, to reflect.Type, data interface{}) (interface{}, error) { + unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + if to.Implements(unmarshalerType) || reflect.PtrTo(to).Implements(unmarshalerType) || + (canGetElementAttrUpdateConfig(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_AttrUpdateConfig(input, result interface{}) error { + config := &mapstructure.DecoderConfig{ + TagName: "json", + WeaklyTypedInput: true, + Result: result, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + jsonUnmarshalerHookAttrUpdateConfig, + ), + } + + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +func join_AttrUpdateConfig(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_AttrUpdateConfig(t *testing.T, val, result interface{}) { + assert.NoError(t, decode_AttrUpdateConfig(val, result)) +} + +func testDecodeSlice_AttrUpdateConfig(t *testing.T, vStringSlice, result interface{}) { + assert.NoError(t, decode_AttrUpdateConfig(vStringSlice, result)) +} + +func TestAttrUpdateConfig_GetPFlagSet(t *testing.T) { + val := AttrUpdateConfig{} + cmdFlags := val.GetPFlagSet("") + assert.True(t, cmdFlags.HasFlags()) +} + +func TestAttrUpdateConfig_SetFlags(t *testing.T) { + actual := AttrUpdateConfig{} + cmdFlags := actual.GetPFlagSet("") + assert.True(t, cmdFlags.HasFlags()) + + t.Run("Test_attrFile", func(t *testing.T) { + t.Run("DefaultValue", func(t *testing.T) { + // Test that default value is set properly + if vString, err := cmdFlags.GetString("attrFile"); err == nil { + assert.Equal(t, string(DefaultUpdateConfig.AttrFile), vString) + } else { + assert.FailNow(t, err.Error()) + } + }) + + t.Run("Override", func(t *testing.T) { + testValue := "1" + + cmdFlags.Set("attrFile", testValue) + if vString, err := cmdFlags.GetString("attrFile"); err == nil { + testDecodeJson_AttrUpdateConfig(t, fmt.Sprintf("%v", vString), &actual.AttrFile) + + } else { + assert.FailNow(t, err.Error()) + } + }) + }) +} diff --git a/cmd/config/subcommand/executionqueueattribute/delete_config.go b/cmd/config/subcommand/executionqueueattribute/delete_config.go new file mode 100644 index 0000000000..a6754eb4f4 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/delete_config.go @@ -0,0 +1,10 @@ +package executionqueueattribute + +//go:generate pflags AttrDeleteConfig --default-var DefaultDelConfig + +// AttrDeleteConfig Matchable resource attributes configuration passed from command line +type AttrDeleteConfig struct { + AttrFile string `json:"attrFile" pflag:",attribute file name to be used for delete attribute for the resource type."` +} + +var DefaultDelConfig = &AttrDeleteConfig{} diff --git a/cmd/config/subcommand/executionqueueattribute/fetch_config.go b/cmd/config/subcommand/executionqueueattribute/fetch_config.go new file mode 100644 index 0000000000..4c5c154f2b --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/fetch_config.go @@ -0,0 +1,9 @@ +package executionqueueattribute + +//go:generate pflags AttrFetchConfig --default-var DefaultFetchConfig + +type AttrFetchConfig struct { + AttrFile string `json:"attrFile" pflag:",attribute file name to be used for generating attribute for the resource type."` +} + +var DefaultFetchConfig = &AttrFetchConfig{} diff --git a/cmd/config/subcommand/executionqueueattribute/file_config.go b/cmd/config/subcommand/executionqueueattribute/file_config.go new file mode 100644 index 0000000000..1726f0b693 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/file_config.go @@ -0,0 +1,47 @@ +package executionqueueattribute + +import ( + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" +) + +// AttrFileConfig shadow Config for ExecutionQueueAttributes. +// The shadow Config is not using ProjectDomainAttribute/Workflowattribute directly inorder to simplify the inputs. +// As the same structure is being used for both ProjectDomainAttribute/Workflowattribute +type AttrFileConfig struct { + Project string `json:"project"` + Domain string `json:"domain"` + Workflow string `json:"workflow,omitempty"` + *admin.ExecutionQueueAttributes +} + +// Decorate decorator over ExecutionQueueAttributes. +func (a AttrFileConfig) Decorate() *admin.MatchingAttributes { + return &admin.MatchingAttributes{ + Target: &admin.MatchingAttributes_ExecutionQueueAttributes{ + ExecutionQueueAttributes: a.ExecutionQueueAttributes, + }, + } +} + +// UnDecorate to uncover ExecutionQueueAttributes. +func (a *AttrFileConfig) UnDecorate(matchingAttribute *admin.MatchingAttributes) { + if matchingAttribute == nil { + return + } + a.ExecutionQueueAttributes = matchingAttribute.GetExecutionQueueAttributes() +} + +// GetProject from the AttrFileConfig +func (a AttrFileConfig) GetProject() string { + return a.Project +} + +// GetDomain from the AttrFileConfig +func (a AttrFileConfig) GetDomain() string { + return a.Domain +} + +// GetWorkflow from the AttrFileConfig +func (a AttrFileConfig) GetWorkflow() string { + return a.Workflow +} diff --git a/cmd/config/subcommand/executionqueueattribute/file_config_test.go b/cmd/config/subcommand/executionqueueattribute/file_config_test.go new file mode 100644 index 0000000000..8148d8b7cd --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/file_config_test.go @@ -0,0 +1,46 @@ +package executionqueueattribute + +import ( + "testing" + + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" + + "github.com/stretchr/testify/assert" +) + +func TestFileConfig(t *testing.T) { + executionQueueAttrFileConfig := AttrFileConfig{ + Project: "dummyProject", + Domain: "dummyDomain", + ExecutionQueueAttributes: &admin.ExecutionQueueAttributes{ + Tags: []string{"foo", "bar"}, + }, + } + matchingAttr := &admin.MatchingAttributes{ + Target: &admin.MatchingAttributes_ExecutionQueueAttributes{ + ExecutionQueueAttributes: executionQueueAttrFileConfig.ExecutionQueueAttributes, + }, + } + t.Run("decorate", func(t *testing.T) { + assert.Equal(t, matchingAttr, executionQueueAttrFileConfig.Decorate()) + }) + + t.Run("decorate", func(t *testing.T) { + executionAttrFileConfigNew := AttrFileConfig{ + Project: "dummyProject", + Domain: "dummyDomain", + } + executionAttrFileConfigNew.UnDecorate(matchingAttr) + assert.Equal(t, executionQueueAttrFileConfig, executionAttrFileConfigNew) + }) + t.Run("get project domain workflow", func(t *testing.T) { + executionQueueAttrFileConfigNew := AttrFileConfig{ + Project: "dummyProject", + Domain: "dummyDomain", + Workflow: "workflow", + } + assert.Equal(t, "dummyProject", executionQueueAttrFileConfigNew.GetProject()) + assert.Equal(t, "dummyDomain", executionQueueAttrFileConfigNew.GetDomain()) + assert.Equal(t, "workflow", executionQueueAttrFileConfigNew.GetWorkflow()) + }) +} diff --git a/cmd/config/subcommand/executionqueueattribute/update_config.go b/cmd/config/subcommand/executionqueueattribute/update_config.go new file mode 100644 index 0000000000..11b319f1d1 --- /dev/null +++ b/cmd/config/subcommand/executionqueueattribute/update_config.go @@ -0,0 +1,10 @@ +package executionqueueattribute + +//go:generate pflags AttrUpdateConfig --default-var DefaultUpdateConfig + +// AttrUpdateConfig Matchable resource attributes configuration passed from command line +type AttrUpdateConfig struct { + AttrFile string `json:"attrFile" pflag:",attribute file name to be used for updating attribute for the resource type."` +} + +var DefaultUpdateConfig = &AttrUpdateConfig{} diff --git a/cmd/delete/delete.go b/cmd/delete/delete.go index fe518f9ca0..5a64a58ce3 100644 --- a/cmd/delete/delete.go +++ b/cmd/delete/delete.go @@ -2,6 +2,7 @@ package delete import ( "github.com/flyteorg/flytectl/cmd/config/subcommand/clusterresourceattribute" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" "github.com/flyteorg/flytectl/cmd/config/subcommand/taskresourceattribute" cmdcore "github.com/flyteorg/flytectl/cmd/core" @@ -35,6 +36,9 @@ func RemoteDeleteCommand() *cobra.Command { "cluster-resource-attribute": {CmdFunc: deleteClusterResourceAttributes, Aliases: []string{"cluster-resource-attributes"}, Short: clusterResourceAttributesShort, Long: clusterResourceAttributesLong, PFlagProvider: clusterresourceattribute.DefaultDelConfig, ProjectDomainNotRequired: true}, + "execution-queue-attribute": {CmdFunc: deleteExecutionQueueAttributes, Aliases: []string{"execution-queue-attributes"}, + Short: executionQueueAttributesShort, + Long: executionQueueAttributesLong, PFlagProvider: executionqueueattribute.DefaultDelConfig, ProjectDomainNotRequired: true}, } cmdcore.AddCommands(deleteCmd, terminateResourcesFuncs) return deleteCmd diff --git a/cmd/delete/delete_test.go b/cmd/delete/delete_test.go index 52ea0e9090..3f5739c9cf 100644 --- a/cmd/delete/delete_test.go +++ b/cmd/delete/delete_test.go @@ -18,6 +18,12 @@ var ( mockClient *mocks.AdminServiceClient cmdCtx cmdCore.CommandContext ) + +const ( + testDataNonExistentFile = "testdata/non-existent-file" + testDataInvalidAttrFile = "testdata/invalid_attribute.yaml" +) + var setup = testutils.Setup var tearDownAndVerify = testutils.TearDownAndVerify @@ -26,16 +32,16 @@ func TestDeleteCommand(t *testing.T) { assert.Equal(t, deleteCommand.Use, "delete") assert.Equal(t, deleteCommand.Short, deleteCmdShort) assert.Equal(t, deleteCommand.Long, deleteCmdLong) - assert.Equal(t, len(deleteCommand.Commands()), 3) + assert.Equal(t, len(deleteCommand.Commands()), 4) cmdNouns := deleteCommand.Commands() // Sort by Use value. sort.Slice(cmdNouns, func(i, j int) bool { return cmdNouns[i].Use < cmdNouns[j].Use }) - useArray := []string{"cluster-resource-attribute", "execution", "task-resource-attribute"} - aliases := [][]string{{"cluster-resource-attributes"}, {"executions"}, {"task-resource-attributes"}} - shortArray := []string{clusterResourceAttributesShort, execCmdShort, taskResourceAttributesShort} - longArray := []string{clusterResourceAttributesLong, execCmdLong, taskResourceAttributesLong} + useArray := []string{"cluster-resource-attribute", "execution", "execution-queue-attribute", "task-resource-attribute"} + aliases := [][]string{{"cluster-resource-attributes"}, {"executions"}, {"execution-queue-attributes"}, {"task-resource-attributes"}} + shortArray := []string{clusterResourceAttributesShort, execCmdShort, executionQueueAttributesShort, taskResourceAttributesShort} + longArray := []string{clusterResourceAttributesLong, execCmdLong, executionQueueAttributesLong, taskResourceAttributesLong} for i := range cmdNouns { assert.Equal(t, cmdNouns[i].Use, useArray[i]) assert.Equal(t, cmdNouns[i].Aliases, aliases[i]) diff --git a/cmd/delete/matchable_cluster_resource_attribute.go b/cmd/delete/matchable_cluster_resource_attribute.go index 18dfa582e8..9dd6bc526b 100644 --- a/cmd/delete/matchable_cluster_resource_attribute.go +++ b/cmd/delete/matchable_cluster_resource_attribute.go @@ -22,8 +22,9 @@ Here the command delete cluster resource attributes for project flytectldemo an flytectl delete cluster-resource-attribute -p flytectldemo -d development -Deleting cluster resource attribute using config file which was used for creating it. +Deletes cluster resource attribute using config file which was used for creating it. Here the command deletes cluster resource attributes from the config file cra.yaml +Attributes are optional in the file as they are unread during the delete command but can be kept as the same file can be used for get, update or delete eg: content of cra.yaml which will use the project domain and workflow name for deleting the resource :: @@ -33,13 +34,13 @@ eg: content of cra.yaml which will use the project domain and workflow name for .. code-block:: yaml - domain: development - project: flytectldemo - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + attributes: + foo: "bar" + buzz: "lightyear" -Deleting cluster resource attribute for a workflow +Deletes cluster resource attribute for a workflow Here the command deletes cluster resource attributes for a workflow :: diff --git a/cmd/delete/matchable_cluster_resource_attribute_test.go b/cmd/delete/matchable_cluster_resource_attribute_test.go index ef84023c45..f9290ad6b7 100644 --- a/cmd/delete/matchable_cluster_resource_attribute_test.go +++ b/cmd/delete/matchable_cluster_resource_attribute_test.go @@ -107,7 +107,7 @@ func TestDeleteClusterResourceAttributes(t *testing.T) { setup() deleteClusterResourceAttributeSetup() // Empty attribute file - clusterresourceattribute.DefaultDelConfig.AttrFile = "testdata/non-existent" + clusterresourceattribute.DefaultDelConfig.AttrFile = testDataNonExistentFile // No args implying project domain attribute deletion u.DeleterExt.OnDeleteWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) @@ -121,7 +121,7 @@ func TestDeleteClusterResourceAttributes(t *testing.T) { setup() deleteClusterResourceAttributeSetup() // Empty attribute file - clusterresourceattribute.DefaultDelConfig.AttrFile = "testdata/invalid_attribute.yaml" + clusterresourceattribute.DefaultDelConfig.AttrFile = testDataInvalidAttrFile // No args implying project domain attribute deletion err = deleteClusterResourceAttributes(ctx, args, cmdCtx) assert.NotNil(t, err) diff --git a/cmd/delete/matchable_execution_queue_attribute.go b/cmd/delete/matchable_execution_queue_attribute.go new file mode 100644 index 0000000000..2f11ce5c5b --- /dev/null +++ b/cmd/delete/matchable_execution_queue_attribute.go @@ -0,0 +1,82 @@ +package delete + +import ( + "context" + + "github.com/flyteorg/flytectl/cmd/config" + sconfig "github.com/flyteorg/flytectl/cmd/config/subcommand" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" + cmdCore "github.com/flyteorg/flytectl/cmd/core" + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" +) + +const ( + executionQueueAttributesShort = "Deletes matchable resources of execution queue attributes" + executionQueueAttributesLong = ` +Deletes execution queue attributes for given project and domain combination or additionally with workflow name. + +Deletes execution queue attribute for project and domain +Here the command delete execution queue attributes for project flytectldemo and development domain. +:: + + flytectl delete execution-queue-attribute -p flytectldemo -d development + + +Deletes execution queue attribute using config file which was used for creating it. +Here the command deletes execution queue attributes from the config file era.yaml +Tags are optional in the file as they are unread during the delete command but can be kept as the same file can be used for get, update or delete +eg: content of era.yaml which will use the project domain and workflow name for deleting the resource + +:: + + flytectl delete execution-queue-attribute --attrFile era.yaml + + +.. code-block:: yaml + + domain: development + project: flytectldemo + tags: + - foo + - bar + - buzz + - lightyear + +Deletes execution queue attribute for a workflow +Here the command deletes the execution queue attributes for a workflow + +:: + + flytectl delete execution-queue-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +Usage +` +) + +func deleteExecutionQueueAttributes(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error { + var pwdGetter sconfig.ProjectDomainWorkflowGetter + pwdGetter = sconfig.PDWGetterCommandLine{Config: config.GetConfig(), Args: args} + delConfig := executionqueueattribute.DefaultDelConfig + + // Get the project domain workflowName from the config file or commandline params + if len(delConfig.AttrFile) > 0 { + // Initialize AttrFileConfig which will be used if delConfig.AttrFile is non empty + // And Reads from the attribute file + pwdGetter = &executionqueueattribute.AttrFileConfig{} + if err := sconfig.ReadConfigFromFile(pwdGetter, delConfig.AttrFile); err != nil { + return err + } + } + // Use the pwdGetter to initialize the project domain and workflow + project := pwdGetter.GetProject() + domain := pwdGetter.GetDomain() + workflowName := pwdGetter.GetWorkflow() + + // Deletes the matchable attributes using the AttrFileConfig + if err := deleteMatchableAttr(ctx, project, domain, workflowName, cmdCtx.AdminDeleterExt(), + admin.MatchableResource_EXECUTION_QUEUE); err != nil { + return err + } + + return nil +} diff --git a/cmd/delete/matchable_execution_queue_attribute_test.go b/cmd/delete/matchable_execution_queue_attribute_test.go new file mode 100644 index 0000000000..ef5b2975c0 --- /dev/null +++ b/cmd/delete/matchable_execution_queue_attribute_test.go @@ -0,0 +1,134 @@ +package delete + +import ( + "fmt" + "testing" + + "github.com/flyteorg/flytectl/cmd/config" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" + u "github.com/flyteorg/flytectl/cmd/testutils" + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func deleteExecutionQueueAttributeSetup() { + ctx = u.Ctx + cmdCtx = u.CmdCtx + mockClient = u.MockClient + executionqueueattribute.DefaultDelConfig = &executionqueueattribute.AttrDeleteConfig{} + args = []string{} +} + +func TestDeleteExecutionQueueAttributes(t *testing.T) { + t.Run("successful project domain attribute deletion commandline", func(t *testing.T) { + setup() + deleteExecutionQueueAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = "" + // No args implying project domain attribute deletion + u.DeleterExt.OnDeleteProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(nil) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.DeleterExt.AssertCalled(t, "DeleteProjectDomainAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("failed project domain attribute deletion", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // No args implying project domain attribute deletion + u.DeleterExt.OnDeleteProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(fmt.Errorf("failed to delte project domain attributes")) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("failed to delte project domain attributes"), err) + u.DeleterExt.AssertCalled(t, "DeleteProjectDomainAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("successful project domain attribute deletion file", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = "testdata/valid_project_domain_execution_queue_attribute.yaml" + // No args implying project domain attribute deletion + u.DeleterExt.OnDeleteProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(nil) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.DeleterExt.AssertCalled(t, "DeleteProjectDomainAttributes", + ctx, "flytectldemo", "development", admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("successful workflow attribute deletion", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = "" + args := []string{"workflow1"} + u.DeleterExt.OnDeleteWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(nil) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.DeleterExt.AssertCalled(t, "DeleteWorkflowAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, "workflow1", + admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("failed workflow attribute deletion", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = "" + args := []string{"workflow1"} + u.DeleterExt.OnDeleteWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(fmt.Errorf("failed to delete workflow attribute")) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("failed to delete workflow attribute"), err) + u.DeleterExt.AssertCalled(t, "DeleteWorkflowAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, "workflow1", + admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("successful workflow attribute deletion file", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = "testdata/valid_workflow_execution_queue_attribute.yaml" + // No args implying project domain attribute deletion + u.DeleterExt.OnDeleteWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(nil) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.DeleterExt.AssertCalled(t, "DeleteWorkflowAttributes", + ctx, "flytectldemo", "development", "core.control_flow.run_merge_sort.merge_sort", + admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("workflow attribute deletion non existent file", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = testDataNonExistentFile + // No args implying project domain attribute deletion + u.DeleterExt.OnDeleteWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(nil) + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + u.DeleterExt.AssertNotCalled(t, "DeleteWorkflowAttributes", + ctx, "flytectldemo", "development", "core.control_flow.run_merge_sort.merge_sort", + admin.MatchableResource_EXECUTION_QUEUE) + }) + t.Run("attribute deletion invalid file", func(t *testing.T) { + setup() + deleteTaskResourceAttributeSetup() + // Empty attribute file + executionqueueattribute.DefaultDelConfig.AttrFile = testDataInvalidAttrFile + // No args implying project domain attribute deletion + err = deleteExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, + fmt.Errorf("error unmarshaling JSON: while decoding JSON: json: unknown field \"InvalidDomain\""), + err) + u.DeleterExt.AssertNotCalled(t, "DeleteProjectDomainAttributes", + ctx, "flytectldemo", "development", admin.MatchableResource_EXECUTION_QUEUE) + }) +} diff --git a/cmd/delete/matchable_task_resource_attribute.go b/cmd/delete/matchable_task_resource_attribute.go index dbd8293cfe..cafc354714 100644 --- a/cmd/delete/matchable_task_resource_attribute.go +++ b/cmd/delete/matchable_task_resource_attribute.go @@ -22,8 +22,9 @@ Here the command delete task resource attributes for project flytectldemo and d flytectl delete task-resource-attribute -p flytectldemo -d development -Deleting task resource attribute using config file which was used for creating it. +Deletes task resource attribute using config file which was used for creating it. Here the command deletes task resource attributes from the config file tra.yaml +defaults/limits are optional in the file as they are unread during the delete command but can be kept as the same file can be used for get, update or delete eg: content of tra.yaml which will use the project domain and workflow name for deleting the resource :: @@ -33,16 +34,16 @@ eg: content of tra.yaml which will use the project domain and workflow name for .. code-block:: yaml - domain: development - project: flytectldemo - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" -Deleting task resource attribute for a workflow +Deletes task resource attribute for a workflow Here the command deletes task resource attributes for a workflow :: diff --git a/cmd/delete/matchable_task_resource_attribute_test.go b/cmd/delete/matchable_task_resource_attribute_test.go index 16443ef270..204d46f8c7 100644 --- a/cmd/delete/matchable_task_resource_attribute_test.go +++ b/cmd/delete/matchable_task_resource_attribute_test.go @@ -107,7 +107,7 @@ func TestDeleteTaskResourceAttributes(t *testing.T) { setup() deleteTaskResourceAttributeSetup() // Empty attribute file - taskresourceattribute.DefaultDelConfig.AttrFile = "testdata/non-existent" + taskresourceattribute.DefaultDelConfig.AttrFile = testDataNonExistentFile // No args implying project domain attribute deletion u.DeleterExt.OnDeleteWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) @@ -121,7 +121,7 @@ func TestDeleteTaskResourceAttributes(t *testing.T) { setup() deleteTaskResourceAttributeSetup() // Empty attribute file - taskresourceattribute.DefaultDelConfig.AttrFile = "testdata/invalid_attribute.yaml" + taskresourceattribute.DefaultDelConfig.AttrFile = testDataInvalidAttrFile // No args implying project domain attribute deletion err = deleteTaskResourceAttributes(ctx, args, cmdCtx) assert.NotNil(t, err) diff --git a/cmd/delete/testdata/valid_project_domain_execution_queue_attribute.yaml b/cmd/delete/testdata/valid_project_domain_execution_queue_attribute.yaml new file mode 100644 index 0000000000..d04a525b88 --- /dev/null +++ b/cmd/delete/testdata/valid_project_domain_execution_queue_attribute.yaml @@ -0,0 +1,7 @@ +domain: development +project: flytectldemo +tags: + - foo + - bar + - buzz + - lightyear \ No newline at end of file diff --git a/cmd/delete/testdata/valid_workflow_execution_queue_attribute.yaml b/cmd/delete/testdata/valid_workflow_execution_queue_attribute.yaml new file mode 100644 index 0000000000..7c69c43fec --- /dev/null +++ b/cmd/delete/testdata/valid_workflow_execution_queue_attribute.yaml @@ -0,0 +1,8 @@ +domain: development +project: flytectldemo +workflow: core.control_flow.run_merge_sort.merge_sort +tags: + - foo + - bar + - buzz + - lightyear \ No newline at end of file diff --git a/cmd/get/get.go b/cmd/get/get.go index a03e4931b3..10f1e6bdb1 100644 --- a/cmd/get/get.go +++ b/cmd/get/get.go @@ -2,6 +2,7 @@ package get import ( "github.com/flyteorg/flytectl/cmd/config/subcommand/clusterresourceattribute" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" "github.com/flyteorg/flytectl/cmd/config/subcommand/taskresourceattribute" "github.com/flyteorg/flytectl/cmd/config/subcommand/workflow" cmdcore "github.com/flyteorg/flytectl/cmd/core" @@ -46,6 +47,9 @@ func CreateGetCommand() *cobra.Command { "cluster-resource-attribute": {CmdFunc: getClusterResourceAttributes, Aliases: []string{"cluster-resource-attributes"}, Short: clusterResourceAttributesShort, Long: clusterResourceAttributesLong, PFlagProvider: clusterresourceattribute.DefaultFetchConfig}, + "execution-queue-attribute": {CmdFunc: getExecutionQueueAttributes, Aliases: []string{"execution-queue-attributes"}, + Short: executionQueueAttributesShort, + Long: executionQueueAttributesLong, PFlagProvider: executionqueueattribute.DefaultFetchConfig}, } cmdcore.AddCommands(getCmd, getResourcesFuncs) diff --git a/cmd/get/get_test.go b/cmd/get/get_test.go index 1d0bebe97b..1f567dacc3 100644 --- a/cmd/get/get_test.go +++ b/cmd/get/get_test.go @@ -32,24 +32,29 @@ var ( var setup = testutils.Setup var tearDownAndVerify = testutils.TearDownAndVerify +const ( + testDataTempFile = "temp-output-file" + testDataNotExistentTempFile = "non-existent-dir/temp-output-file" +) + func TestCreateGetCommand(t *testing.T) { getCommand := CreateGetCommand() assert.Equal(t, getCommand.Use, "get") assert.Equal(t, getCommand.Short, "Used for fetching various flyte resources including tasks/workflows/launchplans/executions/project.") fmt.Println(getCommand.Commands()) - assert.Equal(t, len(getCommand.Commands()), 7) + assert.Equal(t, len(getCommand.Commands()), 8) cmdNouns := getCommand.Commands() // Sort by Use value. sort.Slice(cmdNouns, func(i, j int) bool { return cmdNouns[i].Use < cmdNouns[j].Use }) - useArray := []string{"cluster-resource-attribute", "execution", "launchplan", "project", + useArray := []string{"cluster-resource-attribute", "execution", "execution-queue-attribute", "launchplan", "project", "task", "task-resource-attribute", "workflow"} - aliases := [][]string{{"cluster-resource-attributes"}, {"executions"}, {"launchplans"}, {"projects"}, {"tasks"}, + aliases := [][]string{{"cluster-resource-attributes"}, {"executions"}, {"execution-queue-attributes"}, {"launchplans"}, {"projects"}, {"tasks"}, {"task-resource-attributes"}, {"workflows"}} - shortArray := []string{clusterResourceAttributesShort, executionShort, launchPlanShort, projectShort, + shortArray := []string{clusterResourceAttributesShort, executionShort, executionQueueAttributesShort, launchPlanShort, projectShort, taskShort, taskResourceAttributesShort, workflowShort} - longArray := []string{clusterResourceAttributesLong, executionLong, launchPlanLong, projectLong, taskLong, + longArray := []string{clusterResourceAttributesLong, executionLong, executionQueueAttributesLong, launchPlanLong, projectLong, taskLong, taskResourceAttributesLong, workflowLong} for i := range cmdNouns { assert.Equal(t, cmdNouns[i].Use, useArray[i]) diff --git a/cmd/get/matchable_cluster_resource_attribute.go b/cmd/get/matchable_cluster_resource_attribute.go index 4ca0934cd4..7df8190d09 100644 --- a/cmd/get/matchable_cluster_resource_attribute.go +++ b/cmd/get/matchable_cluster_resource_attribute.go @@ -21,28 +21,40 @@ Here the command get cluster resource attributes for project flytectldemo and d flytectl get cluster-resource-attribute -p flytectldemo -d development -eg : O/P +eg : output from the command .. code-block:: json {"project":"flytectldemo","domain":"development","attributes":{"buzz":"lightyear","foo":"bar"}} +Retrieves cluster resource attribute for project and domain and workflow +Here the command get cluster resource attributes for project flytectldemo ,development domain and workflow core.control_flow.run_merge_sort.merge_sort +:: + + flytectl get cluster-resource-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","workflow":"core.control_flow.run_merge_sort.merge_sort","attributes":{"buzz":"lightyear","foo":"bar"}} + Writing the cluster resource attribute to a file. If there are no cluster resource attributes , command would return an error. -Here the command gets task resource attributes and writes the config file to tra.yaml -eg: content of tra.yaml +Here the command gets task resource attributes and writes the config file to cra.yaml +eg: content of cra.yaml :: - flytectl get task-resource-attribute --attrFile tra.yaml + flytectl get task-resource-attribute --attrFile cra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + attributes: + foo: "bar" + buzz: "lightyear" Usage ` diff --git a/cmd/get/matchable_cluster_resource_attribute_test.go b/cmd/get/matchable_cluster_resource_attribute_test.go index dd93934a91..9991e3688d 100644 --- a/cmd/get/matchable_cluster_resource_attribute_test.go +++ b/cmd/get/matchable_cluster_resource_attribute_test.go @@ -20,7 +20,7 @@ func getClusterResourceAttributeSetup() { mockClient = u.MockClient clusterresourceattribute.DefaultFetchConfig = &clusterresourceattribute.AttrFetchConfig{} // Clean up the temp directory. - _ = os.Remove("temp-output-file") + _ = os.Remove(testDataTempFile) } func TestGetClusterResourceAttributes(t *testing.T) { @@ -67,7 +67,7 @@ func TestGetClusterResourceAttributes(t *testing.T) { var args []string setup() getClusterResourceAttributeSetup() - clusterresourceattribute.DefaultFetchConfig.AttrFile = "temp-output-file" + clusterresourceattribute.DefaultFetchConfig.AttrFile = testDataTempFile // No args implying project domain attribute deletion u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(projectDomainResp, nil) @@ -81,7 +81,7 @@ func TestGetClusterResourceAttributes(t *testing.T) { var args []string setup() getClusterResourceAttributeSetup() - clusterresourceattribute.DefaultFetchConfig.AttrFile = "non-existent-dir/temp-output-file" + clusterresourceattribute.DefaultFetchConfig.AttrFile = testDataNotExistentTempFile // No args implying project domain attribute deletion u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(projectDomainResp, nil) diff --git a/cmd/get/matchable_execution_queue_attribute.go b/cmd/get/matchable_execution_queue_attribute.go new file mode 100644 index 0000000000..07e51e3d91 --- /dev/null +++ b/cmd/get/matchable_execution_queue_attribute.go @@ -0,0 +1,92 @@ +package get + +import ( + "context" + + "github.com/flyteorg/flytectl/cmd/config" + sconfig "github.com/flyteorg/flytectl/cmd/config/subcommand" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" + cmdCore "github.com/flyteorg/flytectl/cmd/core" + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" +) + +const ( + executionQueueAttributesShort = "Gets matchable resources of execution queue attributes" + executionQueueAttributesLong = ` +Retrieves execution queue attributes for given project and domain combination or additionally with workflow name. + +Retrieves execution queue attribute for project and domain +Here the command get execution queue attributes for project flytectldemo and development domain. +:: + + flytectl get execution-queue-attribute -p flytectldemo -d development + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","tags":["foo", "bar"]} + +Retrieves execution queue attribute for project and domain and workflow +Here the command get execution queue attributes for project flytectldemo ,development domain and workflow core.control_flow.run_merge_sort.merge_sort +:: + + flytectl get execution-queue-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","workflow":"core.control_flow.run_merge_sort.merge_sort","tags":["foo", "bar"]} + +Writing the execution queue attribute to a file. If there are no execution queue attributes, command would return an error. +Here the command gets execution queue attributes and writes the config file to era.yaml +eg: content of era.yaml + +:: + + flytectl get execution-queue-attribute --attrFile era.yaml + + +.. code-block:: yaml + + domain: development + project: flytectldemo + tags: + - foo + - bar + - buzz + - lightyear + +Usage +` +) + +func getExecutionQueueAttributes(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error { + var project string + var domain string + var workflowName string + + // Get the project domain workflow name parameters from the command line. Project and domain are mandatory for this command + project = config.GetConfig().Project + domain = config.GetConfig().Domain + if len(args) == 1 { + workflowName = args[0] + } + // Construct a shadow config for ExecutionQueueAttribute. The shadow config is not using ProjectDomainAttribute/Workflowattribute directly inorder to simplify the inputs. + executionQueueAttrFileConfig := executionqueueattribute.AttrFileConfig{Project: project, Domain: domain, Workflow: workflowName} + // Get the attribute file name from the command line config + fileName := executionqueueattribute.DefaultFetchConfig.AttrFile + + // Updates the taskResourceAttrFileConfig with the fetched matchable attribute + if err := FetchAndUnDecorateMatchableAttr(ctx, project, domain, workflowName, cmdCtx.AdminFetcherExt(), + &executionQueueAttrFileConfig, admin.MatchableResource_EXECUTION_QUEUE); err != nil { + return err + } + + // Write the config to the file which can be used for update + if err := sconfig.DumpTaskResourceAttr(executionQueueAttrFileConfig, fileName); err != nil { + return err + } + return nil +} diff --git a/cmd/get/matchable_execution_queue_attribute_test.go b/cmd/get/matchable_execution_queue_attribute_test.go new file mode 100644 index 0000000000..92bf156d95 --- /dev/null +++ b/cmd/get/matchable_execution_queue_attribute_test.go @@ -0,0 +1,138 @@ +package get + +import ( + "fmt" + "os" + "testing" + + "github.com/flyteorg/flytectl/cmd/config" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" + u "github.com/flyteorg/flytectl/cmd/testutils" + "github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/admin" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func getExecutionQueueAttributeSetup() { + ctx = u.Ctx + cmdCtx = u.CmdCtx + mockClient = u.MockClient + executionqueueattribute.DefaultFetchConfig = &executionqueueattribute.AttrFetchConfig{} + // Clean up the temp directory. + _ = os.Remove(testDataTempFile) +} + +func TestGetExecutionQueueAttributes(t *testing.T) { + executionQueueAttr := &admin.ExecutionQueueAttributes{ + Tags: []string{"foo", "bar"}, + } + projectDomainResp := &admin.ProjectDomainAttributesGetResponse{ + Attributes: &admin.ProjectDomainAttributes{ + Project: config.GetConfig().Project, + Domain: config.GetConfig().Domain, + MatchingAttributes: &admin.MatchingAttributes{ + Target: &admin.MatchingAttributes_ExecutionQueueAttributes{ + ExecutionQueueAttributes: executionQueueAttr, + }, + }, + }, + } + workflowResp := &admin.WorkflowAttributesGetResponse{ + Attributes: &admin.WorkflowAttributes{ + Project: config.GetConfig().Project, + Domain: config.GetConfig().Domain, + Workflow: "workflow", + MatchingAttributes: &admin.MatchingAttributes{ + Target: &admin.MatchingAttributes_ExecutionQueueAttributes{ + ExecutionQueueAttributes: executionQueueAttr, + }, + }, + }, + } + t.Run("successful get project domain attribute", func(t *testing.T) { + var args []string + setup() + getExecutionQueueAttributeSetup() + // No args implying project domain attribute deletion + u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(projectDomainResp, nil) + err = getExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.FetcherExt.AssertCalled(t, "FetchProjectDomainAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, admin.MatchableResource_EXECUTION_QUEUE) + tearDownAndVerify(t, `{"project":"dummyProject","domain":"dummyDomain","tags":["foo","bar"]}`) + }) + t.Run("successful get project domain attribute and write to file", func(t *testing.T) { + var args []string + setup() + getExecutionQueueAttributeSetup() + executionqueueattribute.DefaultFetchConfig.AttrFile = testDataTempFile + // No args implying project domain attribute deletion + u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(projectDomainResp, nil) + err = getExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.FetcherExt.AssertCalled(t, "FetchProjectDomainAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, admin.MatchableResource_EXECUTION_QUEUE) + tearDownAndVerify(t, `wrote the config to file temp-output-file`) + }) + t.Run("successful get project domain attribute and write to file failure", func(t *testing.T) { + var args []string + setup() + getExecutionQueueAttributeSetup() + executionqueueattribute.DefaultFetchConfig.AttrFile = testDataNotExistentTempFile + // No args implying project domain attribute deletion + u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(projectDomainResp, nil) + err = getExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("error dumping in file due to open non-existent-dir/temp-output-file: no such file or directory"), err) + u.FetcherExt.AssertCalled(t, "FetchProjectDomainAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, admin.MatchableResource_EXECUTION_QUEUE) + tearDownAndVerify(t, ``) + }) + t.Run("failed get project domain attribute", func(t *testing.T) { + var args []string + setup() + getExecutionQueueAttributeSetup() + // No args implying project domain attribute deletion + u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(nil, fmt.Errorf("failed to fetch response")) + err = getExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("failed to fetch response"), err) + u.FetcherExt.AssertCalled(t, "FetchProjectDomainAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, admin.MatchableResource_EXECUTION_QUEUE) + tearDownAndVerify(t, ``) + }) + t.Run("successful get workflow attribute", func(t *testing.T) { + var args []string + setup() + getExecutionQueueAttributeSetup() + args = []string{"workflow"} + u.FetcherExt.OnFetchWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(workflowResp, nil) + err = getExecutionQueueAttributes(ctx, args, cmdCtx) + assert.Nil(t, err) + u.FetcherExt.AssertCalled(t, "FetchWorkflowAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, "workflow", + admin.MatchableResource_EXECUTION_QUEUE) + tearDownAndVerify(t, `{"project":"dummyProject","domain":"dummyDomain","workflow":"workflow","tags":["foo","bar"]}`) + }) + t.Run("failed get workflow attribute", func(t *testing.T) { + var args []string + setup() + getExecutionQueueAttributeSetup() + args = []string{"workflow"} + u.FetcherExt.OnFetchWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(nil, fmt.Errorf("failed to fetch response")) + err = getExecutionQueueAttributes(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("failed to fetch response"), err) + u.FetcherExt.AssertCalled(t, "FetchWorkflowAttributes", + ctx, config.GetConfig().Project, config.GetConfig().Domain, "workflow", + admin.MatchableResource_EXECUTION_QUEUE) + tearDownAndVerify(t, ``) + }) +} diff --git a/cmd/get/matchable_task_resource_attribute.go b/cmd/get/matchable_task_resource_attribute.go index e27367e8a2..b3ba8023c4 100644 --- a/cmd/get/matchable_task_resource_attribute.go +++ b/cmd/get/matchable_task_resource_attribute.go @@ -21,11 +21,24 @@ Here the command get task resource attributes for project flytectldemo and deve flytectl get task-resource-attribute -p flytectldemo -d development -eg : O/P +eg : output from the command .. code-block:: json - {"Project":"flytectldemo","Domain":"development","Workflow":"","defaults":{"cpu":"1","memory":"150Mi"},"limits":{"cpu":"2","memory":"450Mi"}} + {"project":"flytectldemo","domain":"development","workflow":"","defaults":{"cpu":"1","memory":"150Mi"},"limits":{"cpu":"2","memory":"450Mi"}} + +Retrieves task resource attribute for project and domain and workflow +Here the command get task resource attributes for project flytectldemo ,development domain and workflow core.control_flow.run_merge_sort.merge_sort +:: + + flytectl get task-resource-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","workflow":"core.control_flow.run_merge_sort.merge_sort","defaults":{"cpu":"1","memory":"150Mi"},"limits":{"cpu":"2","memory":"450Mi"}} + Writing the task resource attribute to a file. If there are no task resource attributes a file would be written with basic data populated. Here the command gets task resource attributes and writes the config file to tra.yaml @@ -38,14 +51,14 @@ eg: content of tra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" Usage ` diff --git a/cmd/get/matchable_task_resource_attribute_test.go b/cmd/get/matchable_task_resource_attribute_test.go index 2477661d70..6df5479859 100644 --- a/cmd/get/matchable_task_resource_attribute_test.go +++ b/cmd/get/matchable_task_resource_attribute_test.go @@ -20,7 +20,7 @@ func getTaskResourceAttributeSetup() { mockClient = u.MockClient taskresourceattribute.DefaultFetchConfig = &taskresourceattribute.AttrFetchConfig{} // Clean up the temp directory. - _ = os.Remove("temp-output-file") + _ = os.Remove(testDataTempFile) } func TestGetTaskResourceAttributes(t *testing.T) { @@ -74,7 +74,7 @@ func TestGetTaskResourceAttributes(t *testing.T) { var args []string setup() getTaskResourceAttributeSetup() - taskresourceattribute.DefaultFetchConfig.AttrFile = "temp-output-file" + taskresourceattribute.DefaultFetchConfig.AttrFile = testDataTempFile // No args implying project domain attribute deletion u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(projectDomainResp, nil) @@ -88,7 +88,7 @@ func TestGetTaskResourceAttributes(t *testing.T) { var args []string setup() getTaskResourceAttributeSetup() - taskresourceattribute.DefaultFetchConfig.AttrFile = "non-existent-dir/temp-output-file" + taskresourceattribute.DefaultFetchConfig.AttrFile = testDataNotExistentTempFile // No args implying project domain attribute deletion u.FetcherExt.OnFetchProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(projectDomainResp, nil) diff --git a/cmd/update/matchable_cluster_resource_attribute.go b/cmd/update/matchable_cluster_resource_attribute.go index ff0b42c9ef..77b0821c7c 100644 --- a/cmd/update/matchable_cluster_resource_attribute.go +++ b/cmd/update/matchable_cluster_resource_attribute.go @@ -16,35 +16,39 @@ Updates cluster resource attributes for given project and domain combination or Updating to the cluster resource attribute is only available from a generated file. See the get section for generating this file. Here the command updates takes the input for cluster resource attributes from the config file cra.yaml -eg: content of tra.yaml +eg: content of cra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + attributes: + foo: "bar" + buzz: "lightyear" :: - flytectl update cluster-resource-attribute -attrFile cra.yaml + flytectl update cluster-resource-attribute --attrFile cra.yaml Updating cluster resource attribute for project and domain and workflow combination. This will take precedence over any other resource attribute defined at project domain level. +Also this will completely overwrite any existing custom project and domain and workflow combination attributes. +Would be preferable to do get and generate an attribute file if there is an existing attribute already set and then update it to have new values +Refer to get cluster-resource-attribute section on how to generate this file Update the cluster resource attributes for workflow core.control_flow.run_merge_sort.merge_sort in flytectldemo , development domain + .. code-block:: yaml - domain: development - project: flytectldemo - workflow: core.control_flow.run_merge_sort.merge_sort - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + workflow: core.control_flow.run_merge_sort.merge_sort + attributes: + foo: "bar" + buzz: "lightyear" :: - flytectl update cluster-resource-attribute -attrFile cra.yaml + flytectl update cluster-resource-attribute --attrFile cra.yaml Usage diff --git a/cmd/update/matchable_cluster_resource_attribute_test.go b/cmd/update/matchable_cluster_resource_attribute_test.go index 1819c6cec4..8cb13ee340 100644 --- a/cmd/update/matchable_cluster_resource_attribute_test.go +++ b/cmd/update/matchable_cluster_resource_attribute_test.go @@ -76,16 +76,16 @@ func TestUpdateClusterResourceAttributes(t *testing.T) { t.Run("non existent file", func(t *testing.T) { setup() updateClusterResourceAttributeSetup() - clusterresourceattribute.DefaultUpdateConfig.AttrFile = "testdata/non-existent-filel" + clusterresourceattribute.DefaultUpdateConfig.AttrFile = testDataNonExistentFile err = updateClusterResourceAttributesFunc(ctx, nil, cmdCtx) assert.NotNil(t, err) - assert.Equal(t, fmt.Errorf("unable to read from testdata/non-existent-filel yaml file"), err) + assert.Equal(t, fmt.Errorf("unable to read from testdata/non-existent-file yaml file"), err) tearDownAndVerify(t, ``) }) t.Run("invalid update file", func(t *testing.T) { setup() updateClusterResourceAttributeSetup() - clusterresourceattribute.DefaultUpdateConfig.AttrFile = "testdata/invalid_attribute.yaml" + clusterresourceattribute.DefaultUpdateConfig.AttrFile = testDataInvalidAttrFile err = updateClusterResourceAttributesFunc(ctx, nil, cmdCtx) assert.NotNil(t, err) assert.Equal(t, fmt.Errorf("error unmarshaling JSON: while decoding JSON: json: unknown field \"InvalidDomain\""), err) diff --git a/cmd/update/matchable_execution_queue_attribute.go b/cmd/update/matchable_execution_queue_attribute.go new file mode 100644 index 0000000000..676c351396 --- /dev/null +++ b/cmd/update/matchable_execution_queue_attribute.go @@ -0,0 +1,84 @@ +package update + +import ( + "context" + "fmt" + + sconfig "github.com/flyteorg/flytectl/cmd/config/subcommand" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" + cmdCore "github.com/flyteorg/flytectl/cmd/core" +) + +const ( + executionQueueAttributesShort = "Updates matchable resources of execution queue attributes" + executionQueueAttributesLong = ` +Updates execution queue attributes for given project and domain combination or additionally with workflow name. + +Updating to the execution queue attribute is only available from a generated file. See the get section for generating this file. +Also this will completely overwrite any existing custom project and domain and workflow combination attributes. +Would be preferable to do get and generate an attribute file if there is an existing attribute already set and then update it to have new values +Refer to get execution-queue-attribute section on how to generate this file +Here the command updates takes the input for execution queue attributes from the config file era.yaml +eg: content of era.yaml + +.. code-block:: yaml + + domain: development + project: flytectldemo + tags: + - foo + - bar + - buzz + - lightyear + +:: + + flytectl update execution-queue-attribute --attrFile era.yaml + +Updating execution queue attribute for project and domain and workflow combination. This will take precedence over any other +execution queue attribute defined at project domain level. +Update the execution queue attributes for workflow core.control_flow.run_merge_sort.merge_sort in flytectldemo , development domain + +.. code-block:: yaml + + domain: development + project: flytectldemo + workflow: core.control_flow.run_merge_sort.merge_sort + tags: + - foo + - bar + - buzz + - lightyear + +:: + + flytectl update execution-queue-attribute --attrFile era.yaml + +Usage + +` +) + +func updateExecutionQueueAttributesFunc(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error { + updateConfig := executionqueueattribute.DefaultUpdateConfig + if len(updateConfig.AttrFile) == 0 { + return fmt.Errorf("attrFile is mandatory while calling update for execution queue attribute") + } + + executionQueueAttrFileConfig := executionqueueattribute.AttrFileConfig{} + if err := sconfig.ReadConfigFromFile(&executionQueueAttrFileConfig, updateConfig.AttrFile); err != nil { + return err + } + + // Get project domain workflow name from the read file. + project := executionQueueAttrFileConfig.Project + domain := executionQueueAttrFileConfig.Domain + workflowName := executionQueueAttrFileConfig.Workflow + + // Updates the admin matchable attribute from executionQueueAttrFileConfig + if err := DecorateAndUpdateMatchableAttr(ctx, project, domain, workflowName, cmdCtx.AdminUpdaterExt(), + executionQueueAttrFileConfig); err != nil { + return err + } + return nil +} diff --git a/cmd/update/matchable_execution_queue_attribute_test.go b/cmd/update/matchable_execution_queue_attribute_test.go new file mode 100644 index 0000000000..5659a35696 --- /dev/null +++ b/cmd/update/matchable_execution_queue_attribute_test.go @@ -0,0 +1,94 @@ +package update + +import ( + "fmt" + "testing" + + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" + u "github.com/flyteorg/flytectl/cmd/testutils" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func updateExecutionQueueAttributeSetup() { + ctx = u.Ctx + cmdCtx = u.CmdCtx + mockClient = u.MockClient + executionqueueattribute.DefaultUpdateConfig = &executionqueueattribute.AttrUpdateConfig{} +} + +func TestExecutionQueueAttributes(t *testing.T) { + t.Run("no input file for update", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + err = updateExecutionQueueAttributesFunc(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("attrFile is mandatory while calling update for execution queue attribute"), err) + tearDownAndVerify(t, ``) + }) + t.Run("successful update project domain attribute", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + executionqueueattribute.DefaultUpdateConfig.AttrFile = "testdata/valid_project_domain_execution_queue_attribute.yaml" + // No args implying project domain attribute deletion + u.UpdaterExt.OnUpdateProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(nil) + err = updateExecutionQueueAttributesFunc(ctx, args, cmdCtx) + assert.Nil(t, err) + tearDownAndVerify(t, ``) + }) + t.Run("failed update project domain attribute", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + executionqueueattribute.DefaultUpdateConfig.AttrFile = "testdata/valid_project_domain_execution_queue_attribute.yaml" + // No args implying project domain attribute deletion + u.UpdaterExt.OnUpdateProjectDomainAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything).Return(fmt.Errorf("failed to update attributes")) + err = updateExecutionQueueAttributesFunc(ctx, args, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("failed to update attributes"), err) + tearDownAndVerify(t, ``) + }) + t.Run("successful update workflow attribute", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + executionqueueattribute.DefaultUpdateConfig.AttrFile = "testdata/valid_workflow_execution_queue_attribute.yaml" + // No args implying project domain attribute deletion + u.UpdaterExt.OnUpdateWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(nil) + err = updateExecutionQueueAttributesFunc(ctx, nil, cmdCtx) + assert.Nil(t, err) + tearDownAndVerify(t, ``) + }) + t.Run("failed update workflow attribute", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + executionqueueattribute.DefaultUpdateConfig.AttrFile = "testdata/valid_workflow_execution_queue_attribute.yaml" + // No args implying project domain attribute deletion + u.UpdaterExt.OnUpdateWorkflowAttributesMatch(mock.Anything, mock.Anything, mock.Anything, + mock.Anything, mock.Anything).Return(fmt.Errorf("failed to update attributes")) + err = updateExecutionQueueAttributesFunc(ctx, nil, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("failed to update attributes"), err) + tearDownAndVerify(t, ``) + }) + t.Run("non existent file", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + executionqueueattribute.DefaultUpdateConfig.AttrFile = testDataNonExistentFile + err = updateExecutionQueueAttributesFunc(ctx, nil, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("unable to read from testdata/non-existent-file yaml file"), err) + tearDownAndVerify(t, ``) + }) + t.Run("invalid update file", func(t *testing.T) { + setup() + updateExecutionQueueAttributeSetup() + executionqueueattribute.DefaultUpdateConfig.AttrFile = testDataInvalidAttrFile + err = updateExecutionQueueAttributesFunc(ctx, nil, cmdCtx) + assert.NotNil(t, err) + assert.Equal(t, fmt.Errorf("error unmarshaling JSON: while decoding JSON: json: unknown field \"InvalidDomain\""), err) + tearDownAndVerify(t, ``) + }) +} diff --git a/cmd/update/matchable_task_resource_attribute.go b/cmd/update/matchable_task_resource_attribute.go index 84e3128145..3e351baa95 100644 --- a/cmd/update/matchable_task_resource_attribute.go +++ b/cmd/update/matchable_task_resource_attribute.go @@ -15,42 +15,46 @@ const ( Updates task resource attributes for given project and domain combination or additionally with workflow name. Updating the task resource attribute is only available from a generated file. See the get section for generating this file. +Also this will completely overwrite any existing custom project and domain and workflow combination attributes. +Would be preferable to do get and generate an attribute file if there is an existing attribute already set and then update it to have new values +Refer to get task-resource-attribute section on how to generate this file Here the command updates takes the input for task resource attributes from the config file tra.yaml eg: content of tra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" :: - flytectl update task-resource-attribute -attrFile tra.yaml + flytectl update task-resource-attribute --attrFile tra.yaml Updating task resource attribute for project and domain and workflow combination. This will take precedence over any other resource attribute defined at project domain level. Update the resource attributes for workflow core.control_flow.run_merge_sort.merge_sort in flytectldemo , development domain + .. code-block:: yaml - domain: development - project: flytectldemo - workflow: core.control_flow.run_merge_sort.merge_sort - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + workflow: core.control_flow.run_merge_sort.merge_sort + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" :: - flytectl update task-resource-attribute -attrFile tra.yaml + flytectl update task-resource-attribute --attrFile tra.yaml Usage diff --git a/cmd/update/matchable_task_resource_attribute_test.go b/cmd/update/matchable_task_resource_attribute_test.go index 75aca56c29..a5dd5f7a02 100644 --- a/cmd/update/matchable_task_resource_attribute_test.go +++ b/cmd/update/matchable_task_resource_attribute_test.go @@ -76,16 +76,16 @@ func TestUpdateTaskResourceAttributes(t *testing.T) { t.Run("non existent file", func(t *testing.T) { setup() updateTaskResourceAttributeSetup() - taskresourceattribute.DefaultUpdateConfig.AttrFile = "testdata/non-existent-filel" + taskresourceattribute.DefaultUpdateConfig.AttrFile = testDataNonExistentFile err = updateTaskResourceAttributesFunc(ctx, nil, cmdCtx) assert.NotNil(t, err) - assert.Equal(t, fmt.Errorf("unable to read from testdata/non-existent-filel yaml file"), err) + assert.Equal(t, fmt.Errorf("unable to read from testdata/non-existent-file yaml file"), err) tearDownAndVerify(t, ``) }) t.Run("invalid update file", func(t *testing.T) { setup() updateTaskResourceAttributeSetup() - taskresourceattribute.DefaultUpdateConfig.AttrFile = "testdata/invalid_attribute.yaml" + taskresourceattribute.DefaultUpdateConfig.AttrFile = testDataInvalidAttrFile err = updateTaskResourceAttributesFunc(ctx, nil, cmdCtx) assert.NotNil(t, err) assert.Equal(t, fmt.Errorf("error unmarshaling JSON: while decoding JSON: json: unknown field \"InvalidDomain\""), err) diff --git a/cmd/update/testdata/valid_project_domain_execution_queue_attribute.yaml b/cmd/update/testdata/valid_project_domain_execution_queue_attribute.yaml new file mode 100644 index 0000000000..d04a525b88 --- /dev/null +++ b/cmd/update/testdata/valid_project_domain_execution_queue_attribute.yaml @@ -0,0 +1,7 @@ +domain: development +project: flytectldemo +tags: + - foo + - bar + - buzz + - lightyear \ No newline at end of file diff --git a/cmd/update/testdata/valid_workflow_execution_queue_attribute.yaml b/cmd/update/testdata/valid_workflow_execution_queue_attribute.yaml new file mode 100644 index 0000000000..7c69c43fec --- /dev/null +++ b/cmd/update/testdata/valid_workflow_execution_queue_attribute.yaml @@ -0,0 +1,8 @@ +domain: development +project: flytectldemo +workflow: core.control_flow.run_merge_sort.merge_sort +tags: + - foo + - bar + - buzz + - lightyear \ No newline at end of file diff --git a/cmd/update/update.go b/cmd/update/update.go index 203407d306..5ea12d3899 100644 --- a/cmd/update/update.go +++ b/cmd/update/update.go @@ -2,6 +2,7 @@ package update import ( "github.com/flyteorg/flytectl/cmd/config/subcommand/clusterresourceattribute" + "github.com/flyteorg/flytectl/cmd/config/subcommand/executionqueueattribute" "github.com/flyteorg/flytectl/cmd/config/subcommand/taskresourceattribute" cmdCore "github.com/flyteorg/flytectl/cmd/core" @@ -42,6 +43,8 @@ func CreateUpdateCommand() *cobra.Command { Short: taskResourceAttributesShort, Long: taskResourceAttributesLong, ProjectDomainNotRequired: true}, "cluster-resource-attribute": {CmdFunc: updateClusterResourceAttributesFunc, Aliases: []string{}, PFlagProvider: clusterresourceattribute.DefaultUpdateConfig, Short: clusterResourceAttributesShort, Long: clusterResourceAttributesLong, ProjectDomainNotRequired: true}, + "execution-queue-attribute": {CmdFunc: updateExecutionQueueAttributesFunc, Aliases: []string{}, PFlagProvider: executionqueueattribute.DefaultUpdateConfig, + Short: executionQueueAttributesShort, Long: executionQueueAttributesLong, ProjectDomainNotRequired: true}, } cmdCore.AddCommands(updateCmd, updateResourcesFuncs) return updateCmd diff --git a/cmd/update/update_test.go b/cmd/update/update_test.go index abebad5236..953bc712ab 100644 --- a/cmd/update/update_test.go +++ b/cmd/update/update_test.go @@ -18,6 +18,12 @@ var ( mockClient *mocks.AdminServiceClient cmdCtx cmdCore.CommandContext ) + +const ( + testDataNonExistentFile = "testdata/non-existent-file" + testDataInvalidAttrFile = "testdata/invalid_attribute.yaml" +) + var setup = testutils.Setup var tearDownAndVerify = testutils.TearDownAndVerify @@ -26,18 +32,18 @@ func TestUpdateCommand(t *testing.T) { assert.Equal(t, updateCommand.Use, updateUse) assert.Equal(t, updateCommand.Short, updateShort) assert.Equal(t, updateCommand.Long, updatecmdLong) - assert.Equal(t, len(updateCommand.Commands()), 6) + assert.Equal(t, len(updateCommand.Commands()), 7) cmdNouns := updateCommand.Commands() // Sort by Use value. sort.Slice(cmdNouns, func(i, j int) bool { return cmdNouns[i].Use < cmdNouns[j].Use }) - useArray := []string{"cluster-resource-attribute", "launchplan", "project", "task", + useArray := []string{"cluster-resource-attribute", "execution-queue-attribute", "launchplan", "project", "task", "task-resource-attribute", "workflow"} - aliases := [][]string{{}, {}, {}, {}, {}, {}} - shortArray := []string{clusterResourceAttributesShort, updateLPShort, projectShort, updateTaskShort, + aliases := [][]string{{}, {}, {}, {}, {}, {}, {}} + shortArray := []string{clusterResourceAttributesShort, executionQueueAttributesShort, updateLPShort, projectShort, updateTaskShort, taskResourceAttributesShort, updateWorkflowShort} - longArray := []string{clusterResourceAttributesLong, updateLPLong, projectLong, updateTaskLong, + longArray := []string{clusterResourceAttributesLong, executionQueueAttributesLong, updateLPLong, projectLong, updateTaskLong, taskResourceAttributesLong, updateWorkflowLong} for i := range cmdNouns { assert.Equal(t, cmdNouns[i].Use, useArray[i]) diff --git a/docs/source/gen/flytectl_delete.rst b/docs/source/gen/flytectl_delete.rst index be95495573..f766162a09 100644 --- a/docs/source/gen/flytectl_delete.rst +++ b/docs/source/gen/flytectl_delete.rst @@ -73,5 +73,6 @@ SEE ALSO * :doc:`flytectl` - flyetcl CLI tool * :doc:`flytectl_delete_cluster-resource-attribute` - Deletes matchable resources of cluster attributes * :doc:`flytectl_delete_execution` - Terminate/Delete execution resources. +* :doc:`flytectl_delete_execution-queue-attribute` - Deletes matchable resources of execution queue attributes * :doc:`flytectl_delete_task-resource-attribute` - Deletes matchable resources of task attributes diff --git a/docs/source/gen/flytectl_delete_cluster-resource-attribute.rst b/docs/source/gen/flytectl_delete_cluster-resource-attribute.rst index bb342e1ed9..9971f0bc79 100644 --- a/docs/source/gen/flytectl_delete_cluster-resource-attribute.rst +++ b/docs/source/gen/flytectl_delete_cluster-resource-attribute.rst @@ -19,8 +19,9 @@ Here the command delete cluster resource attributes for project flytectldemo an flytectl delete cluster-resource-attribute -p flytectldemo -d development -Deleting cluster resource attribute using config file which was used for creating it. +Deletes cluster resource attribute using config file which was used for creating it. Here the command deletes cluster resource attributes from the config file cra.yaml +Attributes are optional in the file as they are unread during the delete command but can be kept as the same file can be used for get, update or delete eg: content of cra.yaml which will use the project domain and workflow name for deleting the resource :: @@ -30,13 +31,13 @@ eg: content of cra.yaml which will use the project domain and workflow name for .. code-block:: yaml - domain: development - project: flytectldemo - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + attributes: + foo: "bar" + buzz: "lightyear" -Deleting cluster resource attribute for a workflow +Deletes cluster resource attribute for a workflow Here the command deletes cluster resource attributes for a workflow :: diff --git a/docs/source/gen/flytectl_delete_execution-queue-attribute.rst b/docs/source/gen/flytectl_delete_execution-queue-attribute.rst new file mode 100644 index 0000000000..d016f47ced --- /dev/null +++ b/docs/source/gen/flytectl_delete_execution-queue-attribute.rst @@ -0,0 +1,112 @@ +.. _flytectl_delete_execution-queue-attribute: + +flytectl delete execution-queue-attribute +----------------------------------------- + +Deletes matchable resources of execution queue attributes + +Synopsis +~~~~~~~~ + + + +Deletes execution queue attributes for given project and domain combination or additionally with workflow name. + +Deletes execution queue attribute for project and domain +Here the command delete execution queue attributes for project flytectldemo and development domain. +:: + + flytectl delete execution-queue-attribute -p flytectldemo -d development + + +Deletes execution queue attribute using config file which was used for creating it. +Here the command deletes execution queue attributes from the config file era.yaml +Tags are optional in the file as they are unread during the delete command but can be kept as the same file can be used for get, update or delete +eg: content of era.yaml which will use the project domain and workflow name for deleting the resource + +:: + + flytectl delete execution-queue-attribute --attrFile era.yaml + + +.. code-block:: yaml + + domain: development + project: flytectldemo + tags: + - foo + - bar + - buzz + - lightyear + +Deletes execution queue attribute for a workflow +Here the command deletes the execution queue attributes for a workflow + +:: + + flytectl delete execution-queue-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +Usage + + +:: + + flytectl delete execution-queue-attribute [flags] + +Options +~~~~~~~ + +:: + + --attrFile string attribute file name to be used for delete attribute for the resource type. + -h, --help help for execution-queue-attribute + +Options inherited from parent commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + --admin.authorizationHeader string Custom metadata header to pass JWT + --admin.authorizationServerUrl string This is the URL to your IdP's authorization server. It'll default to Endpoint + --admin.clientId string Client ID (default "flytepropeller") + --admin.clientSecretLocation string File containing the client secret (default "/etc/secrets/client_secret") + --admin.endpoint string For admin types, specify where the uri of the service is located. + --admin.insecure Use insecure connection. + --admin.maxBackoffDelay string Max delay for grpc backoff (default "8s") + --admin.maxRetries int Max number of gRPC retries (default 4) + --admin.perRetryTimeout string gRPC per retry timeout (default "15s") + --admin.scopes strings List of scopes to request + --admin.tokenUrl string OPTIONAL: Your IdP's token endpoint. It'll be discovered from flyte admin's OAuth Metadata endpoint if not provided. + --admin.useAuth Deprecated: Auth will be enabled/disabled based on admin's dynamically discovered information. + --adminutils.batchSize int Maximum number of records to retrieve per call. (default 100) + --adminutils.maxRecords int Maximum number of records to retrieve. (default 500) + --config string config file (default is $HOME/.flyte/config.yaml) + -d, --domain string Specifies the Flyte project's domain. + --logger.formatter.type string Sets logging format type. (default "json") + --logger.level int Sets the minimum logging level. (default 4) + --logger.mute Mutes all logs regardless of severity. Intended for benchmarks/tests only. + --logger.show-source Includes source code location in logs. + -o, --output string Specifies the output type - supported formats [TABLE JSON YAML] (default "TABLE") + -p, --project string Specifies the Flyte project. + --root.domain string Specified the domain to work on. + --root.output string Specified the output type. + --root.project string Specifies the project to work on. + --storage.cache.max_size_mbs int Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + --storage.cache.target_gc_percent int Sets the garbage collection target percentage. + --storage.connection.access-key string Access key to use. Only required when authtype is set to accesskey. + --storage.connection.auth-type string Auth Type to use [iam, accesskey]. (default "iam") + --storage.connection.disable-ssl Disables SSL connection. Should only be used for development. + --storage.connection.endpoint string URL for storage client to connect to. + --storage.connection.region string Region to connect to. (default "us-east-1") + --storage.connection.secret-key string Secret to use when accesskey is set. + --storage.container string Initial container to create -if it doesn't exist-.' + --storage.defaultHttpClient.timeout string Sets time out on the http client. (default "0s") + --storage.enable-multicontainer If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + --storage.limits.maxDownloadMBs int Maximum allowed download size (in MBs) per call. (default 2) + --storage.type string Sets the type of storage to configure [s3/minio/local/mem/stow]. (default "s3") + +SEE ALSO +~~~~~~~~ + +* :doc:`flytectl_delete` - Used for terminating/deleting various flyte resources including tasks/workflows/launchplans/executions/project. + diff --git a/docs/source/gen/flytectl_delete_task-resource-attribute.rst b/docs/source/gen/flytectl_delete_task-resource-attribute.rst index d31faa8b9f..c393da6c54 100644 --- a/docs/source/gen/flytectl_delete_task-resource-attribute.rst +++ b/docs/source/gen/flytectl_delete_task-resource-attribute.rst @@ -19,8 +19,9 @@ Here the command delete task resource attributes for project flytectldemo and d flytectl delete task-resource-attribute -p flytectldemo -d development -Deleting task resource attribute using config file which was used for creating it. +Deletes task resource attribute using config file which was used for creating it. Here the command deletes task resource attributes from the config file tra.yaml +defaults/limits are optional in the file as they are unread during the delete command but can be kept as the same file can be used for get, update or delete eg: content of tra.yaml which will use the project domain and workflow name for deleting the resource :: @@ -30,16 +31,16 @@ eg: content of tra.yaml which will use the project domain and workflow name for .. code-block:: yaml - domain: development - project: flytectldemo - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" -Deleting task resource attribute for a workflow +Deletes task resource attribute for a workflow Here the command deletes task resource attributes for a workflow :: diff --git a/docs/source/gen/flytectl_get.rst b/docs/source/gen/flytectl_get.rst index 7a37881b50..2852cda14a 100644 --- a/docs/source/gen/flytectl_get.rst +++ b/docs/source/gen/flytectl_get.rst @@ -73,6 +73,7 @@ SEE ALSO * :doc:`flytectl` - flyetcl CLI tool * :doc:`flytectl_get_cluster-resource-attribute` - Gets matchable resources of cluster resource attributes * :doc:`flytectl_get_execution` - Gets execution resources +* :doc:`flytectl_get_execution-queue-attribute` - Gets matchable resources of execution queue attributes * :doc:`flytectl_get_launchplan` - Gets launch plan resources * :doc:`flytectl_get_project` - Gets project resources * :doc:`flytectl_get_task` - Gets task resources diff --git a/docs/source/gen/flytectl_get_cluster-resource-attribute.rst b/docs/source/gen/flytectl_get_cluster-resource-attribute.rst index db51d52098..5dfa50b3e1 100644 --- a/docs/source/gen/flytectl_get_cluster-resource-attribute.rst +++ b/docs/source/gen/flytectl_get_cluster-resource-attribute.rst @@ -18,28 +18,40 @@ Here the command get cluster resource attributes for project flytectldemo and d flytectl get cluster-resource-attribute -p flytectldemo -d development -eg : O/P +eg : output from the command .. code-block:: json {"project":"flytectldemo","domain":"development","attributes":{"buzz":"lightyear","foo":"bar"}} +Retrieves cluster resource attribute for project and domain and workflow +Here the command get cluster resource attributes for project flytectldemo ,development domain and workflow core.control_flow.run_merge_sort.merge_sort +:: + + flytectl get cluster-resource-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","workflow":"core.control_flow.run_merge_sort.merge_sort","attributes":{"buzz":"lightyear","foo":"bar"}} + Writing the cluster resource attribute to a file. If there are no cluster resource attributes , command would return an error. -Here the command gets task resource attributes and writes the config file to tra.yaml -eg: content of tra.yaml +Here the command gets task resource attributes and writes the config file to cra.yaml +eg: content of cra.yaml :: - flytectl get task-resource-attribute --attrFile tra.yaml + flytectl get task-resource-attribute --attrFile cra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + attributes: + foo: "bar" + buzz: "lightyear" Usage diff --git a/docs/source/gen/flytectl_get_execution-queue-attribute.rst b/docs/source/gen/flytectl_get_execution-queue-attribute.rst new file mode 100644 index 0000000000..db008340a4 --- /dev/null +++ b/docs/source/gen/flytectl_get_execution-queue-attribute.rst @@ -0,0 +1,121 @@ +.. _flytectl_get_execution-queue-attribute: + +flytectl get execution-queue-attribute +-------------------------------------- + +Gets matchable resources of execution queue attributes + +Synopsis +~~~~~~~~ + + + +Retrieves execution queue attributes for given project and domain combination or additionally with workflow name. + +Retrieves execution queue attribute for project and domain +Here the command get execution queue attributes for project flytectldemo and development domain. +:: + + flytectl get execution-queue-attribute -p flytectldemo -d development + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","tags":["foo", "bar"]} + +Retrieves execution queue attribute for project and domain and workflow +Here the command get execution queue attributes for project flytectldemo ,development domain and workflow core.control_flow.run_merge_sort.merge_sort +:: + + flytectl get execution-queue-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","workflow":"core.control_flow.run_merge_sort.merge_sort","tags":["foo", "bar"]} + +Writing the execution queue attribute to a file. If there are no execution queue attributes, command would return an error. +Here the command gets execution queue attributes and writes the config file to era.yaml +eg: content of era.yaml + +:: + + flytectl get execution-queue-attribute --attrFile era.yaml + + +.. code-block:: yaml + + domain: development + project: flytectldemo + tags: + - foo + - bar + - buzz + - lightyear + +Usage + + +:: + + flytectl get execution-queue-attribute [flags] + +Options +~~~~~~~ + +:: + + --attrFile string attribute file name to be used for generating attribute for the resource type. + -h, --help help for execution-queue-attribute + +Options inherited from parent commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + --admin.authorizationHeader string Custom metadata header to pass JWT + --admin.authorizationServerUrl string This is the URL to your IdP's authorization server. It'll default to Endpoint + --admin.clientId string Client ID (default "flytepropeller") + --admin.clientSecretLocation string File containing the client secret (default "/etc/secrets/client_secret") + --admin.endpoint string For admin types, specify where the uri of the service is located. + --admin.insecure Use insecure connection. + --admin.maxBackoffDelay string Max delay for grpc backoff (default "8s") + --admin.maxRetries int Max number of gRPC retries (default 4) + --admin.perRetryTimeout string gRPC per retry timeout (default "15s") + --admin.scopes strings List of scopes to request + --admin.tokenUrl string OPTIONAL: Your IdP's token endpoint. It'll be discovered from flyte admin's OAuth Metadata endpoint if not provided. + --admin.useAuth Deprecated: Auth will be enabled/disabled based on admin's dynamically discovered information. + --adminutils.batchSize int Maximum number of records to retrieve per call. (default 100) + --adminutils.maxRecords int Maximum number of records to retrieve. (default 500) + --config string config file (default is $HOME/.flyte/config.yaml) + -d, --domain string Specifies the Flyte project's domain. + --logger.formatter.type string Sets logging format type. (default "json") + --logger.level int Sets the minimum logging level. (default 4) + --logger.mute Mutes all logs regardless of severity. Intended for benchmarks/tests only. + --logger.show-source Includes source code location in logs. + -o, --output string Specifies the output type - supported formats [TABLE JSON YAML] (default "TABLE") + -p, --project string Specifies the Flyte project. + --root.domain string Specified the domain to work on. + --root.output string Specified the output type. + --root.project string Specifies the project to work on. + --storage.cache.max_size_mbs int Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + --storage.cache.target_gc_percent int Sets the garbage collection target percentage. + --storage.connection.access-key string Access key to use. Only required when authtype is set to accesskey. + --storage.connection.auth-type string Auth Type to use [iam, accesskey]. (default "iam") + --storage.connection.disable-ssl Disables SSL connection. Should only be used for development. + --storage.connection.endpoint string URL for storage client to connect to. + --storage.connection.region string Region to connect to. (default "us-east-1") + --storage.connection.secret-key string Secret to use when accesskey is set. + --storage.container string Initial container to create -if it doesn't exist-.' + --storage.defaultHttpClient.timeout string Sets time out on the http client. (default "0s") + --storage.enable-multicontainer If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + --storage.limits.maxDownloadMBs int Maximum allowed download size (in MBs) per call. (default 2) + --storage.type string Sets the type of storage to configure [s3/minio/local/mem/stow]. (default "s3") + +SEE ALSO +~~~~~~~~ + +* :doc:`flytectl_get` - Used for fetching various flyte resources including tasks/workflows/launchplans/executions/project. + diff --git a/docs/source/gen/flytectl_get_task-resource-attribute.rst b/docs/source/gen/flytectl_get_task-resource-attribute.rst index 5c1d307eae..7b4fa5ba74 100644 --- a/docs/source/gen/flytectl_get_task-resource-attribute.rst +++ b/docs/source/gen/flytectl_get_task-resource-attribute.rst @@ -18,11 +18,24 @@ Here the command get task resource attributes for project flytectldemo and deve flytectl get task-resource-attribute -p flytectldemo -d development -eg : O/P +eg : output from the command .. code-block:: json - {"Project":"flytectldemo","Domain":"development","Workflow":"","defaults":{"cpu":"1","memory":"150Mi"},"limits":{"cpu":"2","memory":"450Mi"}} + {"project":"flytectldemo","domain":"development","workflow":"","defaults":{"cpu":"1","memory":"150Mi"},"limits":{"cpu":"2","memory":"450Mi"}} + +Retrieves task resource attribute for project and domain and workflow +Here the command get task resource attributes for project flytectldemo ,development domain and workflow core.control_flow.run_merge_sort.merge_sort +:: + + flytectl get task-resource-attribute -p flytectldemo -d development core.control_flow.run_merge_sort.merge_sort + +eg : output from the command + +.. code-block:: json + + {"project":"flytectldemo","domain":"development","workflow":"core.control_flow.run_merge_sort.merge_sort","defaults":{"cpu":"1","memory":"150Mi"},"limits":{"cpu":"2","memory":"450Mi"}} + Writing the task resource attribute to a file. If there are no task resource attributes a file would be written with basic data populated. Here the command gets task resource attributes and writes the config file to tra.yaml @@ -35,14 +48,14 @@ eg: content of tra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" Usage diff --git a/docs/source/gen/flytectl_update.rst b/docs/source/gen/flytectl_update.rst index 4692575169..3fd3d51b06 100644 --- a/docs/source/gen/flytectl_update.rst +++ b/docs/source/gen/flytectl_update.rst @@ -74,6 +74,7 @@ SEE ALSO * :doc:`flytectl` - flyetcl CLI tool * :doc:`flytectl_update_cluster-resource-attribute` - Updates matchable resources of cluster attributes +* :doc:`flytectl_update_execution-queue-attribute` - Updates matchable resources of execution queue attributes * :doc:`flytectl_update_launchplan` - Updates launch plan metadata * :doc:`flytectl_update_project` - Updates project resources * :doc:`flytectl_update_task` - Updates task metadata diff --git a/docs/source/gen/flytectl_update_cluster-resource-attribute.rst b/docs/source/gen/flytectl_update_cluster-resource-attribute.rst index 96be5e1fa7..f17c81d62b 100644 --- a/docs/source/gen/flytectl_update_cluster-resource-attribute.rst +++ b/docs/source/gen/flytectl_update_cluster-resource-attribute.rst @@ -14,35 +14,39 @@ Updates cluster resource attributes for given project and domain combination or Updating to the cluster resource attribute is only available from a generated file. See the get section for generating this file. Here the command updates takes the input for cluster resource attributes from the config file cra.yaml -eg: content of tra.yaml +eg: content of cra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + attributes: + foo: "bar" + buzz: "lightyear" :: - flytectl update cluster-resource-attribute -attrFile cra.yaml + flytectl update cluster-resource-attribute --attrFile cra.yaml Updating cluster resource attribute for project and domain and workflow combination. This will take precedence over any other resource attribute defined at project domain level. +Also this will completely overwrite any existing custom project and domain and workflow combination attributes. +Would be preferable to do get and generate an attribute file if there is an existing attribute already set and then update it to have new values +Refer to get cluster-resource-attribute section on how to generate this file Update the cluster resource attributes for workflow core.control_flow.run_merge_sort.merge_sort in flytectldemo , development domain + .. code-block:: yaml - domain: development - project: flytectldemo - workflow: core.control_flow.run_merge_sort.merge_sort - attributes: - foo: "bar" - buzz: "lightyear" + domain: development + project: flytectldemo + workflow: core.control_flow.run_merge_sort.merge_sort + attributes: + foo: "bar" + buzz: "lightyear" :: - flytectl update cluster-resource-attribute -attrFile cra.yaml + flytectl update cluster-resource-attribute --attrFile cra.yaml Usage diff --git a/docs/source/gen/flytectl_update_execution-queue-attribute.rst b/docs/source/gen/flytectl_update_execution-queue-attribute.rst new file mode 100644 index 0000000000..e7aa206301 --- /dev/null +++ b/docs/source/gen/flytectl_update_execution-queue-attribute.rst @@ -0,0 +1,119 @@ +.. _flytectl_update_execution-queue-attribute: + +flytectl update execution-queue-attribute +----------------------------------------- + +Updates matchable resources of execution queue attributes + +Synopsis +~~~~~~~~ + + + +Updates execution queue attributes for given project and domain combination or additionally with workflow name. + +Updating to the execution queue attribute is only available from a generated file. See the get section for generating this file. +Also this will completely overwrite any existing custom project and domain and workflow combination attributes. +Would be preferable to do get and generate an attribute file if there is an existing attribute already set and then update it to have new values +Refer to get execution-queue-attribute section on how to generate this file +Here the command updates takes the input for execution queue attributes from the config file era.yaml +eg: content of era.yaml + +.. code-block:: yaml + + domain: development + project: flytectldemo + tags: + - foo + - bar + - buzz + - lightyear + +:: + + flytectl update execution-queue-attribute --attrFile era.yaml + +Updating execution queue attribute for project and domain and workflow combination. This will take precedence over any other +execution queue attribute defined at project domain level. +Update the execution queue attributes for workflow core.control_flow.run_merge_sort.merge_sort in flytectldemo , development domain + +.. code-block:: yaml + + domain: development + project: flytectldemo + workflow: core.control_flow.run_merge_sort.merge_sort + tags: + - foo + - bar + - buzz + - lightyear + +:: + + flytectl update execution-queue-attribute --attrFile era.yaml + +Usage + + + +:: + + flytectl update execution-queue-attribute [flags] + +Options +~~~~~~~ + +:: + + --attrFile string attribute file name to be used for updating attribute for the resource type. + -h, --help help for execution-queue-attribute + +Options inherited from parent commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + --admin.authorizationHeader string Custom metadata header to pass JWT + --admin.authorizationServerUrl string This is the URL to your IdP's authorization server. It'll default to Endpoint + --admin.clientId string Client ID (default "flytepropeller") + --admin.clientSecretLocation string File containing the client secret (default "/etc/secrets/client_secret") + --admin.endpoint string For admin types, specify where the uri of the service is located. + --admin.insecure Use insecure connection. + --admin.maxBackoffDelay string Max delay for grpc backoff (default "8s") + --admin.maxRetries int Max number of gRPC retries (default 4) + --admin.perRetryTimeout string gRPC per retry timeout (default "15s") + --admin.scopes strings List of scopes to request + --admin.tokenUrl string OPTIONAL: Your IdP's token endpoint. It'll be discovered from flyte admin's OAuth Metadata endpoint if not provided. + --admin.useAuth Deprecated: Auth will be enabled/disabled based on admin's dynamically discovered information. + --adminutils.batchSize int Maximum number of records to retrieve per call. (default 100) + --adminutils.maxRecords int Maximum number of records to retrieve. (default 500) + --config string config file (default is $HOME/.flyte/config.yaml) + -d, --domain string Specifies the Flyte project's domain. + --logger.formatter.type string Sets logging format type. (default "json") + --logger.level int Sets the minimum logging level. (default 4) + --logger.mute Mutes all logs regardless of severity. Intended for benchmarks/tests only. + --logger.show-source Includes source code location in logs. + -o, --output string Specifies the output type - supported formats [TABLE JSON YAML] (default "TABLE") + -p, --project string Specifies the Flyte project. + --root.domain string Specified the domain to work on. + --root.output string Specified the output type. + --root.project string Specifies the project to work on. + --storage.cache.max_size_mbs int Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + --storage.cache.target_gc_percent int Sets the garbage collection target percentage. + --storage.connection.access-key string Access key to use. Only required when authtype is set to accesskey. + --storage.connection.auth-type string Auth Type to use [iam, accesskey]. (default "iam") + --storage.connection.disable-ssl Disables SSL connection. Should only be used for development. + --storage.connection.endpoint string URL for storage client to connect to. + --storage.connection.region string Region to connect to. (default "us-east-1") + --storage.connection.secret-key string Secret to use when accesskey is set. + --storage.container string Initial container to create -if it doesn't exist-.' + --storage.defaultHttpClient.timeout string Sets time out on the http client. (default "0s") + --storage.enable-multicontainer If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + --storage.limits.maxDownloadMBs int Maximum allowed download size (in MBs) per call. (default 2) + --storage.type string Sets the type of storage to configure [s3/minio/local/mem/stow]. (default "s3") + +SEE ALSO +~~~~~~~~ + +* :doc:`flytectl_update` - Used for updating flyte resources eg: project. + diff --git a/docs/source/gen/flytectl_update_task-resource-attribute.rst b/docs/source/gen/flytectl_update_task-resource-attribute.rst index fd4b141361..8e13080509 100644 --- a/docs/source/gen/flytectl_update_task-resource-attribute.rst +++ b/docs/source/gen/flytectl_update_task-resource-attribute.rst @@ -13,42 +13,46 @@ Synopsis Updates task resource attributes for given project and domain combination or additionally with workflow name. Updating the task resource attribute is only available from a generated file. See the get section for generating this file. +Also this will completely overwrite any existing custom project and domain and workflow combination attributes. +Would be preferable to do get and generate an attribute file if there is an existing attribute already set and then update it to have new values +Refer to get task-resource-attribute section on how to generate this file Here the command updates takes the input for task resource attributes from the config file tra.yaml eg: content of tra.yaml .. code-block:: yaml - domain: development - project: flytectldemo - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" :: - flytectl update task-resource-attribute -attrFile tra.yaml + flytectl update task-resource-attribute --attrFile tra.yaml Updating task resource attribute for project and domain and workflow combination. This will take precedence over any other resource attribute defined at project domain level. Update the resource attributes for workflow core.control_flow.run_merge_sort.merge_sort in flytectldemo , development domain + .. code-block:: yaml - domain: development - project: flytectldemo - workflow: core.control_flow.run_merge_sort.merge_sort - defaults: - cpu: "1" - memory: "150Mi" - limits: - cpu: "2" - memory: "450Mi" + domain: development + project: flytectldemo + workflow: core.control_flow.run_merge_sort.merge_sort + defaults: + cpu: "1" + memory: "150Mi" + limits: + cpu: "2" + memory: "450Mi" :: - flytectl update task-resource-attribute -attrFile tra.yaml + flytectl update task-resource-attribute --attrFile tra.yaml Usage diff --git a/docs/source/nouns.rst b/docs/source/nouns.rst index e65582ff28..3c546cbfab 100644 --- a/docs/source/nouns.rst +++ b/docs/source/nouns.rst @@ -14,6 +14,7 @@ Nouns gen/flytectl_get_task gen/flytectl_get_task-resource-attribute gen/flytectl_get_cluster-resource-attribute + gen/flytectl_get_execution-queue-attribute gen/flytectl_get_launchplan gen/flytectl_update_launchplan gen/flytectl_update_workflow @@ -21,10 +22,12 @@ Nouns gen/flytectl_update_task gen/flytectl_update_task-resource-attribute gen/flytectl_update_cluster-resource-attribute + gen/flytectl_update_execution-queue-attribute gen/flytectl_register_files gen/flytectl_delete_execution gen/flytectl_delete_task-resource-attribute gen/flytectl_delete_cluster-resource-attribute + gen/flytectl_delete_execution-queue-attribute gen/flytectl_version gen/flytectl_config_validate gen/flytectl_config_discover