diff --git a/Makefile b/Makefile index 11ab1d6..6bdf533 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ generate: deps mockgen --destination ./internal/mocks/cloud_computing_regions_service.go --package=mocks --source ./vendor/github.com/serverscom/serverscom-go-client/pkg/cloud_computing_regions.go mockgen --destination ./internal/mocks/cloud_block_storage_volumes_service.go --package=mocks --source ./vendor/github.com/serverscom/serverscom-go-client/pkg/cloud_block_storage_volumes.go mockgen --destination ./internal/mocks/cloud_block_storage_backups_service.go --package=mocks --source ./vendor/github.com/serverscom/serverscom-go-client/pkg/cloud_block_storage_backups.go + mockgen --destination ./internal/mocks/dns_service.go --package=mocks --source ./vendor/github.com/serverscom/serverscom-go-client/pkg/dns.go sed -i '' 's|github.com/serverscom/srvctl/vendor/github.com/serverscom/serverscom-go-client/pkg|github.com/serverscom/serverscom-go-client/pkg|g' \ ./internal/mocks/ssh_service.go \ ./internal/mocks/hosts_service.go \ @@ -43,7 +44,8 @@ generate: deps ./internal/mocks/cloud_instances_service.go \ ./internal/mocks/cloud_computing_regions_service.go \ ./internal/mocks/cloud_block_storage_volumes_service.go \ - ./internal/mocks/cloud_block_storage_backups_service.go + ./internal/mocks/cloud_block_storage_backups_service.go \ + ./internal/mocks/dns_service.go docs: go run cmd/gendoc/main.go diff --git a/cmd/base/hooks.go b/cmd/base/hooks.go index d0bfc13..13c7a9f 100644 --- a/cmd/base/hooks.go +++ b/cmd/base/hooks.go @@ -81,9 +81,6 @@ func CheckFormatterFlags(cmdContext *CmdContext, entities map[string]entities.En if entity == nil { return fmt.Errorf("can't find entity") } - if err := entity.SetCmdDefaultFields(cmd.Name()); err != nil { - return err - } if fieldList { formatter.ListEntityFields(entity.GetFields()) os.Exit(0) diff --git a/cmd/base/list_options.go b/cmd/base/list_options.go index 26cf026..d6ed1e4 100644 --- a/cmd/base/list_options.go +++ b/cmd/base/list_options.go @@ -530,3 +530,33 @@ func (o *IsBackupOption[T]) ApplyToCollection(collection serverscom.Collection[T collection.SetParam("is_backup", "true") } } + +// dns domain delegation status option +type DelegationStatusOption[T any] struct { + delegationStatus string +} + +func (o *DelegationStatusOption[T]) AddFlags(cmd *cobra.Command) { + cmd.Flags().StringVar(&o.delegationStatus, "delegation-status", "", "Filter results by delegation status (delegated, verified, undelegated)") +} + +func (o *DelegationStatusOption[T]) ApplyToCollection(collection serverscom.Collection[T]) { + if o.delegationStatus != "" { + collection.SetParam("delegation_status", o.delegationStatus) + } +} + +// dns record type option +type DNSRecordTypeOption[T any] struct { + recordType string +} + +func (o *DNSRecordTypeOption[T]) AddFlags(cmd *cobra.Command) { + cmd.Flags().StringVar(&o.recordType, "type", "", "Filter results by record type (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, ALIAS, PTR, SOA)") +} + +func (o *DNSRecordTypeOption[T]) ApplyToCollection(collection serverscom.Collection[T]) { + if o.recordType != "" { + collection.SetParam("type", strings.ToUpper(o.recordType)) + } +} diff --git a/cmd/entities/cloud-instances/ptr.go b/cmd/entities/cloud-instances/ptr.go index 59511b5..fbd7466 100644 --- a/cmd/entities/cloud-instances/ptr.go +++ b/cmd/entities/cloud-instances/ptr.go @@ -25,9 +25,9 @@ func newAddPTRCmd(cmdContext *base.CmdContext) *cobra.Command { base.SetupProxy(cmd, manager) - input := serverscom.PTRRecordCreateInput{ - Domain: data, - IP: ip, + input := serverscom.CloudComputingInstancePTRRecordCreateInput{ + Data: data, + IP: ip, } if cmd.Flags().Changed("ttl") { input.TTL = &ttl diff --git a/cmd/entities/cloud-instances/ptr_test.go b/cmd/entities/cloud-instances/ptr_test.go index a75f335..3a22448 100644 --- a/cmd/entities/cloud-instances/ptr_test.go +++ b/cmd/entities/cloud-instances/ptr_test.go @@ -161,8 +161,8 @@ func TestAddPTRCmd(t *testing.T) { output: "json", expectedOutput: testutils.ReadFixture(filepath.Join(ptrFixtureBasePath, "get.json")), configureMock: func(mock *mocks.MockCloudComputingInstancesService) { - in := serverscom.PTRRecordCreateInput{ - Domain: testPTR.Domain, + in := serverscom.CloudComputingInstancePTRRecordCreateInput{ + Data: testPTR.Domain, IP: testPTR.IP, TTL: &testPTR.TTL, Priority: &testPTR.Priority, @@ -177,9 +177,9 @@ func TestAddPTRCmd(t *testing.T) { args: []string{testInstanceID, "--data", testPTR.Domain, "--ip", testPTR.IP}, expectError: true, configureMock: func(mock *mocks.MockCloudComputingInstancesService) { - in := serverscom.PTRRecordCreateInput{ - Domain: testPTR.Domain, - IP: testPTR.IP, + in := serverscom.CloudComputingInstancePTRRecordCreateInput{ + Data: testPTR.Domain, + IP: testPTR.IP, } mock.EXPECT(). CreatePTRRecord(gomock.Any(), testInstanceID, in). diff --git a/cmd/entities/cloud-volumes/update.go b/cmd/entities/cloud-volumes/update.go index a6fd0ba..a8c6cac 100644 --- a/cmd/entities/cloud-volumes/update.go +++ b/cmd/entities/cloud-volumes/update.go @@ -11,8 +11,6 @@ import ( func newUpdateCmd(cmdContext *base.CmdContext) *cobra.Command { var name string var description string - var imageID string - var snapshotID string var labels []string cmd := &cobra.Command{ @@ -35,8 +33,6 @@ func newUpdateCmd(cmdContext *base.CmdContext) *cobra.Command { input := serverscom.CloudBlockStorageVolumeUpdateInput{ Name: name, Description: description, - ImageID: imageID, - SnapshotID: snapshotID, Labels: labelsMap, } @@ -58,8 +54,6 @@ func newUpdateCmd(cmdContext *base.CmdContext) *cobra.Command { cmd.Flags().StringVarP(&name, "name", "n", "", "A name of the cloud volume") cmd.Flags().StringVar(&description, "description", "", "Description of the volume") - cmd.Flags().StringVar(&imageID, "image-id", "", "ID of the image") - cmd.Flags().StringVar(&snapshotID, "snapshot-id", "", "ID of the snapshot") cmd.Flags().StringArrayVarP(&labels, "label", "l", []string{}, "string in key=value format") return cmd diff --git a/cmd/entities/dns/add.go b/cmd/entities/dns/add.go new file mode 100644 index 0000000..1d9c2bc --- /dev/null +++ b/cmd/entities/dns/add.go @@ -0,0 +1,100 @@ +package dns + +import ( + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +type AddedFlags struct { + Skeleton bool + InputPath string + Name string + Email string + TTL int + Labels []string +} + +func newAddCmd(cmdContext *base.CmdContext) *cobra.Command { + flags := &AddedFlags{} + + cmd := &cobra.Command{ + Use: "add", + Short: "Add a DNS domain", + Long: "Create/Register a new DNS domain/zone", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + formatter := cmdContext.GetOrCreateFormatter(cmd) + + if flags.Skeleton { + return formatter.FormatSkeleton("dns/add.json") + } + + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + input := &serverscom.DNSDomainCreateInput{} + + if flags.InputPath != "" { + if err := base.ReadInputJSON(flags.InputPath, cmd.InOrStdin(), input); err != nil { + return err + } + } else { + required := []string{"name", "email"} + if err := base.ValidateFlags(cmd, required); err != nil { + return err + } + } + + if err := flags.FillInput(cmd, input); err != nil { + return err + } + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + domain, err := scClient.DNS.CreateDomain(ctx, *input) + if err != nil { + return err + } + + if domain != nil { + return formatter.Format(domain) + } + return nil + }, + } + + cmd.Flags().StringVarP(&flags.InputPath, "input", "i", "", "path to input file or '-' to read from stdin") + cmd.Flags().BoolVarP(&flags.Skeleton, "skeleton", "s", false, "JSON object with structure that is required to be passed") + + cmd.Flags().StringVarP(&flags.Name, "name", "n", "", "A name of a DNS domain") + cmd.Flags().StringVarP(&flags.Email, "email", "", "", "An email used for the zone's SOA record") + cmd.Flags().IntVarP(&flags.TTL, "ttl", "", 0, "A default TTL in seconds (0-604800)") + cmd.Flags().StringArrayVarP(&flags.Labels, "label", "l", []string{}, "string in key=value format") + + return cmd +} + +func (f *AddedFlags) FillInput(cmd *cobra.Command, input *serverscom.DNSDomainCreateInput) error { + if cmd.Flags().Changed("name") { + input.Name = f.Name + } + if cmd.Flags().Changed("email") { + input.Email = f.Email + } + if cmd.Flags().Changed("ttl") { + input.TTL = f.TTL + } + if cmd.Flags().Changed("label") { + labelsMap, err := base.ParseLabels(f.Labels) + if err != nil { + return err + } + + input.Labels = labelsMap + } + + return nil +} diff --git a/cmd/entities/dns/add_record.go b/cmd/entities/dns/add_record.go new file mode 100644 index 0000000..03530b1 --- /dev/null +++ b/cmd/entities/dns/add_record.go @@ -0,0 +1,98 @@ +package dns + +import ( + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +type AddRecordFlags struct { + Skeleton bool + InputPath string + Type string + Name string + Data string + TTL int + Priority int +} + +func newAddRecordCmd(cmdContext *base.CmdContext) *cobra.Command { + flags := &AddRecordFlags{} + + cmd := &cobra.Command{ + Use: "add-record ", + Short: "Add a DNS record", + Long: "Add a new DNS record to a domain", + Args: base.SkeletonOrExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + formatter := cmdContext.GetOrCreateFormatter(cmd) + + if flags.Skeleton { + return formatter.FormatSkeleton("dns/add-record.json") + } + + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + input := &serverscom.DNSRecordCreateInput{} + + if flags.InputPath != "" { + if err := base.ReadInputJSON(flags.InputPath, cmd.InOrStdin(), input); err != nil { + return err + } + } else { + required := []string{"type", "name", "data"} + if err := base.ValidateFlags(cmd, required); err != nil { + return err + } + } + + flags.FillInput(cmd, input) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + record, err := scClient.DNS.CreateRecord(ctx, domainID, *input) + if err != nil { + return err + } + + if record != nil { + return formatter.Format(record) + } + return nil + }, + } + + cmd.Flags().StringVarP(&flags.InputPath, "input", "i", "", "path to input file or '-' to read from stdin") + cmd.Flags().BoolVarP(&flags.Skeleton, "skeleton", "s", false, "JSON object with structure that is required to be passed") + + cmd.Flags().StringVarP(&flags.Type, "type", "", "", "A type of a DNS record (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, ALIAS)") + cmd.Flags().StringVarP(&flags.Name, "name", "n", "", "A name of a DNS record") + cmd.Flags().StringVarP(&flags.Data, "data", "", "", "A data of a DNS record") + cmd.Flags().IntVarP(&flags.TTL, "ttl", "", 0, "A TTL of a DNS record in seconds") + cmd.Flags().IntVarP(&flags.Priority, "priority", "", 0, "A priority of a DNS record (required by convention for MX/SRV, ignored for other types)") + + return cmd +} + +func (f *AddRecordFlags) FillInput(cmd *cobra.Command, input *serverscom.DNSRecordCreateInput) { + if cmd.Flags().Changed("type") { + input.Type = serverscom.DNSRecordType(f.Type) + } + if cmd.Flags().Changed("name") { + input.Name = f.Name + } + if cmd.Flags().Changed("data") { + input.Data = f.Data + } + if cmd.Flags().Changed("ttl") { + input.TTL = &f.TTL + } + if cmd.Flags().Changed("priority") { + input.Priority = &f.Priority + } +} diff --git a/cmd/entities/dns/delegation_data.go b/cmd/entities/dns/delegation_data.go new file mode 100644 index 0000000..c892274 --- /dev/null +++ b/cmd/entities/dns/delegation_data.go @@ -0,0 +1,38 @@ +package dns + +import ( + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newDelegationDataCmd(cmdContext *base.CmdContext) *cobra.Command { + cmd := &cobra.Command{ + Use: "delegation-data", + Short: "Get DNS delegation data", + Long: "Get the nameservers and required TXT record to configure at the domain registrar to delegate/verify a DNS zone", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + data, err := scClient.DNS.GetDelegationData(ctx) + if err != nil { + return err + } + + if data != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(data) + } + return nil + }, + } + + return cmd +} diff --git a/cmd/entities/dns/delete.go b/cmd/entities/dns/delete.go new file mode 100644 index 0000000..a113ef4 --- /dev/null +++ b/cmd/entities/dns/delete.go @@ -0,0 +1,30 @@ +package dns + +import ( + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newDeleteCmd(cmdContext *base.CmdContext) *cobra.Command { + cmd := &cobra.Command{ + Use: "delete ", + Short: "Delete a DNS domain", + Long: "Delete a DNS domain by id", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + return scClient.DNS.DeleteDomain(ctx, domainID) + }, + } + + return cmd +} diff --git a/cmd/entities/dns/delete_record.go b/cmd/entities/dns/delete_record.go new file mode 100644 index 0000000..f2f547e --- /dev/null +++ b/cmd/entities/dns/delete_record.go @@ -0,0 +1,38 @@ +package dns + +import ( + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newDeleteRecordCmd(cmdContext *base.CmdContext) *cobra.Command { + var recordID string + + cmd := &cobra.Command{ + Use: "delete-record --record-id ", + Short: "Delete a DNS record", + Long: "Delete a DNS record by id within a domain", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if err := base.ValidateFlags(cmd, []string{"record-id"}); err != nil { + return err + } + + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + return scClient.DNS.DeleteRecord(ctx, domainID, recordID) + }, + } + + cmd.Flags().StringVarP(&recordID, "record-id", "", "", "A DNS record id") + + return cmd +} diff --git a/cmd/entities/dns/dns.go b/cmd/entities/dns/dns.go new file mode 100644 index 0000000..56f2921 --- /dev/null +++ b/cmd/entities/dns/dns.go @@ -0,0 +1,62 @@ +package dns + +import ( + "log" + + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/serverscom/srvctl/internal/output/entities" + "github.com/spf13/cobra" +) + +func NewCmd(cmdContext *base.CmdContext) *cobra.Command { + dnsDomainEntity, err := entities.Registry.GetEntityFromValue(serverscom.DNSDomain{}) + if err != nil { + log.Fatal(err) + } + dnsRecordEntity, err := entities.Registry.GetEntityFromValue(serverscom.DNSRecord{}) + if err != nil { + log.Fatal(err) + } + dnsDelegationEntity, err := entities.Registry.GetEntityFromValue(serverscom.DNSDomainDelegationData{}) + if err != nil { + log.Fatal(err) + } + + entitiesMap := make(map[string]entities.EntityInterface) + entitiesMap["dns"] = dnsDomainEntity + entitiesMap["list-records"] = dnsRecordEntity + entitiesMap["get-record"] = dnsRecordEntity + entitiesMap["add-record"] = dnsRecordEntity + entitiesMap["update-record"] = dnsRecordEntity + entitiesMap["delegation-data"] = dnsDelegationEntity + + cmd := &cobra.Command{ + Use: "dns", + Short: "Manage DNS domains and records", + PersistentPreRunE: base.CombinePreRunE( + base.CheckFormatterFlags(cmdContext, entitiesMap), + base.CheckEmptyContexts(cmdContext), + ), + Args: base.NoArgs, + Run: base.UsageRun, + } + + cmd.AddCommand( + newListCmd(cmdContext), + newGetCmd(cmdContext), + newAddCmd(cmdContext), + newUpdateCmd(cmdContext), + newDeleteCmd(cmdContext), + newDelegationDataCmd(cmdContext), + newListRecordsCmd(cmdContext), + newGetRecordCmd(cmdContext), + newAddRecordCmd(cmdContext), + newUpdateRecordCmd(cmdContext), + newDeleteRecordCmd(cmdContext), + ) + + base.AddFormatFlags(cmd) + + return cmd +} diff --git a/cmd/entities/dns/dns_test.go b/cmd/entities/dns/dns_test.go new file mode 100644 index 0000000..329dc46 --- /dev/null +++ b/cmd/entities/dns/dns_test.go @@ -0,0 +1,1004 @@ +package dns + +import ( + "errors" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/gomega" + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/testutils" + "github.com/serverscom/srvctl/internal/mocks" + "go.uber.org/mock/gomock" +) + +var ( + fixtureBasePath = filepath.Join("..", "..", "..", "testdata", "entities", "dns") + skeletonTemplatePath = filepath.Join("..", "..", "..", "internal", "output", "skeletons", "templates", "dns") + fixedTime = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC) + + testDomainID = "abc123" + testRecordID = "rec1" + + testDomain = serverscom.DNSDomain{ + ID: testDomainID, + Name: "example.com", + Email: "admin@example.com", + TTL: 3600, + DelegationStatus: serverscom.DNSDomainVerified, + Labels: map[string]string{"foo": "bar"}, + Created: fixedTime, + Updated: fixedTime, + } + + testRecord = serverscom.DNSRecord{ + ID: testRecordID, + DomainID: testDomainID, + Name: "www", + Type: serverscom.DNSRecordTypeA, + Data: new("1.2.3.4"), + TTL: new(3600), + Created: fixedTime, + Updated: fixedTime, + } + + testDelegation = serverscom.DNSDomainDelegationData{ + Nameservers: []string{"ns1.example.com", "ns2.example.com"}, + RequiredTxt: "sc-verification=abc123", + } +) + +func TestAddDNSDomainCmd(t *testing.T) { + testCases := []struct { + name string + output string + args []string + configureMock func(*mocks.MockDNSService) + expectedOutput []byte + expectError bool + }{ + { + name: "create domain with input", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get.json")), + args: []string{"--input", filepath.Join(fixtureBasePath, "create.json")}, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + CreateDomain(gomock.Any(), serverscom.DNSDomainCreateInput{ + Name: "example.com", + Email: "admin@example.com", + TTL: 3600, + Labels: map[string]string{"foo": "bar"}, + }). + Return(&testDomain, nil) + }, + }, + { + name: "create domain with flags", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get.json")), + args: []string{ + "--name", "example.com", + "--email", "admin@example.com", + "--ttl", "3600", + "--label", "foo=bar", + }, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + CreateDomain(gomock.Any(), serverscom.DNSDomainCreateInput{ + Name: "example.com", + Email: "admin@example.com", + TTL: 3600, + Labels: map[string]string{"foo": "bar"}, + }). + Return(&testDomain, nil) + }, + }, + { + name: "skeleton for domain input", + output: "json", + args: []string{"--skeleton"}, + expectedOutput: testutils.ReadFixture(filepath.Join(skeletonTemplatePath, "add.json")), + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT().CreateDomain(gomock.Any(), gomock.Any()).Times(0) + }, + }, + { + name: "create domain with error", + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(dnsServiceHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "add"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(MatchJSON(tc.expectedOutput)) + } + }) + } +} + +func TestGetDNSDomainCmd(t *testing.T) { + testCases := []struct { + name string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "get domain in default format", + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get.txt")), + }, + { + name: "get domain in JSON format", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get.json")), + }, + { + name: "get domain in YAML format", + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get.yaml")), + }, + { + name: "get domain with error", + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + dnsServiceHandler.EXPECT(). + GetDomain(gomock.Any(), testDomainID). + Return(&testDomain, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "get", testDomainID} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestListDNSDomainsCmd(t *testing.T) { + domain1 := testDomain + domain2 := testDomain + domain2.ID = "def456" + domain2.Name = "example2.com" + + testCases := []struct { + name string + output string + args []string + expectedOutput []byte + expectError bool + configureMock func(*mocks.MockCollection[serverscom.DNSDomain]) + }{ + { + name: "list all domains", + output: "json", + args: []string{"-A"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_all.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSDomain]) { + mock.EXPECT(). + Collect(gomock.Any()). + Return([]serverscom.DNSDomain{domain1, domain2}, nil) + }, + }, + { + name: "list domains", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSDomain]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.DNSDomain{domain1}, nil) + }, + }, + { + name: "list domains with template", + args: []string{"--template", "{{range .}}Name: {{.Name}}\n{{end}}"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_template.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSDomain]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.DNSDomain{domain1, domain2}, nil) + }, + }, + { + name: "list domains with pageView", + args: []string{"--page-view"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_pageview.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSDomain]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.DNSDomain{domain1, domain2}, nil) + }, + }, + { + name: "list domains with error", + expectError: true, + configureMock: func(mock *mocks.MockCollection[serverscom.DNSDomain]) { + mock.EXPECT(). + List(gomock.Any()). + Return(nil, errors.New("some error")) + }, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + collectionHandler := mocks.NewMockCollection[serverscom.DNSDomain](mockCtrl) + + dnsServiceHandler.EXPECT(). + Collection(). + Return(collectionHandler). + AnyTimes() + + collectionHandler.EXPECT(). + SetParam(gomock.Any(), gomock.Any()). + Return(collectionHandler). + AnyTimes() + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(collectionHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "list"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestUpdateDNSDomainCmd(t *testing.T) { + newDomain := testDomain + newDomain.Labels = map[string]string{"new": "label"} + + testCases := []struct { + name string + output string + args []string + configureMock func(*mocks.MockDNSService) + expectedOutput []byte + expectError bool + }{ + { + name: "update domain", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "update.json")), + args: []string{"--label", "new=label"}, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + UpdateDomain(gomock.Any(), testDomainID, serverscom.DNSDomainUpdateInput{ + Labels: map[string]string{"new": "label"}, + }). + Return(&newDomain, nil) + }, + }, + { + name: "update domain with error", + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + UpdateDomain(gomock.Any(), testDomainID, serverscom.DNSDomainUpdateInput{ + Labels: make(map[string]string), + }). + Return(nil, errors.New("some error")) + }, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(dnsServiceHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "update", testDomainID} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestDeleteDNSDomainCmd(t *testing.T) { + testCases := []struct { + name string + expectError bool + }{ + {name: "delete domain"}, + {name: "delete domain with error", expectError: true}, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + dnsServiceHandler.EXPECT(). + DeleteDomain(gomock.Any(), testDomainID). + Return(err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "delete", testDomainID} + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + } + }) + } +} + +func TestDelegationDataCmd(t *testing.T) { + testCases := []struct { + name string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "delegation data in default format", + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "delegation_data.txt")), + }, + { + name: "delegation data in JSON format", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "delegation_data.json")), + }, + { + name: "delegation data in YAML format", + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "delegation_data.yaml")), + }, + { + name: "delegation data with error", + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + dnsServiceHandler.EXPECT(). + GetDelegationData(gomock.Any()). + Return(&testDelegation, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "delegation-data"} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestListDNSRecordsCmd(t *testing.T) { + record1 := testRecord + record2 := testRecord + record2.ID = "rec2" + record2.Name = "mail" + record2.Type = serverscom.DNSRecordTypeMX + record2.Data = new("mail.example.com") + record2.Priority = new(10) + + testCases := []struct { + name string + output string + args []string + expectedOutput []byte + expectError bool + configureMock func(*mocks.MockCollection[serverscom.DNSRecord]) + }{ + { + name: "list all records", + output: "json", + args: []string{testDomainID, "-A"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_records_all.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSRecord]) { + mock.EXPECT(). + Collect(gomock.Any()). + Return([]serverscom.DNSRecord{record1, record2}, nil) + }, + }, + { + name: "list records", + output: "json", + args: []string{testDomainID}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_records.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSRecord]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.DNSRecord{record1}, nil) + }, + }, + { + name: "list records with template", + args: []string{testDomainID, "--template", "{{range .}}Name: {{.Name}}\n{{end}}"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_records_template.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSRecord]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.DNSRecord{record1, record2}, nil) + }, + }, + { + name: "list records with pageView", + args: []string{testDomainID, "--page-view"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_records_pageview.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.DNSRecord]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.DNSRecord{record1, record2}, nil) + }, + }, + { + name: "list records with error", + args: []string{testDomainID}, + expectError: true, + configureMock: func(mock *mocks.MockCollection[serverscom.DNSRecord]) { + mock.EXPECT(). + List(gomock.Any()). + Return(nil, errors.New("some error")) + }, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + collectionHandler := mocks.NewMockCollection[serverscom.DNSRecord](mockCtrl) + + dnsServiceHandler.EXPECT(). + Records(testDomainID). + Return(collectionHandler). + AnyTimes() + + collectionHandler.EXPECT(). + SetParam(gomock.Any(), gomock.Any()). + Return(collectionHandler). + AnyTimes() + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(collectionHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "list-records"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestGetDNSRecordCmd(t *testing.T) { + testCases := []struct { + name string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "get record in default format", + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_record.txt")), + }, + { + name: "get record in JSON format", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_record.json")), + }, + { + name: "get record in YAML format", + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_record.yaml")), + }, + { + name: "get record with error", + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + dnsServiceHandler.EXPECT(). + GetRecord(gomock.Any(), testDomainID, testRecordID). + Return(&testRecord, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "get-record", testDomainID, "--record-id", testRecordID} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestAddDNSRecordCmd(t *testing.T) { + testCases := []struct { + name string + output string + args []string + configureMock func(*mocks.MockDNSService) + expectedOutput []byte + expectError bool + }{ + { + name: "create record with input", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_record.json")), + args: []string{testDomainID, "--input", filepath.Join(fixtureBasePath, "create_record.json")}, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + CreateRecord(gomock.Any(), testDomainID, serverscom.DNSRecordCreateInput{ + Type: serverscom.DNSRecordTypeA, + Name: "www", + Data: "1.2.3.4", + TTL: new(3600), + }). + Return(&testRecord, nil) + }, + }, + { + name: "create record with flags", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_record.json")), + args: []string{ + testDomainID, + "--type", "A", + "--name", "www", + "--data", "1.2.3.4", + "--ttl", "3600", + }, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + CreateRecord(gomock.Any(), testDomainID, serverscom.DNSRecordCreateInput{ + Type: serverscom.DNSRecordTypeA, + Name: "www", + Data: "1.2.3.4", + TTL: new(3600), + }). + Return(&testRecord, nil) + }, + }, + { + name: "skeleton for record input", + output: "json", + args: []string{"--skeleton"}, + expectedOutput: testutils.ReadFixture(filepath.Join(skeletonTemplatePath, "add-record.json")), + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT().CreateRecord(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) + }, + }, + { + name: "create record with error", + args: []string{testDomainID}, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(dnsServiceHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "add-record"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(MatchJSON(tc.expectedOutput)) + } + }) + } +} + +func TestUpdateDNSRecordCmd(t *testing.T) { + updatedRecord := testRecord + updatedRecord.Data = new("5.6.7.8") + updatedRecord.TTL = new(7200) + + testCases := []struct { + name string + output string + args []string + configureMock func(*mocks.MockDNSService) + expectedOutput []byte + expectError bool + }{ + { + name: "update record", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "update_record.json")), + args: []string{testDomainID, "--record-id", testRecordID, "--data", "5.6.7.8", "--ttl", "7200"}, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + UpdateRecord(gomock.Any(), testDomainID, testRecordID, serverscom.DNSRecordUpdateInput{ + Data: "5.6.7.8", + TTL: new(7200), + }). + Return(&updatedRecord, nil) + }, + }, + { + name: "update record with error", + args: []string{testDomainID, "--record-id", testRecordID}, + configureMock: func(mock *mocks.MockDNSService) { + mock.EXPECT(). + UpdateRecord(gomock.Any(), testDomainID, testRecordID, serverscom.DNSRecordUpdateInput{}). + Return(nil, errors.New("some error")) + }, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(dnsServiceHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "update-record"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestDeleteDNSRecordCmd(t *testing.T) { + testCases := []struct { + name string + expectError bool + }{ + {name: "delete record"}, + {name: "delete record with error", expectError: true}, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + dnsServiceHandler := mocks.NewMockDNSService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.DNS = dnsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + dnsServiceHandler.EXPECT(). + DeleteRecord(gomock.Any(), testDomainID, testRecordID). + Return(err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + dnsCmd := NewCmd(testCmdContext) + + args := []string{"dns", "delete-record", testDomainID, "--record-id", testRecordID} + + builder := testutils.NewTestCommandBuilder(). + WithCommand(dnsCmd). + WithArgs(args) + + cmd := builder.Build() + + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + } + }) + } +} diff --git a/cmd/entities/dns/get.go b/cmd/entities/dns/get.go new file mode 100644 index 0000000..0cd8124 --- /dev/null +++ b/cmd/entities/dns/get.go @@ -0,0 +1,39 @@ +package dns + +import ( + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newGetCmd(cmdContext *base.CmdContext) *cobra.Command { + cmd := &cobra.Command{ + Use: "get ", + Short: "Get a DNS domain", + Long: "Get a DNS domain by id", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + domain, err := scClient.DNS.GetDomain(ctx, domainID) + if err != nil { + return err + } + + if domain != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(domain) + } + return nil + }, + } + + return cmd +} diff --git a/cmd/entities/dns/get_record.go b/cmd/entities/dns/get_record.go new file mode 100644 index 0000000..51b64de --- /dev/null +++ b/cmd/entities/dns/get_record.go @@ -0,0 +1,47 @@ +package dns + +import ( + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newGetRecordCmd(cmdContext *base.CmdContext) *cobra.Command { + var recordID string + + cmd := &cobra.Command{ + Use: "get-record --record-id ", + Short: "Get a DNS record", + Long: "Get a DNS record by id within a domain", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if err := base.ValidateFlags(cmd, []string{"record-id"}); err != nil { + return err + } + + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + record, err := scClient.DNS.GetRecord(ctx, domainID, recordID) + if err != nil { + return err + } + + if record != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(record) + } + return nil + }, + } + + cmd.Flags().StringVarP(&recordID, "record-id", "", "", "A DNS record id") + + return cmd +} diff --git a/cmd/entities/dns/list.go b/cmd/entities/dns/list.go new file mode 100644 index 0000000..64d57fc --- /dev/null +++ b/cmd/entities/dns/list.go @@ -0,0 +1,41 @@ +package dns + +import ( + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newListCmd(cmdContext *base.CmdContext) *cobra.Command { + factory := func(verbose bool, args ...string) serverscom.Collection[serverscom.DNSDomain] { + scClient := cmdContext.GetClient().SetVerbose(verbose).GetScClient() + return scClient.DNS.Collection() + } + + opts := base.NewListOptions( + &base.BaseListOptions[serverscom.DNSDomain]{}, + &base.SearchPatternOption[serverscom.DNSDomain]{}, + &base.DelegationStatusOption[serverscom.DNSDomain]{}, + &base.LabelSelectorOption[serverscom.DNSDomain]{}, + ) + + return base.NewListCmd("list", "DNS domains", factory, cmdContext, opts...) +} + +func newListRecordsCmd(cmdContext *base.CmdContext) *cobra.Command { + factory := func(verbose bool, args ...string) serverscom.Collection[serverscom.DNSRecord] { + scClient := cmdContext.GetClient().SetVerbose(verbose).GetScClient() + return scClient.DNS.Records(args[0]) + } + + opts := base.NewListOptions( + &base.BaseListOptions[serverscom.DNSRecord]{}, + &base.DNSRecordTypeOption[serverscom.DNSRecord]{}, + ) + + cmd := base.NewListCmd("list-records", "DNS records", factory, cmdContext, opts...) + cmd.Use = "list-records " + cmd.Args = cobra.ExactArgs(1) + + return cmd +} diff --git a/cmd/entities/dns/update.go b/cmd/entities/dns/update.go new file mode 100644 index 0000000..d7d979d --- /dev/null +++ b/cmd/entities/dns/update.go @@ -0,0 +1,54 @@ +package dns + +import ( + "log" + + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newUpdateCmd(cmdContext *base.CmdContext) *cobra.Command { + var labels []string + + cmd := &cobra.Command{ + Use: "update ", + Short: "Update a DNS domain", + Long: "Update a DNS domain by id (labels only)", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + labelsMap, err := base.ParseLabels(labels) + if err != nil { + log.Fatal(err) + } + input := serverscom.DNSDomainUpdateInput{ + Labels: labelsMap, + } + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + domain, err := scClient.DNS.UpdateDomain(ctx, domainID, input) + if err != nil { + return err + } + + if domain != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(domain) + } + return nil + }, + } + + cmd.Flags().StringArrayVarP(&labels, "label", "l", []string{}, "string in key=value format") + + return cmd +} diff --git a/cmd/entities/dns/update_record.go b/cmd/entities/dns/update_record.go new file mode 100644 index 0000000..490b5d9 --- /dev/null +++ b/cmd/entities/dns/update_record.go @@ -0,0 +1,78 @@ +package dns + +import ( + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +type UpdateRecordFlags struct { + RecordID string + Name string + Data string + TTL int + Priority int +} + +func newUpdateRecordCmd(cmdContext *base.CmdContext) *cobra.Command { + flags := &UpdateRecordFlags{} + + cmd := &cobra.Command{ + Use: "update-record --record-id ", + Short: "Update a DNS record", + Long: "Update a DNS record by id within a domain. Record type cannot be changed; SOA/PTR records are not editable", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if err := base.ValidateFlags(cmd, []string{"record-id"}); err != nil { + return err + } + + manager := cmdContext.GetManager() + + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + + input := serverscom.DNSRecordUpdateInput{} + flags.FillInput(cmd, &input) + + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + domainID := args[0] + record, err := scClient.DNS.UpdateRecord(ctx, domainID, flags.RecordID, input) + if err != nil { + return err + } + + if record != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(record) + } + return nil + }, + } + + cmd.Flags().StringVarP(&flags.RecordID, "record-id", "", "", "A DNS record id") + cmd.Flags().StringVarP(&flags.Name, "name", "n", "", "A name of a DNS record") + cmd.Flags().StringVarP(&flags.Data, "data", "", "", "A data of a DNS record") + cmd.Flags().IntVarP(&flags.TTL, "ttl", "", 0, "A TTL of a DNS record in seconds") + cmd.Flags().IntVarP(&flags.Priority, "priority", "", 0, "A priority of a DNS record (required by convention for MX/SRV, ignored for other types)") + + return cmd +} + +func (f *UpdateRecordFlags) FillInput(cmd *cobra.Command, input *serverscom.DNSRecordUpdateInput) { + if cmd.Flags().Changed("name") { + input.Name = f.Name + } + if cmd.Flags().Changed("data") { + input.Data = f.Data + } + if cmd.Flags().Changed("ttl") { + input.TTL = &f.TTL + } + if cmd.Flags().Changed("priority") { + input.Priority = &f.Priority + } +} diff --git a/cmd/entities/hosts/hosts.go b/cmd/entities/hosts/hosts.go index 7b0cf0a..3c0963a 100644 --- a/cmd/entities/hosts/hosts.go +++ b/cmd/entities/hosts/hosts.go @@ -56,6 +56,8 @@ func NewCmd(cmdContext *base.CmdContext) *cobra.Command { newGetEBMNetworkCmd, newAddEBMNetworkCmd, newDeleteEBMNetworkCmd, + newActivateEBMIPv6NetworkCmd, + newGetEBMNetworkUsageCmd, newListEBMCmd, newListEBMServicesCmd, newListEBMFeaturesCmd, @@ -94,6 +96,11 @@ func NewCmd(cmdContext *base.CmdContext) *cobra.Command { newUpdateSBMCmd, newSBMReleaseCmd, newListSBMCmd, + newListSBMNetworksCmd, + newGetSBMNetworkCmd, + newAddSBMNetworkCmd, + newDeleteSBMNetworkCmd, + newGetSBMNetworkUsageCmd, newListSBMPTRCmd, newCreateSBMPTRCmd, newDeleteSBMPTRCmd, diff --git a/cmd/entities/hosts/hosts_test.go b/cmd/entities/hosts/hosts_test.go index 1df8c34..5c772db 100644 --- a/cmd/entities/hosts/hosts_test.go +++ b/cmd/entities/hosts/hosts_test.go @@ -85,6 +85,8 @@ var ( } netTitle = "Some Net" cidr = "100.0.8.0/29" + netFirstIP = "100.0.8.2" + netGateway = "100.0.8.1" testNetwork = serverscom.Network{ ID: testNetworkId, Title: &netTitle, @@ -94,9 +96,19 @@ var ( InterfaceType: "public", DistributionMethod: "gateway", Additional: false, + FirstIP: &netFirstIP, + Gateway: &netGateway, Created: fixedTime, Updated: fixedTime, } + testNetworkUsage = serverscom.NetworkUsage{ + Type: "public", + Utilization: &serverscom.Utilization{ + Value: 100, + Commit: 50, + Unit: "GB", + }, + } testDriveModel = serverscom.DriveModel{ ID: int64(10), Name: "ssd-model-749", @@ -2492,6 +2504,623 @@ func TestListKBMNetworksCmd(t *testing.T) { } } +func TestGetSBMNetworkCmd(t *testing.T) { + testCases := []struct { + name string + id string + networkID string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "get SBM network in default format", + id: testId, + networkID: testNetworkId, + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network.txt")), + }, + { + name: "get SBM network in JSON format", + id: testId, + networkID: testNetworkId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network.json")), + }, + { + name: "get SBM network in YAML format", + id: testId, + networkID: testNetworkId, + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network.yaml")), + }, + { + name: "get SBM network with error", + id: testId, + networkID: testNetworkId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + GetSBMServerNetwork(gomock.Any(), tc.id, tc.networkID). + Return(&testNetwork, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{ + "hosts", "sbm", "get-network", tc.id, + "--network-id", tc.networkID, + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestListSBMNetworksCmd(t *testing.T) { + testNetwork1 := testNetwork + testNetwork1.ID = testNetworkId + testNetwork2 := testNetwork1 + testNetwork2.ID = "testNetId2" + netTitle2 := "Another Net" + testNetwork2.Title = &netTitle2 + + testCases := []struct { + name string + output string + args []string + expectedOutput []byte + expectError bool + configureMock func(*mocks.MockCollection[serverscom.Network]) + }{ + { + name: "list all SBM networks", + output: "json", + args: []string{"testServerId", "-A"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_sbm_networks_all.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + Collect(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + testNetwork2, + }, nil) + }, + }, + { + name: "list SBM networks", + output: "json", + args: []string{"testServerId"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_sbm_networks.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + }, nil) + }, + }, + { + name: "list SBM networks with template", + args: []string{"testServerId", "--template", "{{range .}}Network: {{.ID}} Title: {{.Title}}\n{{end}}"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_sbm_networks_template.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + testNetwork2, + }, nil) + }, + }, + { + name: "list SBM networks with pageView", + args: []string{"testServerId", "--page-view"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_sbm_networks_pageview.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + testNetwork2, + }, nil) + }, + }, + { + name: "list SBM networks with error", + args: []string{"testServerId"}, + expectError: true, + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return(nil, errors.New("some error")) + }, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + collectionHandler := mocks.NewMockCollection[serverscom.Network](mockCtrl) + + hostsServiceHandler.EXPECT(). + SBMServerNetworks(gomock.Any()). + Return(collectionHandler). + AnyTimes() + + collectionHandler.EXPECT(). + SetParam(gomock.Any(), gomock.Any()). + Return(collectionHandler). + AnyTimes() + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(collectionHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "sbm", "list-networks"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestAddSBMNetworkCmd(t *testing.T) { + expectedInputPrivate := serverscom.NetworkInput{ + DistributionMethod: "gateway", + Mask: 29, + } + + testCases := []struct { + name string + output string + args []string + configureMock func(*mocks.MockHostsService) + expectedOutput []byte + expectError bool + }{ + { + name: "add private SBM network", + output: "json", + args: []string{ + testId, + "--type", "private", + "--mask", "29", + "--distribution-method", "gateway", + }, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network.json")), + configureMock: func(mock *mocks.MockHostsService) { + mock.EXPECT(). + AddSBMServerPrivateIPv4Network(gomock.Any(), testId, expectedInputPrivate). + Return(&testNetwork, nil) + }, + }, + { + name: "add public SBM network is not supported", + args: []string{ + testId, + "--type", "public", + "--mask", "29", + }, + expectError: true, + }, + { + name: "add SBM network with unsupported mask", + args: []string{ + testId, + "--type", "private", + "--mask", "24", + }, + expectError: true, + }, + { + name: "add SBM network with error", + output: "json", + args: []string{ + testId, + "--type", "private", + "--mask", "29", + }, + expectError: true, + configureMock: func(mock *mocks.MockHostsService) { + mock.EXPECT(). + AddSBMServerPrivateIPv4Network(gomock.Any(), testId, expectedInputPrivate). + Return(nil, errors.New("some error")) + }, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(hostsServiceHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := append([]string{"hosts", "sbm", "add-network"}, tc.args...) + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestDeleteSBMNetworkCmd(t *testing.T) { + testCases := []struct { + name string + id string + networkID string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "delete SBM network", + id: testId, + networkID: testNetworkId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network.json")), + }, + { + name: "delete SBM network with error", + id: testId, + networkID: testNetworkId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + DeleteSBMServerNetwork(gomock.Any(), tc.id, tc.networkID). + Return(&testNetwork, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "sbm", "delete-network", tc.id, "--network-id", tc.networkID} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestActivateEBMIPv6NetworkCmd(t *testing.T) { + testCases := []struct { + name string + id string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "activate DS IPv6 network", + id: testId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ebm_network.json")), + }, + { + name: "activate DS IPv6 network with error", + id: testId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + ActivateDedicatedServerPubliIPv6Network(gomock.Any(), tc.id). + Return(&testNetwork, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "ebm", "activate-ipv6-network", tc.id} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestGetEBMNetworkUsageCmd(t *testing.T) { + testCases := []struct { + name string + id string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "get DS network usage in default format", + id: testId, + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ebm_network_usage.txt")), + }, + { + name: "get DS network usage in JSON format", + id: testId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ebm_network_usage.json")), + }, + { + name: "get DS network usage in YAML format", + id: testId, + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ebm_network_usage.yaml")), + }, + { + name: "get DS network usage with error", + id: testId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + GetDedicatedServerNetworkUsage(gomock.Any(), tc.id). + Return(&testNetworkUsage, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "ebm", "network-usage", tc.id} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestGetSBMNetworkUsageCmd(t *testing.T) { + testCases := []struct { + name string + id string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "get SBM network usage in default format", + id: testId, + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network_usage.txt")), + }, + { + name: "get SBM network usage in JSON format", + id: testId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network_usage.json")), + }, + { + name: "get SBM network usage in YAML format", + id: testId, + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_sbm_network_usage.yaml")), + }, + { + name: "get SBM network usage with error", + id: testId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + GetSBMServerNetworkUsage(gomock.Any(), tc.id). + Return(&testNetworkUsage, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "sbm", "network-usage", tc.id} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + func TestListEBMDriveSlotsCmd(t *testing.T) { testDriveSlot1 := testDriveSlot testDriveSlot2 := testDriveSlot1 diff --git a/cmd/entities/hosts/networks.go b/cmd/entities/hosts/networks.go index 0d36cd8..3e57a29 100644 --- a/cmd/entities/hosts/networks.go +++ b/cmd/entities/hosts/networks.go @@ -1,6 +1,8 @@ package hosts import ( + "fmt" + serverscom "github.com/serverscom/serverscom-go-client/pkg" "github.com/serverscom/srvctl/cmd/base" "github.com/spf13/cobra" @@ -176,3 +178,242 @@ func newListKBMNetworksCmd(cmdContext *base.CmdContext) *cobra.Command { return cmd } + +func newListSBMNetworksCmd(cmdContext *base.CmdContext) *cobra.Command { + factory := func(verbose bool, args ...string) serverscom.Collection[serverscom.Network] { + scClient := cmdContext.GetClient().SetVerbose(verbose).GetScClient() + return scClient.Hosts.SBMServerNetworks(args[0]) + } + + opts := base.NewListOptions( + &base.BaseListOptions[serverscom.Network]{}, + &base.SearchPatternOption[serverscom.Network]{}, + &base.FamilyOption[serverscom.Network]{}, + &base.InterfaceTypeOption[serverscom.Network]{}, + &base.DistributionMethodOption[serverscom.Network]{}, + &base.AdditionalOption[serverscom.Network]{}, + ) + + cmd := base.NewListCmd("list-networks", "Scalable baremetal server networks", factory, cmdContext, opts...) + cmd.Use = "list-networks " + cmd.Args = cobra.ExactArgs(1) + + return cmd +} + +func newGetSBMNetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + var networkID string + + cmd := &cobra.Command{ + Use: "get-network ", + Short: ("Get a scalable baremetal server network"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.GetSBMServerNetwork(ctx, id, networkID) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + cmd.Flags().StringVar(&networkID, "network-id", "", "Network id (required)") + _ = cmd.MarkFlagRequired("network-id") + + return cmd +} + +func newAddSBMNetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + var ( + networkType string + mask int + distributionMethod string + ) + + cmd := &cobra.Command{ + Use: "add-network ", + Short: "Add private/public IPv4 network to scalable baremetal server", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + id := args[0] + + if err := validateNetworkArgs(networkType, distributionMethod, mask); err != nil { + return err + } + + input := serverscom.NetworkInput{ + DistributionMethod: distributionMethod, + Mask: mask, + } + + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + var entity *serverscom.Network + var err error + switch networkType { + case "public": + return fmt.Errorf("public networks currently are not supported for scalable baremetal servers") + case "private": + entity, err = scClient.Hosts.AddSBMServerPrivateIPv4Network(ctx, id, input) + } + if err != nil { + return err + } + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + cmd.Flags().StringVar(&networkType, "type", "", "Network type: 'private'") + cmd.Flags().IntVar(&mask, "mask", 0, "Network mask (required)") + cmd.Flags().StringVar(&distributionMethod, "distribution-method", "gateway", "Distribution method ('gateway')") + _ = cmd.MarkFlagRequired("type") + _ = cmd.MarkFlagRequired("mask") + + return cmd +} + +func newDeleteSBMNetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + var networkID string + + cmd := &cobra.Command{ + Use: "delete-network ", + Short: ("Delete a scalable baremetal server network"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.DeleteSBMServerNetwork(ctx, id, networkID) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + cmd.Flags().StringVar(&networkID, "network-id", "", "Network id (required)") + _ = cmd.MarkFlagRequired("network-id") + + return cmd +} + +func newActivateEBMIPv6NetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + cmd := &cobra.Command{ + Use: "activate-ipv6-network ", + Short: ("Activate a public IPv6 network for an enterprise bare metal server"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.ActivateDedicatedServerPubliIPv6Network(ctx, id) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + return cmd +} + +func newGetEBMNetworkUsageCmd(cmdContext *base.CmdContext) *cobra.Command { + cmd := &cobra.Command{ + Use: "network-usage ", + Short: ("Get network utilization for an enterprise bare metal server"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.GetDedicatedServerNetworkUsage(ctx, id) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + return cmd +} + +func newGetSBMNetworkUsageCmd(cmdContext *base.CmdContext) *cobra.Command { + cmd := &cobra.Command{ + Use: "network-usage ", + Short: ("Get network utilization for a scalable baremetal server"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.GetSBMServerNetworkUsage(ctx, id) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + return cmd +} diff --git a/cmd/entities/l2_segments/l2_segments.go b/cmd/entities/l2_segments/l2_segments.go index af081b7..f2b9065 100644 --- a/cmd/entities/l2_segments/l2_segments.go +++ b/cmd/entities/l2_segments/l2_segments.go @@ -14,8 +14,13 @@ func NewCmd(cmdContext *base.CmdContext) *cobra.Command { if err != nil { log.Fatal(err) } + l2NetworkEntity, err := entities.Registry.GetEntityFromValue(serverscom.L2SegmentNetwork{}) + if err != nil { + log.Fatal(err) + } entitiesMap := make(map[string]entities.EntityInterface) entitiesMap["l2-segments"] = l2Entity + entitiesMap["list-networks"] = l2NetworkEntity cmd := &cobra.Command{ Use: "l2-segments", Short: "Manage L2 segments", diff --git a/cmd/entities/l2_segments/l2_segments_test.go b/cmd/entities/l2_segments/l2_segments_test.go index da549be..160b897 100644 --- a/cmd/entities/l2_segments/l2_segments_test.go +++ b/cmd/entities/l2_segments/l2_segments_test.go @@ -59,7 +59,7 @@ var ( cidr = "127.1.182.0/24" title = "testNetwork" - testNetwork = serverscom.Network{ + testNetwork = serverscom.L2SegmentNetwork{ ID: testID, Title: &title, Status: "new", @@ -882,17 +882,17 @@ func TestListL2NetworksCmd(t *testing.T) { args []string expectedOutput []byte expectError bool - configureMock func(*mocks.MockCollection[serverscom.Network]) + configureMock func(*mocks.MockCollection[serverscom.L2SegmentNetwork]) }{ { name: "list all l2 networks", output: "json", args: []string{testID, "-A"}, expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_networks_all.json")), - configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + configureMock: func(mock *mocks.MockCollection[serverscom.L2SegmentNetwork]) { mock.EXPECT(). Collect(gomock.Any()). - Return([]serverscom.Network{n1, n2}, nil) + Return([]serverscom.L2SegmentNetwork{n1, n2}, nil) }, }, { @@ -900,37 +900,37 @@ func TestListL2NetworksCmd(t *testing.T) { output: "json", args: []string{testID}, expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_networks.json")), - configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + configureMock: func(mock *mocks.MockCollection[serverscom.L2SegmentNetwork]) { mock.EXPECT(). List(gomock.Any()). - Return([]serverscom.Network{n1}, nil) + Return([]serverscom.L2SegmentNetwork{n1}, nil) }, }, { name: "list l2 networks with template", args: []string{testID, "--template", "{{range .}}ID: {{.ID}} Title: {{.Title}}\n{{end}}"}, expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_networks_template.txt")), - configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + configureMock: func(mock *mocks.MockCollection[serverscom.L2SegmentNetwork]) { mock.EXPECT(). List(gomock.Any()). - Return([]serverscom.Network{n1, n2}, nil) + Return([]serverscom.L2SegmentNetwork{n1, n2}, nil) }, }, { name: "list l2 networks with pageView", args: []string{testID, "--page-view"}, expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_networks_pageview.txt")), - configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + configureMock: func(mock *mocks.MockCollection[serverscom.L2SegmentNetwork]) { mock.EXPECT(). List(gomock.Any()). - Return([]serverscom.Network{n1, n2}, nil) + Return([]serverscom.L2SegmentNetwork{n1, n2}, nil) }, }, { name: "list l2 networks error", args: []string{testID}, expectError: true, - configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + configureMock: func(mock *mocks.MockCollection[serverscom.L2SegmentNetwork]) { mock.EXPECT(). List(gomock.Any()). Return(nil, errors.New("some error")) @@ -941,7 +941,7 @@ func TestListL2NetworksCmd(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - collectionHandler := mocks.NewMockCollection[serverscom.Network](mockCtrl) + collectionHandler := mocks.NewMockCollection[serverscom.L2SegmentNetwork](mockCtrl) l2ServiceHandler := mocks.NewMockL2SegmentsService(mockCtrl) l2ServiceHandler.EXPECT(). Networks(testID). diff --git a/cmd/entities/l2_segments/list.go b/cmd/entities/l2_segments/list.go index 50f4459..5cca14e 100644 --- a/cmd/entities/l2_segments/list.go +++ b/cmd/entities/l2_segments/list.go @@ -54,14 +54,14 @@ func newListMembersCmd(cmdContext *base.CmdContext) *cobra.Command { func newListNetworksCmd(cmdContext *base.CmdContext) *cobra.Command { - factory := func(verbose bool, args ...string) serverscom.Collection[serverscom.Network] { + factory := func(verbose bool, args ...string) serverscom.Collection[serverscom.L2SegmentNetwork] { scClient := cmdContext.GetClient().SetVerbose(verbose).GetScClient() return scClient.L2Segments.Networks(args[0]) } opts := base.NewListOptions( - &base.BaseListOptions[serverscom.Network]{}, - &base.L2SegmentGroupTypeOption[serverscom.Network]{}, + &base.BaseListOptions[serverscom.L2SegmentNetwork]{}, + &base.L2SegmentGroupTypeOption[serverscom.L2SegmentNetwork]{}, ) cmd := base.NewListCmd("list-networks", "l2 segment networks", factory, cmdContext, opts...) diff --git a/cmd/entities/load_balancer_clusters/load_balancer_clusters_test.go b/cmd/entities/load_balancer_clusters/load_balancer_clusters_test.go index 60cccf2..02cb089 100644 --- a/cmd/entities/load_balancer_clusters/load_balancer_clusters_test.go +++ b/cmd/entities/load_balancer_clusters/load_balancer_clusters_test.go @@ -24,7 +24,6 @@ var ( Name: "test-lb-cluster", LocationID: 1, LocationCode: testLocationCode, - Status: "active", Created: fixedTime, Updated: fixedTime, } diff --git a/cmd/root.go b/cmd/root.go index 239e1de..709067c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,6 +9,7 @@ import ( cloudinstances "github.com/serverscom/srvctl/cmd/entities/cloud-instances" cloudregions "github.com/serverscom/srvctl/cmd/entities/cloud-regions" cloudvolumes "github.com/serverscom/srvctl/cmd/entities/cloud-volumes" + "github.com/serverscom/srvctl/cmd/entities/dns" "github.com/serverscom/srvctl/cmd/entities/drivemodels" "github.com/serverscom/srvctl/cmd/entities/hosts" "github.com/serverscom/srvctl/cmd/entities/invoices" @@ -83,6 +84,7 @@ func NewRootCmd(version string) *cobra.Command { cmd.AddCommand(cloudvolumes.NewCmd(cmdContext)) cmd.AddCommand(cloudbackups.NewCmd(cmdContext)) cmd.AddCommand(rbsvolumes.NewCmd(cmdContext)) + cmd.AddCommand(dns.NewCmd(cmdContext)) return cmd } diff --git a/docs/srvctl-lb-l4-add/examples.md b/docs/srvctl-lb-l4-add/examples.md index 30e42f1..0ca4b53 100644 --- a/docs/srvctl-lb-l4-add/examples.md +++ b/docs/srvctl-lb-l4-add/examples.md @@ -18,7 +18,7 @@ JSON structure example: "location_id": "", "cluster_id": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "vhost_zones": [ { "id": "", diff --git a/docs/srvctl-lb-l4-update/examples.md b/docs/srvctl-lb-l4-update/examples.md index 5b3af31..c3a1400 100644 --- a/docs/srvctl-lb-l4-update/examples.md +++ b/docs/srvctl-lb-l4-update/examples.md @@ -18,7 +18,7 @@ JSON structure example: "shared_cluster": "", "name": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "new_external_ips_count": "", "delete_external_ips": [], "vhost_zones": [ diff --git a/docs/srvctl-lb-l7-add/examples.md b/docs/srvctl-lb-l7-add/examples.md index 33319ed..dfa2d6f 100644 --- a/docs/srvctl-lb-l7-add/examples.md +++ b/docs/srvctl-lb-l7-add/examples.md @@ -18,7 +18,7 @@ JSON structure example: "location_id": "", "cluster_id": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "geoip": "true", "vhost_zones": [ { diff --git a/docs/srvctl-lb-l7-update/examples.md b/docs/srvctl-lb-l7-update/examples.md index 69f36af..21d01d7 100644 --- a/docs/srvctl-lb-l7-update/examples.md +++ b/docs/srvctl-lb-l7-update/examples.md @@ -18,7 +18,7 @@ JSON structure example: "cluster_id": "", "shared_cluster": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "geoip": "true", "new_external_ips_count": "", "delete_external_ips": [], diff --git a/go.mod b/go.mod index e878ff5..9f6552b 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/creack/pty v1.1.24 github.com/jmespath/go-jmespath v0.4.0 github.com/onsi/gomega v1.42.1 - github.com/serverscom/serverscom-go-client v1.0.33 + github.com/serverscom/serverscom-go-client v1.1.2 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 github.com/spf13/viper v1.21.0 @@ -33,5 +33,5 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/net v0.57.0 // indirect golang.org/x/sys v0.47.0 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index f7105f8..978a146 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,11 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I= @@ -38,8 +41,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= -github.com/serverscom/serverscom-go-client v1.0.33 h1:JdpzoJnOjUEappDxxGSzhHC4At7RaZItrg7o7wVQZpg= -github.com/serverscom/serverscom-go-client v1.0.33/go.mod h1:/Nf+XygKOxm19Sl2gvMzT55O4X+tWDkj/UM4mjzfKgM= +github.com/serverscom/serverscom-go-client v1.1.2 h1:ddSKFrHRu38zdkk8OXg9Ugr5oTQX1ESfanTls8vb7vI= +github.com/serverscom/serverscom-go-client v1.1.2/go.mod h1:RVmx6+Dop/gvs7FETe6TrzdSEzQZGOzImyUTgUwsBoU= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= @@ -78,8 +81,8 @@ golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/mocks/cloud_instances_service.go b/internal/mocks/cloud_instances_service.go index 389eed7..3d1503d 100644 --- a/internal/mocks/cloud_instances_service.go +++ b/internal/mocks/cloud_instances_service.go @@ -86,7 +86,7 @@ func (mr *MockCloudComputingInstancesServiceMockRecorder) Create(ctx, input any) } // CreatePTRRecord mocks base method. -func (m *MockCloudComputingInstancesService) CreatePTRRecord(ctx context.Context, cloudInstanceID string, input serverscom.PTRRecordCreateInput) (*serverscom.PTRRecord, error) { +func (m *MockCloudComputingInstancesService) CreatePTRRecord(ctx context.Context, cloudInstanceID string, input serverscom.CloudComputingInstancePTRRecordCreateInput) (*serverscom.PTRRecord, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreatePTRRecord", ctx, cloudInstanceID, input) ret0, _ := ret[0].(*serverscom.PTRRecord) diff --git a/internal/mocks/dns_service.go b/internal/mocks/dns_service.go new file mode 100644 index 0000000..2f60b12 --- /dev/null +++ b/internal/mocks/dns_service.go @@ -0,0 +1,203 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./vendor/github.com/serverscom/serverscom-go-client/pkg/dns.go +// +// Generated by this command: +// +// mockgen --destination ./internal/mocks/dns_service.go --package=mocks --source ./vendor/github.com/serverscom/serverscom-go-client/pkg/dns.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + serverscom "github.com/serverscom/serverscom-go-client/pkg" + gomock "go.uber.org/mock/gomock" +) + +// MockDNSService is a mock of DNSService interface. +type MockDNSService struct { + ctrl *gomock.Controller + recorder *MockDNSServiceMockRecorder + isgomock struct{} +} + +// MockDNSServiceMockRecorder is the mock recorder for MockDNSService. +type MockDNSServiceMockRecorder struct { + mock *MockDNSService +} + +// NewMockDNSService creates a new mock instance. +func NewMockDNSService(ctrl *gomock.Controller) *MockDNSService { + mock := &MockDNSService{ctrl: ctrl} + mock.recorder = &MockDNSServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDNSService) EXPECT() *MockDNSServiceMockRecorder { + return m.recorder +} + +// Collection mocks base method. +func (m *MockDNSService) Collection() serverscom.Collection[serverscom.DNSDomain] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Collection") + ret0, _ := ret[0].(serverscom.Collection[serverscom.DNSDomain]) + return ret0 +} + +// Collection indicates an expected call of Collection. +func (mr *MockDNSServiceMockRecorder) Collection() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Collection", reflect.TypeOf((*MockDNSService)(nil).Collection)) +} + +// CreateDomain mocks base method. +func (m *MockDNSService) CreateDomain(ctx context.Context, input serverscom.DNSDomainCreateInput) (*serverscom.DNSDomain, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDomain", ctx, input) + ret0, _ := ret[0].(*serverscom.DNSDomain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDomain indicates an expected call of CreateDomain. +func (mr *MockDNSServiceMockRecorder) CreateDomain(ctx, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDomain", reflect.TypeOf((*MockDNSService)(nil).CreateDomain), ctx, input) +} + +// CreateRecord mocks base method. +func (m *MockDNSService) CreateRecord(ctx context.Context, domainID string, input serverscom.DNSRecordCreateInput) (*serverscom.DNSRecord, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateRecord", ctx, domainID, input) + ret0, _ := ret[0].(*serverscom.DNSRecord) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRecord indicates an expected call of CreateRecord. +func (mr *MockDNSServiceMockRecorder) CreateRecord(ctx, domainID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRecord", reflect.TypeOf((*MockDNSService)(nil).CreateRecord), ctx, domainID, input) +} + +// DeleteDomain mocks base method. +func (m *MockDNSService) DeleteDomain(ctx context.Context, id string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDomain", ctx, id) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDomain indicates an expected call of DeleteDomain. +func (mr *MockDNSServiceMockRecorder) DeleteDomain(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDomain", reflect.TypeOf((*MockDNSService)(nil).DeleteDomain), ctx, id) +} + +// DeleteRecord mocks base method. +func (m *MockDNSService) DeleteRecord(ctx context.Context, domainID, recordID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteRecord", ctx, domainID, recordID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteRecord indicates an expected call of DeleteRecord. +func (mr *MockDNSServiceMockRecorder) DeleteRecord(ctx, domainID, recordID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRecord", reflect.TypeOf((*MockDNSService)(nil).DeleteRecord), ctx, domainID, recordID) +} + +// GetDelegationData mocks base method. +func (m *MockDNSService) GetDelegationData(ctx context.Context) (*serverscom.DNSDomainDelegationData, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDelegationData", ctx) + ret0, _ := ret[0].(*serverscom.DNSDomainDelegationData) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDelegationData indicates an expected call of GetDelegationData. +func (mr *MockDNSServiceMockRecorder) GetDelegationData(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegationData", reflect.TypeOf((*MockDNSService)(nil).GetDelegationData), ctx) +} + +// GetDomain mocks base method. +func (m *MockDNSService) GetDomain(ctx context.Context, id string) (*serverscom.DNSDomain, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDomain", ctx, id) + ret0, _ := ret[0].(*serverscom.DNSDomain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDomain indicates an expected call of GetDomain. +func (mr *MockDNSServiceMockRecorder) GetDomain(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDomain", reflect.TypeOf((*MockDNSService)(nil).GetDomain), ctx, id) +} + +// GetRecord mocks base method. +func (m *MockDNSService) GetRecord(ctx context.Context, domainID, recordID string) (*serverscom.DNSRecord, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRecord", ctx, domainID, recordID) + ret0, _ := ret[0].(*serverscom.DNSRecord) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRecord indicates an expected call of GetRecord. +func (mr *MockDNSServiceMockRecorder) GetRecord(ctx, domainID, recordID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRecord", reflect.TypeOf((*MockDNSService)(nil).GetRecord), ctx, domainID, recordID) +} + +// Records mocks base method. +func (m *MockDNSService) Records(domainID string) serverscom.Collection[serverscom.DNSRecord] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Records", domainID) + ret0, _ := ret[0].(serverscom.Collection[serverscom.DNSRecord]) + return ret0 +} + +// Records indicates an expected call of Records. +func (mr *MockDNSServiceMockRecorder) Records(domainID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Records", reflect.TypeOf((*MockDNSService)(nil).Records), domainID) +} + +// UpdateDomain mocks base method. +func (m *MockDNSService) UpdateDomain(ctx context.Context, id string, input serverscom.DNSDomainUpdateInput) (*serverscom.DNSDomain, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDomain", ctx, id, input) + ret0, _ := ret[0].(*serverscom.DNSDomain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateDomain indicates an expected call of UpdateDomain. +func (mr *MockDNSServiceMockRecorder) UpdateDomain(ctx, id, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDomain", reflect.TypeOf((*MockDNSService)(nil).UpdateDomain), ctx, id, input) +} + +// UpdateRecord mocks base method. +func (m *MockDNSService) UpdateRecord(ctx context.Context, domainID, recordID string, input serverscom.DNSRecordUpdateInput) (*serverscom.DNSRecord, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateRecord", ctx, domainID, recordID, input) + ret0, _ := ret[0].(*serverscom.DNSRecord) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateRecord indicates an expected call of UpdateRecord. +func (mr *MockDNSServiceMockRecorder) UpdateRecord(ctx, domainID, recordID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRecord", reflect.TypeOf((*MockDNSService)(nil).UpdateRecord), ctx, domainID, recordID, input) +} diff --git a/internal/mocks/hosts_service.go b/internal/mocks/hosts_service.go index fb757e8..9b335bb 100644 --- a/internal/mocks/hosts_service.go +++ b/internal/mocks/hosts_service.go @@ -191,6 +191,21 @@ func (mr *MockHostsServiceMockRecorder) ActivatePrivateIpxeBootFeature(ctx, serv return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivatePrivateIpxeBootFeature", reflect.TypeOf((*MockHostsService)(nil).ActivatePrivateIpxeBootFeature), ctx, serverID, input) } +// ActivatePublicIpxeBootFeature mocks base method. +func (m *MockHostsService) ActivatePublicIpxeBootFeature(ctx context.Context, serverID string, input serverscom.PublicIpxeBootFeatureInput) (*serverscom.DedicatedServerFeature, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ActivatePublicIpxeBootFeature", ctx, serverID, input) + ret0, _ := ret[0].(*serverscom.DedicatedServerFeature) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ActivatePublicIpxeBootFeature indicates an expected call of ActivatePublicIpxeBootFeature. +func (mr *MockHostsServiceMockRecorder) ActivatePublicIpxeBootFeature(ctx, serverID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivatePublicIpxeBootFeature", reflect.TypeOf((*MockHostsService)(nil).ActivatePublicIpxeBootFeature), ctx, serverID, input) +} + // AddDedicatedServerPrivateIPv4Network mocks base method. func (m *MockHostsService) AddDedicatedServerPrivateIPv4Network(ctx context.Context, id string, input serverscom.NetworkInput) (*serverscom.Network, error) { m.ctrl.T.Helper() @@ -221,6 +236,21 @@ func (mr *MockHostsServiceMockRecorder) AddDedicatedServerPublicIPv4Network(ctx, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDedicatedServerPublicIPv4Network", reflect.TypeOf((*MockHostsService)(nil).AddDedicatedServerPublicIPv4Network), ctx, id, input) } +// AddSBMServerPrivateIPv4Network mocks base method. +func (m *MockHostsService) AddSBMServerPrivateIPv4Network(ctx context.Context, id string, input serverscom.NetworkInput) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddSBMServerPrivateIPv4Network", ctx, id, input) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddSBMServerPrivateIPv4Network indicates an expected call of AddSBMServerPrivateIPv4Network. +func (mr *MockHostsServiceMockRecorder) AddSBMServerPrivateIPv4Network(ctx, id, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSBMServerPrivateIPv4Network", reflect.TypeOf((*MockHostsService)(nil).AddSBMServerPrivateIPv4Network), ctx, id, input) +} + // AttachSSHKeysToDedicatedServer mocks base method. func (m *MockHostsService) AttachSSHKeysToDedicatedServer(ctx context.Context, id string, input serverscom.SSHKeyAttachInput) ([]serverscom.SSHKey, error) { m.ctrl.T.Helper() @@ -430,6 +460,21 @@ func (mr *MockHostsServiceMockRecorder) DeactivatePrivateIpxeBootFeature(ctx, se return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivatePrivateIpxeBootFeature", reflect.TypeOf((*MockHostsService)(nil).DeactivatePrivateIpxeBootFeature), ctx, serverID) } +// DeactivatePublicIpxeBootFeature mocks base method. +func (m *MockHostsService) DeactivatePublicIpxeBootFeature(ctx context.Context, serverID string) (*serverscom.DedicatedServerFeature, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeactivatePublicIpxeBootFeature", ctx, serverID) + ret0, _ := ret[0].(*serverscom.DedicatedServerFeature) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeactivatePublicIpxeBootFeature indicates an expected call of DeactivatePublicIpxeBootFeature. +func (mr *MockHostsServiceMockRecorder) DeactivatePublicIpxeBootFeature(ctx, serverID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivatePublicIpxeBootFeature", reflect.TypeOf((*MockHostsService)(nil).DeactivatePublicIpxeBootFeature), ctx, serverID) +} + // DedicatedServerConnections mocks base method. func (m *MockHostsService) DedicatedServerConnections(id string) serverscom.Collection[serverscom.HostConnection] { m.ctrl.T.Helper() @@ -572,6 +617,21 @@ func (mr *MockHostsServiceMockRecorder) DeletePTRRecordForSBMServer(ctx, serverI return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePTRRecordForSBMServer", reflect.TypeOf((*MockHostsService)(nil).DeletePTRRecordForSBMServer), ctx, serverID, ptrRecordID) } +// DeleteSBMServerNetwork mocks base method. +func (m *MockHostsService) DeleteSBMServerNetwork(ctx context.Context, serverID, networkID string) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteSBMServerNetwork", ctx, serverID, networkID) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteSBMServerNetwork indicates an expected call of DeleteSBMServerNetwork. +func (mr *MockHostsServiceMockRecorder) DeleteSBMServerNetwork(ctx, serverID, networkID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSBMServerNetwork", reflect.TypeOf((*MockHostsService)(nil).DeleteSBMServerNetwork), ctx, serverID, networkID) +} + // DetachSSHKeyFromDedicatedServer mocks base method. func (m *MockHostsService) DetachSSHKeyFromDedicatedServer(ctx context.Context, serverID, fingerprint string) error { m.ctrl.T.Helper() @@ -646,6 +706,21 @@ func (mr *MockHostsServiceMockRecorder) GetDedicatedServerOOBCredentials(ctx, id return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDedicatedServerOOBCredentials", reflect.TypeOf((*MockHostsService)(nil).GetDedicatedServerOOBCredentials), ctx, id, params) } +// GetDedicatedServerSSHKey mocks base method. +func (m *MockHostsService) GetDedicatedServerSSHKey(ctx context.Context, serverID, fingerprint string) (*serverscom.SSHKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDedicatedServerSSHKey", ctx, serverID, fingerprint) + ret0, _ := ret[0].(*serverscom.SSHKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDedicatedServerSSHKey indicates an expected call of GetDedicatedServerSSHKey. +func (mr *MockHostsServiceMockRecorder) GetDedicatedServerSSHKey(ctx, serverID, fingerprint any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDedicatedServerSSHKey", reflect.TypeOf((*MockHostsService)(nil).GetDedicatedServerSSHKey), ctx, serverID, fingerprint) +} + // GetKubernetesBaremetalNode mocks base method. func (m *MockHostsService) GetKubernetesBaremetalNode(ctx context.Context, id string) (*serverscom.KubernetesBaremetalNode, error) { m.ctrl.T.Helper() @@ -676,6 +751,36 @@ func (mr *MockHostsServiceMockRecorder) GetSBMServer(ctx, id any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSBMServer", reflect.TypeOf((*MockHostsService)(nil).GetSBMServer), ctx, id) } +// GetSBMServerNetwork mocks base method. +func (m *MockHostsService) GetSBMServerNetwork(ctx context.Context, serverID, networkID string) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSBMServerNetwork", ctx, serverID, networkID) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSBMServerNetwork indicates an expected call of GetSBMServerNetwork. +func (mr *MockHostsServiceMockRecorder) GetSBMServerNetwork(ctx, serverID, networkID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSBMServerNetwork", reflect.TypeOf((*MockHostsService)(nil).GetSBMServerNetwork), ctx, serverID, networkID) +} + +// GetSBMServerNetworkUsage mocks base method. +func (m *MockHostsService) GetSBMServerNetworkUsage(ctx context.Context, id string) (*serverscom.NetworkUsage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSBMServerNetworkUsage", ctx, id) + ret0, _ := ret[0].(*serverscom.NetworkUsage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSBMServerNetworkUsage indicates an expected call of GetSBMServerNetworkUsage. +func (mr *MockHostsServiceMockRecorder) GetSBMServerNetworkUsage(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSBMServerNetworkUsage", reflect.TypeOf((*MockHostsService)(nil).GetSBMServerNetworkUsage), ctx, id) +} + // KubernetesBaremetalNodeDriveSlots mocks base method. func (m *MockHostsService) KubernetesBaremetalNodeDriveSlots(id string) serverscom.Collection[serverscom.HostDriveSlot] { m.ctrl.T.Helper() @@ -956,6 +1061,20 @@ func (mr *MockHostsServiceMockRecorder) ReleaseSBMServer(ctx, id any) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseSBMServer", reflect.TypeOf((*MockHostsService)(nil).ReleaseSBMServer), ctx, id) } +// SBMServerNetworks mocks base method. +func (m *MockHostsService) SBMServerNetworks(id string) serverscom.Collection[serverscom.Network] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SBMServerNetworks", id) + ret0, _ := ret[0].(serverscom.Collection[serverscom.Network]) + return ret0 +} + +// SBMServerNetworks indicates an expected call of SBMServerNetworks. +func (mr *MockHostsServiceMockRecorder) SBMServerNetworks(id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SBMServerNetworks", reflect.TypeOf((*MockHostsService)(nil).SBMServerNetworks), id) +} + // SBMServerPTRRecords mocks base method. func (m *MockHostsService) SBMServerPTRRecords(id string) serverscom.Collection[serverscom.PTRRecord] { m.ctrl.T.Helper() diff --git a/internal/mocks/kubernetes_clusters_service.go b/internal/mocks/kubernetes_clusters_service.go index cb559c1..99af754 100644 --- a/internal/mocks/kubernetes_clusters_service.go +++ b/internal/mocks/kubernetes_clusters_service.go @@ -55,6 +55,35 @@ func (mr *MockKubernetesClustersServiceMockRecorder) Collection() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Collection", reflect.TypeOf((*MockKubernetesClustersService)(nil).Collection)) } +// CreateNodeGroup mocks base method. +func (m *MockKubernetesClustersService) CreateNodeGroup(ctx context.Context, clusterID string, input serverscom.KubernetesClusterNodeGroupCreateInput) (*serverscom.KubernetesClusterNodeGroup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateNodeGroup", ctx, clusterID, input) + ret0, _ := ret[0].(*serverscom.KubernetesClusterNodeGroup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateNodeGroup indicates an expected call of CreateNodeGroup. +func (mr *MockKubernetesClustersServiceMockRecorder) CreateNodeGroup(ctx, clusterID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNodeGroup", reflect.TypeOf((*MockKubernetesClustersService)(nil).CreateNodeGroup), ctx, clusterID, input) +} + +// DeleteNodeGroup mocks base method. +func (m *MockKubernetesClustersService) DeleteNodeGroup(ctx context.Context, clusterID, nodeGroupID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteNodeGroup", ctx, clusterID, nodeGroupID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteNodeGroup indicates an expected call of DeleteNodeGroup. +func (mr *MockKubernetesClustersServiceMockRecorder) DeleteNodeGroup(ctx, clusterID, nodeGroupID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteNodeGroup", reflect.TypeOf((*MockKubernetesClustersService)(nil).DeleteNodeGroup), ctx, clusterID, nodeGroupID) +} + // Get mocks base method. func (m *MockKubernetesClustersService) Get(ctx context.Context, id string) (*serverscom.KubernetesCluster, error) { m.ctrl.T.Helper() @@ -85,6 +114,35 @@ func (mr *MockKubernetesClustersServiceMockRecorder) GetNode(ctx, clusterID, nod return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNode", reflect.TypeOf((*MockKubernetesClustersService)(nil).GetNode), ctx, clusterID, nodeID) } +// MoveNodes mocks base method. +func (m *MockKubernetesClustersService) MoveNodes(ctx context.Context, clusterID string, input serverscom.KubernetesClusterMoveNodesInput) ([]serverscom.KubernetesClusterNode, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MoveNodes", ctx, clusterID, input) + ret0, _ := ret[0].([]serverscom.KubernetesClusterNode) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MoveNodes indicates an expected call of MoveNodes. +func (mr *MockKubernetesClustersServiceMockRecorder) MoveNodes(ctx, clusterID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MoveNodes", reflect.TypeOf((*MockKubernetesClustersService)(nil).MoveNodes), ctx, clusterID, input) +} + +// NodeGroups mocks base method. +func (m *MockKubernetesClustersService) NodeGroups(id string) serverscom.Collection[serverscom.KubernetesClusterNodeGroup] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeGroups", id) + ret0, _ := ret[0].(serverscom.Collection[serverscom.KubernetesClusterNodeGroup]) + return ret0 +} + +// NodeGroups indicates an expected call of NodeGroups. +func (mr *MockKubernetesClustersServiceMockRecorder) NodeGroups(id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeGroups", reflect.TypeOf((*MockKubernetesClustersService)(nil).NodeGroups), id) +} + // Nodes mocks base method. func (m *MockKubernetesClustersService) Nodes(id string) serverscom.Collection[serverscom.KubernetesClusterNode] { m.ctrl.T.Helper() @@ -113,3 +171,33 @@ func (mr *MockKubernetesClustersServiceMockRecorder) Update(ctx, id, input any) mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockKubernetesClustersService)(nil).Update), ctx, id, input) } + +// UpdateNode mocks base method. +func (m *MockKubernetesClustersService) UpdateNode(ctx context.Context, clusterID, nodeID string, input serverscom.KubernetesClusterNodeUpdateInput) (*serverscom.KubernetesClusterNode, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateNode", ctx, clusterID, nodeID, input) + ret0, _ := ret[0].(*serverscom.KubernetesClusterNode) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateNode indicates an expected call of UpdateNode. +func (mr *MockKubernetesClustersServiceMockRecorder) UpdateNode(ctx, clusterID, nodeID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateNode", reflect.TypeOf((*MockKubernetesClustersService)(nil).UpdateNode), ctx, clusterID, nodeID, input) +} + +// UpdateNodeGroup mocks base method. +func (m *MockKubernetesClustersService) UpdateNodeGroup(ctx context.Context, clusterID, nodeGroupID string, input serverscom.KubernetesClusterNodeGroupUpdateInput) (*serverscom.KubernetesClusterNodeGroup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateNodeGroup", ctx, clusterID, nodeGroupID, input) + ret0, _ := ret[0].(*serverscom.KubernetesClusterNodeGroup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateNodeGroup indicates an expected call of UpdateNodeGroup. +func (mr *MockKubernetesClustersServiceMockRecorder) UpdateNodeGroup(ctx, clusterID, nodeGroupID, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateNodeGroup", reflect.TypeOf((*MockKubernetesClustersService)(nil).UpdateNodeGroup), ctx, clusterID, nodeGroupID, input) +} diff --git a/internal/mocks/l2_segment_service.go b/internal/mocks/l2_segment_service.go index 68b8b75..0daefea 100644 --- a/internal/mocks/l2_segment_service.go +++ b/internal/mocks/l2_segment_service.go @@ -143,10 +143,10 @@ func (mr *MockL2SegmentsServiceMockRecorder) Members(segmentID any) *gomock.Call } // Networks mocks base method. -func (m *MockL2SegmentsService) Networks(segmentID string) serverscom.Collection[serverscom.Network] { +func (m *MockL2SegmentsService) Networks(segmentID string) serverscom.Collection[serverscom.L2SegmentNetwork] { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Networks", segmentID) - ret0, _ := ret[0].(serverscom.Collection[serverscom.Network]) + ret0, _ := ret[0].(serverscom.Collection[serverscom.L2SegmentNetwork]) return ret0 } diff --git a/internal/output/entities/cloud_instances.go b/internal/output/entities/cloud_instances.go index 13d3183..ff3f5ca 100644 --- a/internal/output/entities/cloud_instances.go +++ b/internal/output/entities/cloud_instances.go @@ -34,8 +34,8 @@ func RegisterCloudComputingInstanceDefinition() { {ID: "BackupCopies", Name: "BackupCopies", Path: "BackupCopies", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler}, {ID: "PublicPortBlocked", Name: "PublicPortBlocked", Path: "PublicPortBlocked", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler}, {ID: "Labels", Name: "Labels", Path: "Labels", PageViewHandlerFunc: mapPvHandler}, - {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler}, - {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler}, + {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, }, cmdDefaultFields: map[string][]string{ "list": CloudComputingInstanceListDefaultFields, diff --git a/internal/output/entities/dns.go b/internal/output/entities/dns.go new file mode 100644 index 0000000..3b1e0d7 --- /dev/null +++ b/internal/output/entities/dns.go @@ -0,0 +1,71 @@ +package entities + +import ( + "log" + "reflect" + + serverscom "github.com/serverscom/serverscom-go-client/pkg" +) + +var ( + DNSDomainType = reflect.TypeFor[serverscom.DNSDomain]() + DNSRecordType = reflect.TypeFor[serverscom.DNSRecord]() + DNSDelegationDataType = reflect.TypeFor[serverscom.DNSDomainDelegationData]() + DNSDomainListDefaultFields = []string{"ID", "Name", "DelegationStatus", "TTL"} + DNSRecordListDefaultFields = []string{"ID", "Type", "Name", "Data", "TTL", "Priority"} +) + +func RegisterDNSDefinitions() { + dnsDomainEntity := &Entity{ + fields: []Field{ + {ID: "ID", Name: "ID", Path: "ID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Name", Name: "Name", Path: "Name", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Email", Name: "Email", Path: "Email", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "TTL", Name: "TTL", Path: "TTL", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "DelegationStatus", Name: "DelegationStatus", Path: "DelegationStatus", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Labels", Name: "Labels", Path: "Labels", PageViewHandlerFunc: mapPvHandler}, + {ID: "UnpublishDate", Name: "UnpublishDate", Path: "UnpublishDate", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler}, + {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + }, + cmdDefaultFields: map[string][]string{ + "list": DNSDomainListDefaultFields, + }, + eType: DNSDomainType, + } + if err := Registry.Register(dnsDomainEntity); err != nil { + log.Fatal(err) + } + + dnsRecordEntity := &Entity{ + fields: []Field{ + {ID: "ID", Name: "ID", Path: "ID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "DomainID", Name: "DomainID", Path: "DomainID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Type", Name: "Type", Path: "Type", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Name", Name: "Name", Path: "Name", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Data", Name: "Data", Path: "Data", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "TTL", Name: "TTL", Path: "TTL", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Priority", Name: "Priority", Path: "Priority", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + }, + cmdDefaultFields: map[string][]string{ + "list-records": DNSRecordListDefaultFields, + }, + eType: DNSRecordType, + } + if err := Registry.Register(dnsRecordEntity); err != nil { + log.Fatal(err) + } + + dnsDelegationDataEntity := &Entity{ + fields: []Field{ + {ID: "Nameservers", Name: "Nameservers", Path: "Nameservers", ListHandlerFunc: stringHandler, PageViewHandlerFunc: slicePvHandler, Default: true}, + {ID: "RequiredTxt", Name: "RequiredTxt", Path: "RequiredTxt", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + }, + eType: DNSDelegationDataType, + } + if err := Registry.Register(dnsDelegationDataEntity); err != nil { + log.Fatal(err) + } +} diff --git a/internal/output/entities/hosts.go b/internal/output/entities/hosts.go index 73e95b6..7b83886 100644 --- a/internal/output/entities/hosts.go +++ b/internal/output/entities/hosts.go @@ -17,6 +17,7 @@ var ( HostDriveSlotType = reflect.TypeFor[serverscom.HostDriveSlot]() HostPTRRecordType = reflect.TypeFor[serverscom.PTRRecord]() HostNetworkType = reflect.TypeFor[serverscom.Network]() + HostNetworkUsageType = reflect.TypeFor[serverscom.NetworkUsage]() HostFeatureType = reflect.TypeFor[serverscom.DedicatedServerFeature]() HostServiceType = reflect.TypeFor[serverscom.DedicatedServerService]() HostOOBCredsType = reflect.TypeFor[serverscom.DedicatedServerOOBCredentials]() @@ -25,7 +26,7 @@ var ( KubernetesBaremetalNodeListDefaultFields = []string{"ID", "KubernetesClusterNodeNumber", "Title", "LocationCode", "Status", "PublicIPv4Address"} SBMServerListDefaultFields = []string{"ID", "Title", "RackID", "LocationCode", "Status", "PublicIPv4Address"} - NetworkListDefaultFields = []string{"ID", "Title", "Status", "CIDR", "Family", "InterfaceType", "DistributionMethod", "Additional"} + NetworkListDefaultFields = []string{"ID", "Title", "Status", "CIDR", "Family", "InterfaceType", "DistributionMethod", "Additional", "FirstIP", "Gateway"} ) func getConfigurationDetailsField() Field { @@ -267,6 +268,8 @@ func RegisterHostsSubDefinitions() { {ID: "InterfaceType", Name: "InterfaceType", Path: "InterfaceType", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "DistributionMethod", Name: "DistributionMethod", Path: "DistributionMethod", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "Additional", Name: "Additional", Path: "Additional", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "FirstIP", Name: "FirstIP", Path: "FirstIP", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Gateway", Name: "Gateway", Path: "Gateway", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, }, @@ -279,6 +282,19 @@ func RegisterHostsSubDefinitions() { log.Fatal(err) } + hostNetworkUsageEntity := &Entity{ + fields: []Field{ + {ID: "Type", Name: "Type", Path: "Type", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Value", Name: "Value", Path: "Utilization.Value", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Commit", Name: "Commit", Path: "Utilization.Commit", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Unit", Name: "Unit", Path: "Utilization.Unit", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + }, + eType: HostNetworkUsageType, + } + if err := Registry.Register(hostNetworkUsageEntity); err != nil { + log.Fatal(err) + } + hostFeatureEntity := &Entity{ fields: []Field{ {ID: "Name", Name: "Name", Path: "Name", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, diff --git a/internal/output/entities/init.go b/internal/output/entities/init.go index 5eef8b5..f17efe6 100644 --- a/internal/output/entities/init.go +++ b/internal/output/entities/init.go @@ -38,4 +38,5 @@ func init() { RegisterCloudBackupDefinition() RegisterRbsVolumeDefinitions() RegisterRbsVolumeCredentialsDefinition() + RegisterDNSDefinitions() } diff --git a/internal/output/entities/interface.go b/internal/output/entities/interface.go index 0e4f11a..142d34c 100644 --- a/internal/output/entities/interface.go +++ b/internal/output/entities/interface.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "reflect" - "slices" ) // RegistryInterface represents the interface for the EntityRegistry @@ -20,9 +19,9 @@ type EntityRegistry map[reflect.Type]EntityInterface type EntityInterface interface { GetType() reflect.Type GetDefaultFields() []string + GetCmdDefaultFields(cmd string) []string GetFields() []Field Validate(fields []string) error - SetCmdDefaultFields(cmd string) error } // Entity represents the base entity structure @@ -134,26 +133,14 @@ func (e *Entity) Validate(fields []string) error { return nil } -// SetCmdDefaultFields sets the default fields for an entity based on cmd -func (e *Entity) SetCmdDefaultFields(cmd string) error { +// GetCmdDefaultFields returns the default field IDs to show for the given +// command. If the command has an explicit set in cmdDefaultFields it is returned, otherwise it +// falls back to the registration-time defaults (fields marked Field.Default). +func (e *Entity) GetCmdDefaultFields(cmd string) []string { if defaultFields, ok := e.cmdDefaultFields[cmd]; ok { - fieldSet := make(map[string]struct{}, len(e.fields)) - for i, f := range e.fields { - e.fields[i].Default = false - fieldSet[f.ID] = struct{}{} - } - - for _, df := range defaultFields { - if _, exists := fieldSet[df]; !exists { - return fmt.Errorf("can't find field %s in entity field set", df) - } - } - - for i := range e.fields { - e.fields[i].Default = slices.Contains(defaultFields, e.fields[i].ID) - } + return defaultFields } - return nil + return e.GetDefaultFields() } // fieldInChildFields checks if a field is in the list of child fields diff --git a/internal/output/entities/l2_segments.go b/internal/output/entities/l2_segments.go index b2d4f4a..888942d 100644 --- a/internal/output/entities/l2_segments.go +++ b/internal/output/entities/l2_segments.go @@ -8,12 +8,13 @@ import ( ) var ( - L2SegmentType = reflect.TypeFor[serverscom.L2Segment]() - L2SegmentLocationGroupType = reflect.TypeFor[serverscom.L2LocationGroup]() - L2SegmentMemberType = reflect.TypeFor[serverscom.L2Member]() - L2SegmentNetworkType = reflect.TypeFor[serverscom.Network]() - L2SegmentListDefaultFields = []string{"ID", "Name", "Type", "Status", "LocationGroupID", "LocationGroupCode"} - L2SegmentMemberListDefaultFields = []string{"ID", "Title", "Mode", "VLAN", "Status"} + L2SegmentType = reflect.TypeFor[serverscom.L2Segment]() + L2SegmentLocationGroupType = reflect.TypeFor[serverscom.L2LocationGroup]() + L2SegmentMemberType = reflect.TypeFor[serverscom.L2Member]() + L2SegmentNetworkType = reflect.TypeFor[serverscom.L2SegmentNetwork]() + L2SegmentListDefaultFields = []string{"ID", "Name", "Type", "Status", "LocationGroupID", "LocationGroupCode"} + L2SegmentMemberListDefaultFields = []string{"ID", "Title", "Mode", "VLAN", "Status"} + L2SegmentNetworkListDefaultFields = []string{"ID", "Title", "Status", "CIDR", "Family", "InterfaceType", "DistributionMethod", "Additional"} ) func RegisterL2SegmentDefinitions() { @@ -75,4 +76,26 @@ func RegisterL2SegmentDefinitions() { if err := Registry.Register(l2SegmentMemberEntity); err != nil { log.Fatal(err) } + + l2SegmentNetworkEntity := &Entity{ + fields: []Field{ + {ID: "ID", Name: "ID", Path: "ID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Title", Name: "Title", Path: "Title", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Status", Name: "Status", Path: "Status", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "CIDR", Name: "CIDR", Path: "Cidr", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Family", Name: "Family", Path: "Family", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "InterfaceType", Name: "InterfaceType", Path: "InterfaceType", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "DistributionMethod", Name: "DistributionMethod", Path: "DistributionMethod", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Additional", Name: "Additional", Path: "Additional", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + }, + cmdDefaultFields: map[string][]string{ + "list-networks": L2SegmentNetworkListDefaultFields, + }, + eType: L2SegmentNetworkType, + } + if err := Registry.Register(l2SegmentNetworkEntity); err != nil { + log.Fatal(err) + } } diff --git a/internal/output/entities/load_balancer_clusters.go b/internal/output/entities/load_balancer_clusters.go index 672f243..b833f58 100644 --- a/internal/output/entities/load_balancer_clusters.go +++ b/internal/output/entities/load_balancer_clusters.go @@ -16,7 +16,6 @@ func RegisterLoadBalancerClusterDefinition() { fields: []Field{ {ID: "ID", Name: "ID", Path: "ID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "Name", Name: "Name", Path: "Name", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, - {ID: "Status", Name: "Status", Path: "Status", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "LocationID", Name: "LocationID", Path: "LocationID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "LocationCode", Name: "LocationCode", Path: "LocationCode", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, diff --git a/internal/output/formatter.go b/internal/output/formatter.go index 1bf5b22..bdbc33b 100644 --- a/internal/output/formatter.go +++ b/internal/output/formatter.go @@ -21,6 +21,7 @@ type Formatter struct { fieldsToShow []string fieldList bool header bool + cmdName string } // NewFormatter creates new formatter with specified io.Writer @@ -40,6 +41,7 @@ func NewFormatter(cmd *cobra.Command, manager *config.Manager) *Formatter { fieldsToShow: fields, fieldList: fieldList, header: !noHeader, + cmdName: cmd.Name(), } } diff --git a/internal/output/skeletons/templates/dns/add-record.json b/internal/output/skeletons/templates/dns/add-record.json new file mode 100644 index 0000000..cbbc203 --- /dev/null +++ b/internal/output/skeletons/templates/dns/add-record.json @@ -0,0 +1,7 @@ +{ + "type": "", + "name": "", + "data": "", + "ttl": 0, + "priority": 0 +} diff --git a/internal/output/skeletons/templates/dns/add.json b/internal/output/skeletons/templates/dns/add.json new file mode 100644 index 0000000..16c7201 --- /dev/null +++ b/internal/output/skeletons/templates/dns/add.json @@ -0,0 +1,8 @@ +{ + "name": "", + "email": "", + "ttl": 0, + "labels": { + "key": "value" + } +} diff --git a/internal/output/skeletons/templates/lb/add_l4.json b/internal/output/skeletons/templates/lb/add_l4.json index 421deb8..b4d1158 100644 --- a/internal/output/skeletons/templates/lb/add_l4.json +++ b/internal/output/skeletons/templates/lb/add_l4.json @@ -3,7 +3,7 @@ "location_id": "", "cluster_id": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "vhost_zones": [ { "id": "", diff --git a/internal/output/skeletons/templates/lb/add_l7.json b/internal/output/skeletons/templates/lb/add_l7.json index c0ff224..acc0171 100644 --- a/internal/output/skeletons/templates/lb/add_l7.json +++ b/internal/output/skeletons/templates/lb/add_l7.json @@ -3,7 +3,7 @@ "location_id": "", "cluster_id": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "geoip": "true", "vhost_zones": [ { diff --git a/internal/output/skeletons/templates/lb/update_l4.json b/internal/output/skeletons/templates/lb/update_l4.json index 6e5c512..89d5149 100644 --- a/internal/output/skeletons/templates/lb/update_l4.json +++ b/internal/output/skeletons/templates/lb/update_l4.json @@ -3,7 +3,7 @@ "shared_cluster": "", "name": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "new_external_ips_count": "", "delete_external_ips": [], "vhost_zones": [ diff --git a/internal/output/skeletons/templates/lb/update_l7.json b/internal/output/skeletons/templates/lb/update_l7.json index 73ddc54..e93ba3c 100644 --- a/internal/output/skeletons/templates/lb/update_l7.json +++ b/internal/output/skeletons/templates/lb/update_l7.json @@ -3,7 +3,7 @@ "cluster_id": "", "shared_cluster": "", "store_logs": true, - "store_logs_region_id": "", + "store_logs_region_id": 0, "geoip": "true", "new_external_ips_count": "", "delete_external_ips": [], diff --git a/internal/output/utils.go b/internal/output/utils.go index fa4000f..7f41f10 100644 --- a/internal/output/utils.go +++ b/internal/output/utils.go @@ -50,7 +50,7 @@ func (f *Formatter) getOrderedFields(entity entities.EntityInterface) []entities if f.pageView { return entity.GetFields() } - fieldsToShow = entity.GetDefaultFields() + fieldsToShow = entity.GetCmdDefaultFields(f.cmdName) } availableFields := entity.GetFields() diff --git a/testdata/entities/cloud-instances/get.json b/testdata/entities/cloud-instances/get.json index f4b6c29..cfcb6c0 100644 --- a/testdata/entities/cloud-instances/get.json +++ b/testdata/entities/cloud-instances/get.json @@ -20,6 +20,7 @@ "labels": { "env": "test" }, + "vpn2gpn_instance": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/cloud-instances/get.txt b/testdata/entities/cloud-instances/get.txt index 2433656..772bdcc 100644 --- a/testdata/entities/cloud-instances/get.txt +++ b/testdata/entities/cloud-instances/get.txt @@ -1,2 +1,2 @@ -ID Name RegionCode Status PublicIPv4Address -test-instance-id test-instance AMS1 active 1.2.3.4 +ID Name RegionCode Status PublicIPv4Address Created Updated +test-instance-id test-instance AMS1 active 1.2.3.4 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/cloud-instances/get.yaml b/testdata/entities/cloud-instances/get.yaml index b9db1a2..df9505a 100644 --- a/testdata/entities/cloud-instances/get.yaml +++ b/testdata/entities/cloud-instances/get.yaml @@ -18,5 +18,6 @@ backupcopies: 2 publicportblocked: false labels: env: test +vpn2gpninstance: null created: 2025-01-01T12:00:00Z updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/cloud-instances/list.json b/testdata/entities/cloud-instances/list.json index 8c528e6..1604c05 100644 --- a/testdata/entities/cloud-instances/list.json +++ b/testdata/entities/cloud-instances/list.json @@ -21,6 +21,7 @@ "labels": { "env": "test" }, + "vpn2gpn_instance": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/cloud-instances/list_all.json b/testdata/entities/cloud-instances/list_all.json index 9551a69..d0ddf1e 100644 --- a/testdata/entities/cloud-instances/list_all.json +++ b/testdata/entities/cloud-instances/list_all.json @@ -21,6 +21,7 @@ "labels": { "env": "test" }, + "vpn2gpn_instance": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" }, @@ -46,6 +47,7 @@ "labels": { "env": "test" }, + "vpn2gpn_instance": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/cloud-regions/list_flavors.json b/testdata/entities/cloud-regions/list_flavors.json index d86c005..6d9a46e 100644 --- a/testdata/entities/cloud-regions/list_flavors.json +++ b/testdata/entities/cloud-regions/list_flavors.json @@ -1,6 +1,9 @@ [ { "id": "flavor-123", - "name": "Test Flavor" + "name": "Test Flavor", + "disk": 0, + "ram": 0, + "vcpus": 0 } ] diff --git a/testdata/entities/cloud-regions/list_flavors_all.json b/testdata/entities/cloud-regions/list_flavors_all.json index f8cd084..ecc8632 100644 --- a/testdata/entities/cloud-regions/list_flavors_all.json +++ b/testdata/entities/cloud-regions/list_flavors_all.json @@ -1,10 +1,16 @@ [ { "id": "flavor-123", - "name": "Test Flavor" + "name": "Test Flavor", + "disk": 0, + "ram": 0, + "vcpus": 0 }, { "id": "flavor-456", - "name": "Test Flavor 2" + "name": "Test Flavor 2", + "disk": 0, + "ram": 0, + "vcpus": 0 } ] diff --git a/testdata/entities/cloud-regions/list_images.json b/testdata/entities/cloud-regions/list_images.json index 9228627..220fcdd 100644 --- a/testdata/entities/cloud-regions/list_images.json +++ b/testdata/entities/cloud-regions/list_images.json @@ -1,6 +1,9 @@ [ { "id": "img-123", - "name": "Test Image" + "name": "Test Image", + "allowed_flavors": null, + "image_size": 0, + "min_disk": 0 } ] diff --git a/testdata/entities/cloud-regions/list_images_all.json b/testdata/entities/cloud-regions/list_images_all.json index 9e5995f..783d34f 100644 --- a/testdata/entities/cloud-regions/list_images_all.json +++ b/testdata/entities/cloud-regions/list_images_all.json @@ -1,10 +1,16 @@ [ { "id": "img-123", - "name": "Test Image" + "name": "Test Image", + "allowed_flavors": null, + "image_size": 0, + "min_disk": 0 }, { "id": "img-456", - "name": "Test Image 2" + "name": "Test Image 2", + "allowed_flavors": null, + "image_size": 0, + "min_disk": 0 } ] diff --git a/testdata/entities/dns/create.json b/testdata/entities/dns/create.json new file mode 100644 index 0000000..369bac5 --- /dev/null +++ b/testdata/entities/dns/create.json @@ -0,0 +1,8 @@ +{ + "name": "example.com", + "email": "admin@example.com", + "ttl": 3600, + "labels": { + "foo": "bar" + } +} diff --git a/testdata/entities/dns/create_record.json b/testdata/entities/dns/create_record.json new file mode 100644 index 0000000..df1e672 --- /dev/null +++ b/testdata/entities/dns/create_record.json @@ -0,0 +1,6 @@ +{ + "type": "A", + "name": "www", + "data": "1.2.3.4", + "ttl": 3600 +} diff --git a/testdata/entities/dns/delegation_data.json b/testdata/entities/dns/delegation_data.json new file mode 100644 index 0000000..34f974b --- /dev/null +++ b/testdata/entities/dns/delegation_data.json @@ -0,0 +1,7 @@ +{ + "nameservers": [ + "ns1.example.com", + "ns2.example.com" + ], + "required_txt": "sc-verification=abc123" +} diff --git a/testdata/entities/dns/delegation_data.txt b/testdata/entities/dns/delegation_data.txt new file mode 100644 index 0000000..b1c55ba --- /dev/null +++ b/testdata/entities/dns/delegation_data.txt @@ -0,0 +1,2 @@ +Nameservers RequiredTxt +[ns1.example.com ns2.example.com] sc-verification=abc123 diff --git a/testdata/entities/dns/delegation_data.yaml b/testdata/entities/dns/delegation_data.yaml new file mode 100644 index 0000000..cb530b2 --- /dev/null +++ b/testdata/entities/dns/delegation_data.yaml @@ -0,0 +1,4 @@ +nameservers: + - ns1.example.com + - ns2.example.com +requiredtxt: sc-verification=abc123 diff --git a/testdata/entities/dns/get.json b/testdata/entities/dns/get.json new file mode 100644 index 0000000..d5d2bc4 --- /dev/null +++ b/testdata/entities/dns/get.json @@ -0,0 +1,13 @@ +{ + "id": "abc123", + "name": "example.com", + "email": "admin@example.com", + "ttl": 3600, + "delegation_status": "verified", + "labels": { + "foo": "bar" + }, + "unpublish_date": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" +} diff --git a/testdata/entities/dns/get.txt b/testdata/entities/dns/get.txt new file mode 100644 index 0000000..87b4f77 --- /dev/null +++ b/testdata/entities/dns/get.txt @@ -0,0 +1,2 @@ +ID Name Email TTL DelegationStatus Created Updated +abc123 example.com admin@example.com 3600 verified 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/dns/get.yaml b/testdata/entities/dns/get.yaml new file mode 100644 index 0000000..e64600d --- /dev/null +++ b/testdata/entities/dns/get.yaml @@ -0,0 +1,10 @@ +id: abc123 +name: example.com +email: admin@example.com +ttl: 3600 +delegationstatus: verified +labels: + foo: bar +unpublishdate: null +created: 2025-01-01T12:00:00Z +updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/dns/get_record.json b/testdata/entities/dns/get_record.json new file mode 100644 index 0000000..10e7c37 --- /dev/null +++ b/testdata/entities/dns/get_record.json @@ -0,0 +1,11 @@ +{ + "id": "rec1", + "domain_id": "abc123", + "name": "www", + "type": "A", + "data": "1.2.3.4", + "ttl": 3600, + "priority": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" +} diff --git a/testdata/entities/dns/get_record.txt b/testdata/entities/dns/get_record.txt new file mode 100644 index 0000000..3d0097e --- /dev/null +++ b/testdata/entities/dns/get_record.txt @@ -0,0 +1,2 @@ +ID DomainID Type Name Data TTL Priority Created Updated +rec1 abc123 A www 1.2.3.4 3600 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/dns/get_record.yaml b/testdata/entities/dns/get_record.yaml new file mode 100644 index 0000000..c0d8082 --- /dev/null +++ b/testdata/entities/dns/get_record.yaml @@ -0,0 +1,9 @@ +id: rec1 +domainid: abc123 +name: www +type: A +data: 1.2.3.4 +ttl: 3600 +priority: null +created: 2025-01-01T12:00:00Z +updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/dns/list.json b/testdata/entities/dns/list.json new file mode 100644 index 0000000..dba936f --- /dev/null +++ b/testdata/entities/dns/list.json @@ -0,0 +1,15 @@ +[ + { + "id": "abc123", + "name": "example.com", + "email": "admin@example.com", + "ttl": 3600, + "delegation_status": "verified", + "labels": { + "foo": "bar" + }, + "unpublish_date": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + } +] diff --git a/testdata/entities/dns/list_all.json b/testdata/entities/dns/list_all.json new file mode 100644 index 0000000..72bfaeb --- /dev/null +++ b/testdata/entities/dns/list_all.json @@ -0,0 +1,28 @@ +[ + { + "id": "abc123", + "name": "example.com", + "email": "admin@example.com", + "ttl": 3600, + "delegation_status": "verified", + "labels": { + "foo": "bar" + }, + "unpublish_date": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + }, + { + "id": "def456", + "name": "example2.com", + "email": "admin@example.com", + "ttl": 3600, + "delegation_status": "verified", + "labels": { + "foo": "bar" + }, + "unpublish_date": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + } +] diff --git a/testdata/entities/dns/list_pageview.txt b/testdata/entities/dns/list_pageview.txt new file mode 100644 index 0000000..1336931 --- /dev/null +++ b/testdata/entities/dns/list_pageview.txt @@ -0,0 +1,19 @@ +ID: abc123 +Name: example.com +Email: admin@example.com +TTL: 3600 +DelegationStatus: verified +Labels: foo=bar +UnpublishDate: +Created: 2025-01-01T12:00:00Z +Updated: 2025-01-01T12:00:00Z +--- +ID: def456 +Name: example2.com +Email: admin@example.com +TTL: 3600 +DelegationStatus: verified +Labels: foo=bar +UnpublishDate: +Created: 2025-01-01T12:00:00Z +Updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/dns/list_records.json b/testdata/entities/dns/list_records.json new file mode 100644 index 0000000..083496a --- /dev/null +++ b/testdata/entities/dns/list_records.json @@ -0,0 +1,13 @@ +[ + { + "id": "rec1", + "domain_id": "abc123", + "name": "www", + "type": "A", + "data": "1.2.3.4", + "ttl": 3600, + "priority": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + } +] diff --git a/testdata/entities/dns/list_records_all.json b/testdata/entities/dns/list_records_all.json new file mode 100644 index 0000000..997e293 --- /dev/null +++ b/testdata/entities/dns/list_records_all.json @@ -0,0 +1,24 @@ +[ + { + "id": "rec1", + "domain_id": "abc123", + "name": "www", + "type": "A", + "data": "1.2.3.4", + "ttl": 3600, + "priority": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + }, + { + "id": "rec2", + "domain_id": "abc123", + "name": "mail", + "type": "MX", + "data": "mail.example.com", + "ttl": 3600, + "priority": 10, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + } +] diff --git a/testdata/entities/dns/list_records_pageview.txt b/testdata/entities/dns/list_records_pageview.txt new file mode 100644 index 0000000..2f6ad08 --- /dev/null +++ b/testdata/entities/dns/list_records_pageview.txt @@ -0,0 +1,19 @@ +ID: rec1 +DomainID: abc123 +Type: A +Name: www +Data: 1.2.3.4 +TTL: 3600 +Priority: +Created: 2025-01-01T12:00:00Z +Updated: 2025-01-01T12:00:00Z +--- +ID: rec2 +DomainID: abc123 +Type: MX +Name: mail +Data: mail.example.com +TTL: 3600 +Priority: 10 +Created: 2025-01-01T12:00:00Z +Updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/dns/list_records_template.txt b/testdata/entities/dns/list_records_template.txt new file mode 100644 index 0000000..f902a9b --- /dev/null +++ b/testdata/entities/dns/list_records_template.txt @@ -0,0 +1,2 @@ +Name: www +Name: mail diff --git a/testdata/entities/dns/list_template.txt b/testdata/entities/dns/list_template.txt new file mode 100644 index 0000000..6f5254e --- /dev/null +++ b/testdata/entities/dns/list_template.txt @@ -0,0 +1,2 @@ +Name: example.com +Name: example2.com diff --git a/testdata/entities/dns/update.json b/testdata/entities/dns/update.json new file mode 100644 index 0000000..4b0d233 --- /dev/null +++ b/testdata/entities/dns/update.json @@ -0,0 +1,13 @@ +{ + "id": "abc123", + "name": "example.com", + "email": "admin@example.com", + "ttl": 3600, + "delegation_status": "verified", + "labels": { + "new": "label" + }, + "unpublish_date": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" +} diff --git a/testdata/entities/dns/update_record.json b/testdata/entities/dns/update_record.json new file mode 100644 index 0000000..fad9c93 --- /dev/null +++ b/testdata/entities/dns/update_record.json @@ -0,0 +1,11 @@ +{ + "id": "rec1", + "domain_id": "abc123", + "name": "www", + "type": "A", + "data": "5.6.7.8", + "ttl": 7200, + "priority": null, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" +} diff --git a/testdata/entities/hosts/create_ebm_resp.json b/testdata/entities/hosts/create_ebm_resp.json index 3fc68a6..2d974cf 100644 --- a/testdata/entities/hosts/create_ebm_resp.json +++ b/testdata/entities/hosts/create_ebm_resp.json @@ -29,6 +29,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/get_ebm.json b/testdata/entities/hosts/get_ebm.json index d79f41f..3da118b 100644 --- a/testdata/entities/hosts/get_ebm.json +++ b/testdata/entities/hosts/get_ebm.json @@ -28,6 +28,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/get_ebm.yaml b/testdata/entities/hosts/get_ebm.yaml index c0b84cd..34a0ccd 100644 --- a/testdata/entities/hosts/get_ebm.yaml +++ b/testdata/entities/hosts/get_ebm.yaml @@ -26,5 +26,7 @@ configurationdetails: operatingsystemid: 5 operatingsystemfullname: CentOS 7 x86_64 labels: {} +ipxeconfig: null +userdatasha256: null created: 2025-01-01T12:00:00Z updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/get_ebm_network.json b/testdata/entities/hosts/get_ebm_network.json index 12661cc..d0a5f89 100644 --- a/testdata/entities/hosts/get_ebm_network.json +++ b/testdata/entities/hosts/get_ebm_network.json @@ -7,7 +7,8 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/get_ebm_network.txt b/testdata/entities/hosts/get_ebm_network.txt index 87fcf6f..0c2b290 100644 --- a/testdata/entities/hosts/get_ebm_network.txt +++ b/testdata/entities/hosts/get_ebm_network.txt @@ -1,2 +1,2 @@ -ID Title Status CIDR Family InterfaceType DistributionMethod Additional Created Updated -testNetId Some Net active 100.0.8.0/29 ipv4 public gateway false 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z +ID Title Status CIDR Family InterfaceType DistributionMethod Additional FirstIP Gateway Created Updated +testNetId Some Net active 100.0.8.0/29 ipv4 public gateway false 100.0.8.2 100.0.8.1 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/get_ebm_network.yaml b/testdata/entities/hosts/get_ebm_network.yaml index 130e2cc..a5e0771 100644 --- a/testdata/entities/hosts/get_ebm_network.yaml +++ b/testdata/entities/hosts/get_ebm_network.yaml @@ -6,6 +6,7 @@ family: ipv4 interfacetype: public distributionmethod: gateway additional: false +firstip: 100.0.8.2 +gateway: 100.0.8.1 created: 2025-01-01T12:00:00Z updated: 2025-01-01T12:00:00Z -state: "" diff --git a/testdata/entities/hosts/get_ebm_network_usage.json b/testdata/entities/hosts/get_ebm_network_usage.json new file mode 100644 index 0000000..1957b57 --- /dev/null +++ b/testdata/entities/hosts/get_ebm_network_usage.json @@ -0,0 +1,8 @@ +{ + "type": "public", + "utilization": { + "value": 100, + "commit": 50, + "unit": "GB" + } +} diff --git a/testdata/entities/hosts/get_ebm_network_usage.txt b/testdata/entities/hosts/get_ebm_network_usage.txt new file mode 100644 index 0000000..924c822 --- /dev/null +++ b/testdata/entities/hosts/get_ebm_network_usage.txt @@ -0,0 +1,2 @@ +Type Value Commit Unit +public 100 50 GB diff --git a/testdata/entities/hosts/get_ebm_network_usage.yaml b/testdata/entities/hosts/get_ebm_network_usage.yaml new file mode 100644 index 0000000..8636bdb --- /dev/null +++ b/testdata/entities/hosts/get_ebm_network_usage.yaml @@ -0,0 +1,5 @@ +type: public +utilization: + value: 100 + commit: 50 + unit: GB diff --git a/testdata/entities/hosts/get_sbm_network.json b/testdata/entities/hosts/get_sbm_network.json new file mode 100644 index 0000000..d0a5f89 --- /dev/null +++ b/testdata/entities/hosts/get_sbm_network.json @@ -0,0 +1,14 @@ +{ + "id": "testNetId", + "title": "Some Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" +} diff --git a/testdata/entities/hosts/get_sbm_network.txt b/testdata/entities/hosts/get_sbm_network.txt new file mode 100644 index 0000000..0c2b290 --- /dev/null +++ b/testdata/entities/hosts/get_sbm_network.txt @@ -0,0 +1,2 @@ +ID Title Status CIDR Family InterfaceType DistributionMethod Additional FirstIP Gateway Created Updated +testNetId Some Net active 100.0.8.0/29 ipv4 public gateway false 100.0.8.2 100.0.8.1 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/get_sbm_network.yaml b/testdata/entities/hosts/get_sbm_network.yaml new file mode 100644 index 0000000..a5e0771 --- /dev/null +++ b/testdata/entities/hosts/get_sbm_network.yaml @@ -0,0 +1,12 @@ +id: testNetId +title: Some Net +status: active +cidr: 100.0.8.0/29 +family: ipv4 +interfacetype: public +distributionmethod: gateway +additional: false +firstip: 100.0.8.2 +gateway: 100.0.8.1 +created: 2025-01-01T12:00:00Z +updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/get_sbm_network_usage.json b/testdata/entities/hosts/get_sbm_network_usage.json new file mode 100644 index 0000000..1957b57 --- /dev/null +++ b/testdata/entities/hosts/get_sbm_network_usage.json @@ -0,0 +1,8 @@ +{ + "type": "public", + "utilization": { + "value": 100, + "commit": 50, + "unit": "GB" + } +} diff --git a/testdata/entities/hosts/get_sbm_network_usage.txt b/testdata/entities/hosts/get_sbm_network_usage.txt new file mode 100644 index 0000000..924c822 --- /dev/null +++ b/testdata/entities/hosts/get_sbm_network_usage.txt @@ -0,0 +1,2 @@ +Type Value Commit Unit +public 100 50 GB diff --git a/testdata/entities/hosts/get_sbm_network_usage.yaml b/testdata/entities/hosts/get_sbm_network_usage.yaml new file mode 100644 index 0000000..8636bdb --- /dev/null +++ b/testdata/entities/hosts/get_sbm_network_usage.yaml @@ -0,0 +1,5 @@ +type: public +utilization: + value: 100 + commit: 50 + unit: GB diff --git a/testdata/entities/hosts/list_ebm.json b/testdata/entities/hosts/list_ebm.json index 3fc68a6..2d974cf 100644 --- a/testdata/entities/hosts/list_ebm.json +++ b/testdata/entities/hosts/list_ebm.json @@ -29,6 +29,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/list_ebm_all.json b/testdata/entities/hosts/list_ebm_all.json index d25ef74..abd722c 100644 --- a/testdata/entities/hosts/list_ebm_all.json +++ b/testdata/entities/hosts/list_ebm_all.json @@ -29,6 +29,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" }, @@ -62,6 +64,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/list_ebm_networks.json b/testdata/entities/hosts/list_ebm_networks.json index 669c5bf..8e36150 100644 --- a/testdata/entities/hosts/list_ebm_networks.json +++ b/testdata/entities/hosts/list_ebm_networks.json @@ -8,8 +8,9 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } ] diff --git a/testdata/entities/hosts/list_ebm_networks_all.json b/testdata/entities/hosts/list_ebm_networks_all.json index a9aca37..d79a5cc 100644 --- a/testdata/entities/hosts/list_ebm_networks_all.json +++ b/testdata/entities/hosts/list_ebm_networks_all.json @@ -8,9 +8,10 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" }, { "id": "testNetId2", @@ -21,8 +22,9 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } ] diff --git a/testdata/entities/hosts/list_ebm_networks_pageview.txt b/testdata/entities/hosts/list_ebm_networks_pageview.txt index a98985d..47471df 100644 --- a/testdata/entities/hosts/list_ebm_networks_pageview.txt +++ b/testdata/entities/hosts/list_ebm_networks_pageview.txt @@ -6,6 +6,8 @@ Family: ipv4 InterfaceType: public DistributionMethod: gateway Additional: false +FirstIP: 100.0.8.2 +Gateway: 100.0.8.1 Created: 2025-01-01T12:00:00Z Updated: 2025-01-01T12:00:00Z --- @@ -17,5 +19,7 @@ Family: ipv4 InterfaceType: public DistributionMethod: gateway Additional: false +FirstIP: 100.0.8.2 +Gateway: 100.0.8.1 Created: 2025-01-01T12:00:00Z Updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/list_hosts.json b/testdata/entities/hosts/list_hosts.json index f7004a0..900db5a 100644 --- a/testdata/entities/hosts/list_hosts.json +++ b/testdata/entities/hosts/list_hosts.json @@ -12,6 +12,10 @@ "private_ipv4_address": null, "public_ipv4_address": "1.2.3.4", "scheduled_release_at": null, + "lease_start_at": null, + "oob_ipv4_address": null, + "rack_id": null, + "labels": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" }, @@ -28,6 +32,10 @@ "private_ipv4_address": null, "public_ipv4_address": "1.2.3.4", "scheduled_release_at": null, + "lease_start_at": null, + "oob_ipv4_address": null, + "rack_id": null, + "labels": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/list_kbm_networks.json b/testdata/entities/hosts/list_kbm_networks.json index 669c5bf..8e36150 100644 --- a/testdata/entities/hosts/list_kbm_networks.json +++ b/testdata/entities/hosts/list_kbm_networks.json @@ -8,8 +8,9 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } ] diff --git a/testdata/entities/hosts/list_kbm_networks_all.json b/testdata/entities/hosts/list_kbm_networks_all.json index a9aca37..d79a5cc 100644 --- a/testdata/entities/hosts/list_kbm_networks_all.json +++ b/testdata/entities/hosts/list_kbm_networks_all.json @@ -8,9 +8,10 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" }, { "id": "testNetId2", @@ -21,8 +22,9 @@ "interface_type": "public", "distribution_method": "gateway", "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } ] diff --git a/testdata/entities/hosts/list_kbm_networks_pageview.txt b/testdata/entities/hosts/list_kbm_networks_pageview.txt index a98985d..47471df 100644 --- a/testdata/entities/hosts/list_kbm_networks_pageview.txt +++ b/testdata/entities/hosts/list_kbm_networks_pageview.txt @@ -6,6 +6,8 @@ Family: ipv4 InterfaceType: public DistributionMethod: gateway Additional: false +FirstIP: 100.0.8.2 +Gateway: 100.0.8.1 Created: 2025-01-01T12:00:00Z Updated: 2025-01-01T12:00:00Z --- @@ -17,5 +19,7 @@ Family: ipv4 InterfaceType: public DistributionMethod: gateway Additional: false +FirstIP: 100.0.8.2 +Gateway: 100.0.8.1 Created: 2025-01-01T12:00:00Z Updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/list_sbm_networks.json b/testdata/entities/hosts/list_sbm_networks.json new file mode 100644 index 0000000..8e36150 --- /dev/null +++ b/testdata/entities/hosts/list_sbm_networks.json @@ -0,0 +1,16 @@ +[ + { + "id": "testNetId", + "title": "Some Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + } +] diff --git a/testdata/entities/hosts/list_sbm_networks_all.json b/testdata/entities/hosts/list_sbm_networks_all.json new file mode 100644 index 0000000..d79a5cc --- /dev/null +++ b/testdata/entities/hosts/list_sbm_networks_all.json @@ -0,0 +1,30 @@ +[ + { + "id": "testNetId", + "title": "Some Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + }, + { + "id": "testNetId2", + "title": "Another Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "first_ip": "100.0.8.2", + "gateway": "100.0.8.1", + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z" + } +] diff --git a/testdata/entities/hosts/list_sbm_networks_pageview.txt b/testdata/entities/hosts/list_sbm_networks_pageview.txt new file mode 100644 index 0000000..47471df --- /dev/null +++ b/testdata/entities/hosts/list_sbm_networks_pageview.txt @@ -0,0 +1,25 @@ +ID: testNetId +Title: Some Net +Status: active +CIDR: 100.0.8.0/29 +Family: ipv4 +InterfaceType: public +DistributionMethod: gateway +Additional: false +FirstIP: 100.0.8.2 +Gateway: 100.0.8.1 +Created: 2025-01-01T12:00:00Z +Updated: 2025-01-01T12:00:00Z +--- +ID: testNetId2 +Title: Another Net +Status: active +CIDR: 100.0.8.0/29 +Family: ipv4 +InterfaceType: public +DistributionMethod: gateway +Additional: false +FirstIP: 100.0.8.2 +Gateway: 100.0.8.1 +Created: 2025-01-01T12:00:00Z +Updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/list_sbm_networks_template.txt b/testdata/entities/hosts/list_sbm_networks_template.txt new file mode 100644 index 0000000..8f58214 --- /dev/null +++ b/testdata/entities/hosts/list_sbm_networks_template.txt @@ -0,0 +1,2 @@ +Network: testNetId Title: Some Net +Network: testNetId2 Title: Another Net diff --git a/testdata/entities/hosts/release_ebm_resp.json b/testdata/entities/hosts/release_ebm_resp.json index d79f41f..3da118b 100644 --- a/testdata/entities/hosts/release_ebm_resp.json +++ b/testdata/entities/hosts/release_ebm_resp.json @@ -28,6 +28,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/release_ebm_scheduled_resp.json b/testdata/entities/hosts/release_ebm_scheduled_resp.json index 30d3238..fee760c 100644 --- a/testdata/entities/hosts/release_ebm_scheduled_resp.json +++ b/testdata/entities/hosts/release_ebm_scheduled_resp.json @@ -28,6 +28,8 @@ "operating_system_full_name": "CentOS 7 x86_64" }, "labels": null, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/hosts/update_ebm_resp.json b/testdata/entities/hosts/update_ebm_resp.json index 271d8c3..2ab7077 100644 --- a/testdata/entities/hosts/update_ebm_resp.json +++ b/testdata/entities/hosts/update_ebm_resp.json @@ -30,6 +30,8 @@ "labels": { "new": "label" }, + "ipxe_config": null, + "userdata_sha256": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/k8s/get_node.json b/testdata/entities/k8s/get_node.json index 251cf71..d63e7ab 100644 --- a/testdata/entities/k8s/get_node.json +++ b/testdata/entities/k8s/get_node.json @@ -10,6 +10,16 @@ "public_ipv4_address": "127.0.0.1", "ref_id": "1", "cluster_id": "testId", + "location_id": 0, + "location_code": "", + "node_group": { + "id": "", + "name": "", + "description": null, + "node_count": 0, + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z" + }, "labels": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" diff --git a/testdata/entities/k8s/get_node.yaml b/testdata/entities/k8s/get_node.yaml index 410c3c8..28e2f87 100644 --- a/testdata/entities/k8s/get_node.yaml +++ b/testdata/entities/k8s/get_node.yaml @@ -9,6 +9,15 @@ privateipv4address: 10.0.0.1 publicipv4address: 127.0.0.1 refid: "1" clusterid: testId +locationid: 0 +locationcode: "" +nodegroup: + id: "" + name: "" + description: null + nodecount: 0 + created: 0001-01-01T00:00:00Z + updated: 0001-01-01T00:00:00Z labels: {} created: 2025-01-01T12:00:00Z updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/k8s/list_all_nodes.json b/testdata/entities/k8s/list_all_nodes.json index 3830021..ed70db5 100644 --- a/testdata/entities/k8s/list_all_nodes.json +++ b/testdata/entities/k8s/list_all_nodes.json @@ -11,6 +11,16 @@ "public_ipv4_address": "127.0.0.1", "ref_id": "1", "cluster_id": "testId", + "location_id": 0, + "location_code": "", + "node_group": { + "id": "", + "name": "", + "description": null, + "node_count": 0, + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z" + }, "labels": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" @@ -27,6 +37,16 @@ "public_ipv4_address": "127.0.0.1", "ref_id": "1", "cluster_id": "testId", + "location_id": 0, + "location_code": "", + "node_group": { + "id": "", + "name": "", + "description": null, + "node_count": 0, + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z" + }, "labels": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" diff --git a/testdata/entities/k8s/list_nodes.json b/testdata/entities/k8s/list_nodes.json index 31ab3dd..bde440f 100644 --- a/testdata/entities/k8s/list_nodes.json +++ b/testdata/entities/k8s/list_nodes.json @@ -11,6 +11,16 @@ "public_ipv4_address": "127.0.0.1", "ref_id": "1", "cluster_id": "testId", + "location_id": 0, + "location_code": "", + "node_group": { + "id": "", + "name": "", + "description": null, + "node_count": 0, + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z" + }, "labels": null, "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" diff --git a/testdata/entities/l2-segments/list_networks.json b/testdata/entities/l2-segments/list_networks.json index 4534467..c33b704 100644 --- a/testdata/entities/l2-segments/list_networks.json +++ b/testdata/entities/l2-segments/list_networks.json @@ -9,7 +9,6 @@ "distribution_method": "route", "additional": true, "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } ] diff --git a/testdata/entities/l2-segments/list_networks_all.json b/testdata/entities/l2-segments/list_networks_all.json index c1251c7..8295f5f 100644 --- a/testdata/entities/l2-segments/list_networks_all.json +++ b/testdata/entities/l2-segments/list_networks_all.json @@ -9,8 +9,7 @@ "distribution_method": "route", "additional": true, "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" }, { "id": "testId2", @@ -22,7 +21,6 @@ "distribution_method": "route", "additional": true, "created_at": "2025-01-01T12:00:00Z", - "updated_at": "2025-01-01T12:00:00Z", - "state": "" + "updated_at": "2025-01-01T12:00:00Z" } ] diff --git a/testdata/entities/lb-clusters/get.json b/testdata/entities/lb-clusters/get.json index e2cf999..f5f85a9 100644 --- a/testdata/entities/lb-clusters/get.json +++ b/testdata/entities/lb-clusters/get.json @@ -3,7 +3,6 @@ "name": "test-lb-cluster", "location_id": 1, "location_code": "test", - "status": "active", "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/lb-clusters/get.txt b/testdata/entities/lb-clusters/get.txt index 0207050..ccf1995 100644 --- a/testdata/entities/lb-clusters/get.txt +++ b/testdata/entities/lb-clusters/get.txt @@ -1,2 +1,2 @@ -ID Name Status LocationID LocationCode Created Updated -testId test-lb-cluster active 1 test 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z +ID Name LocationID LocationCode Created Updated +testId test-lb-cluster 1 test 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/lb-clusters/get.yaml b/testdata/entities/lb-clusters/get.yaml index c9221d2..116554f 100644 --- a/testdata/entities/lb-clusters/get.yaml +++ b/testdata/entities/lb-clusters/get.yaml @@ -2,6 +2,5 @@ id: testId name: test-lb-cluster locationid: 1 locationcode: test -status: active created: 2025-01-01T12:00:00Z updated: 2025-01-01T12:00:00Z diff --git a/testdata/entities/lb-clusters/list.json b/testdata/entities/lb-clusters/list.json index c1d78a0..ed24a27 100644 --- a/testdata/entities/lb-clusters/list.json +++ b/testdata/entities/lb-clusters/list.json @@ -4,7 +4,6 @@ "name": "test-lb-cluster-1", "location_id": 1, "location_code": "test", - "status": "active", "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/lb-clusters/list_all.json b/testdata/entities/lb-clusters/list_all.json index fe1580e..a3d04fa 100644 --- a/testdata/entities/lb-clusters/list_all.json +++ b/testdata/entities/lb-clusters/list_all.json @@ -4,7 +4,6 @@ "name": "test-lb-cluster-1", "location_id": 1, "location_code": "test", - "status": "active", "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" }, @@ -13,7 +12,6 @@ "name": "test-lb-cluster-2", "location_id": 1, "location_code": "test", - "status": "active", "created_at": "2025-01-01T12:00:00Z", "updated_at": "2025-01-01T12:00:00Z" } diff --git a/testdata/entities/lb-clusters/list_pageview.txt b/testdata/entities/lb-clusters/list_pageview.txt index ec15f54..9f50d6c 100644 --- a/testdata/entities/lb-clusters/list_pageview.txt +++ b/testdata/entities/lb-clusters/list_pageview.txt @@ -1,6 +1,5 @@ ID: testId1 Name: test-lb-cluster-1 -Status: active LocationID: 1 LocationCode: test Created: 2025-01-01T12:00:00Z @@ -8,7 +7,6 @@ Updated: 2025-01-01T12:00:00Z --- ID: testId2 Name: test-lb-cluster-2 -Status: active LocationID: 1 LocationCode: test Created: 2025-01-01T12:00:00Z diff --git a/testdata/entities/lb/get_l4.json b/testdata/entities/lb/get_l4.json index e8bd4dd..2a7b9a1 100644 --- a/testdata/entities/lb/get_l4.json +++ b/testdata/entities/lb/get_l4.json @@ -9,7 +9,11 @@ "location_id": 1, "location_code": "test", "store_logs": false, + "store_logs_region_id": 0, "cluster_id": null, + "shared_cluster": false, + "vhost_zones": null, + "upstream_zones": null, "labels": { "foo": "bar" }, diff --git a/testdata/entities/lb/get_l4.yaml b/testdata/entities/lb/get_l4.yaml index be7b421..77d65df 100644 --- a/testdata/entities/lb/get_l4.yaml +++ b/testdata/entities/lb/get_l4.yaml @@ -7,7 +7,11 @@ externaladdresses: locationid: 1 locationcode: test storelogs: false +storelogsregionid: 0 clusterid: null +sharedcluster: false +vhostzones: [] +upstreamzones: [] labels: foo: bar created: 2025-01-01T12:00:00Z diff --git a/testdata/entities/lb/get_l7.json b/testdata/entities/lb/get_l7.json index 8774921..17a662c 100644 --- a/testdata/entities/lb/get_l7.json +++ b/testdata/entities/lb/get_l7.json @@ -15,6 +15,9 @@ "store_logs": false, "store_logs_region_id": 0, "cluster_id": null, + "shared_cluster": false, + "vhost_zones": null, + "upstream_zones": null, "labels": { "foo": "bar" }, diff --git a/testdata/entities/lb/get_l7.yaml b/testdata/entities/lb/get_l7.yaml index 5cbf62b..67cf5c8 100644 --- a/testdata/entities/lb/get_l7.yaml +++ b/testdata/entities/lb/get_l7.yaml @@ -12,6 +12,9 @@ geoip: false storelogs: false storelogsregionid: 0 clusterid: null +sharedcluster: false +vhostzones: [] +upstreamzones: [] labels: foo: bar created: 2025-01-01T12:00:00Z diff --git a/testdata/entities/lb/list_all.json b/testdata/entities/lb/list_all.json index 89e9356..93a6ea8 100644 --- a/testdata/entities/lb/list_all.json +++ b/testdata/entities/lb/list_all.json @@ -10,6 +10,7 @@ "location_id": 1, "location_code": "test", "cluster_id": null, + "shared_cluster": false, "labels": { "foo": "bar" }, @@ -27,6 +28,7 @@ "location_id": 1, "location_code": "test", "cluster_id": null, + "shared_cluster": false, "labels": { "foo": "bar" }, diff --git a/testdata/entities/lb/list_l4.json b/testdata/entities/lb/list_l4.json index 18b1906..d8c763d 100644 --- a/testdata/entities/lb/list_l4.json +++ b/testdata/entities/lb/list_l4.json @@ -10,6 +10,7 @@ "location_id": 1, "location_code": "test", "cluster_id": null, + "shared_cluster": false, "labels": { "foo": "bar" }, diff --git a/testdata/entities/lb/list_l7.json b/testdata/entities/lb/list_l7.json index 2e7782e..f225044 100644 --- a/testdata/entities/lb/list_l7.json +++ b/testdata/entities/lb/list_l7.json @@ -10,6 +10,7 @@ "location_id": 1, "location_code": "test", "cluster_id": null, + "shared_cluster": false, "labels": { "foo": "bar" }, diff --git a/testdata/entities/lb/update_l4.json b/testdata/entities/lb/update_l4.json index 04e8ee2..c3ff2cf 100644 --- a/testdata/entities/lb/update_l4.json +++ b/testdata/entities/lb/update_l4.json @@ -9,7 +9,11 @@ "location_id": 1, "location_code": "test", "store_logs": false, + "store_logs_region_id": 0, "cluster_id": null, + "shared_cluster": false, + "vhost_zones": null, + "upstream_zones": null, "labels": { "new": "label" }, diff --git a/testdata/entities/lb/update_l7.json b/testdata/entities/lb/update_l7.json index 4a46127..d09fdd5 100644 --- a/testdata/entities/lb/update_l7.json +++ b/testdata/entities/lb/update_l7.json @@ -15,6 +15,9 @@ "store_logs": false, "store_logs_region_id": 0, "cluster_id": null, + "shared_cluster": false, + "vhost_zones": null, + "upstream_zones": null, "labels": { "new": "label" },