From edad6a53b985ac15b9a7cdc3f25b8de5d52f0e18 Mon Sep 17 00:00:00 2001 From: Christopher J Schaefer Date: Wed, 17 Aug 2022 11:15:43 -0500 Subject: [PATCH 1/2] IBMCloud: Add DNS Service support - installconfig Add support for DNS Service on IBM Cloud in IPI. This allows lookup of resources based on PublishStrategy, CIS (External) vs. DNS (Internal). Handles service and zone lookup, and configuring DNS and Infrastructure. Partial: https://issues.redhat.com/browse/SPLAT-633 --- pkg/asset/installconfig/ibmcloud/client.go | 126 +++++++++++++++--- pkg/asset/installconfig/ibmcloud/dns.go | 14 +- pkg/asset/installconfig/ibmcloud/metadata.go | 52 +++++++- .../ibmcloud/mock/ibmcloudclient_generated.go | 32 +++-- .../installconfig/ibmcloud/validation.go | 11 +- .../installconfig/ibmcloud/validation_test.go | 41 ++++-- .../installconfig/platformprovisioncheck.go | 2 +- pkg/asset/manifests/dns.go | 2 +- pkg/asset/manifests/infrastructure.go | 18 ++- pkg/types/validation/installconfig.go | 2 +- 10 files changed, 243 insertions(+), 57 deletions(-) diff --git a/pkg/asset/installconfig/ibmcloud/client.go b/pkg/asset/installconfig/ibmcloud/client.go index d4bd7f14da3..1a7d0a2873c 100644 --- a/pkg/asset/installconfig/ibmcloud/client.go +++ b/pkg/asset/installconfig/ibmcloud/client.go @@ -5,16 +5,20 @@ import ( "fmt" "net/http" "os" + "strings" "time" "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/networking-go-sdk/dnsrecordsv1" + "github.com/IBM/networking-go-sdk/dnszonesv1" "github.com/IBM/networking-go-sdk/zonesv1" "github.com/IBM/platform-services-go-sdk/iamidentityv1" "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2" "github.com/IBM/platform-services-go-sdk/resourcemanagerv2" "github.com/IBM/vpc-go-sdk/vpcv1" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) //go:generate mockgen -source=./client.go -destination=./mock/ibmcloudclient_generated.go -package=mock @@ -23,11 +27,12 @@ import ( type API interface { GetAuthenticatorAPIKeyDetails(ctx context.Context) (*iamidentityv1.APIKey, error) GetCISInstance(ctx context.Context, crnstr string) (*resourcecontrollerv2.ResourceInstance, error) + GetDNSInstance(ctx context.Context, crnstr string) (*resourcecontrollerv2.ResourceInstance, error) GetDedicatedHostByName(ctx context.Context, name string, region string) (*vpcv1.DedicatedHost, error) GetDedicatedHostProfiles(ctx context.Context, region string) ([]vpcv1.DedicatedHostProfile, error) GetDNSRecordsByName(ctx context.Context, crnstr string, zoneID string, recordName string) ([]dnsrecordsv1.DnsrecordDetails, error) - GetDNSZoneIDByName(ctx context.Context, name string) (string, error) - GetDNSZones(ctx context.Context) ([]DNSZoneResponse, error) + GetDNSZoneIDByName(ctx context.Context, name string, publish types.PublishingStrategy) (string, error) + GetDNSZones(ctx context.Context, publish types.PublishingStrategy) ([]DNSZoneResponse, error) GetEncryptionKey(ctx context.Context, keyCRN string) (*EncryptionKeyResponse, error) GetResourceGroups(ctx context.Context) ([]resourcemanagerv2.ResourceGroup, error) GetResourceGroup(ctx context.Context, nameOrID string) (*resourcemanagerv2.ResourceGroup, error) @@ -49,8 +54,20 @@ type Client struct { vpcAPI *vpcv1.VpcV1 } -// cisServiceID is the Cloud Internet Services' catalog service ID. -const cisServiceID = "75874a60-cb12-11e7-948e-37ac098eb1b9" +// InstanceType is the IBM Cloud network services type being used +type InstanceType string + +const ( + // CISInstanceType is a Cloud Internet Services InstanceType + CISInstanceType InstanceType = "CIS" + // DNSInstanceType is a DNS Services InstanceType + DNSInstanceType InstanceType = "DNS" + + // cisServiceID is the Cloud Internet Services' catalog service ID. + cisServiceID = "75874a60-cb12-11e7-948e-37ac098eb1b9" + // dnsServiceID is the DNS Services' catalog service ID. + dnsServiceID = "b4ed8a30-936f-11e9-b289-1d079699cbe5" +) // VPCResourceNotFoundError represents an error for a VPC resoruce that is not found. type VPCResourceNotFoundError struct{} @@ -68,15 +85,19 @@ type DNSZoneResponse struct { // ID is the zone's ID. ID string - // CISInstanceCRN is the IBM Cloud Resource Name for the CIS instance where + // InstanceID is the IBM Cloud Resource ID for the service instance where // the DNS zone is managed. - CISInstanceCRN string + InstanceID string - // CISInstanceName is the display name of the CIS instance where the DNS zone + // InstanceCRN is the IBM Cloud Resource CRN for the service instance where + // the DNS zone is managed. + InstanceCRN string + + // InstanceName is the display name of the service instance where the DNS zone // is managed. - CISInstanceName string + InstanceName string - // ResourceGroupID is the resource group ID of the CIS instance. + // ResourceGroupID is the resource group ID of the service instance. ResourceGroupID string } @@ -138,20 +159,30 @@ func (c *Client) GetAuthenticatorAPIKeyDetails(ctx context.Context) (*iamidentit return details, nil } -// GetCISInstance gets a specific Cloud Internet Services instance by its CRN. -func (c *Client) GetCISInstance(ctx context.Context, crnstr string) (*resourcecontrollerv2.ResourceInstance, error) { +// getInstance gets a specific DNS or CIS instance by its CRN. +func (c *Client) getInstance(ctx context.Context, crnstr string, iType InstanceType) (*resourcecontrollerv2.ResourceInstance, error) { _, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() options := c.controllerAPI.NewGetResourceInstanceOptions(crnstr) resourceInstance, _, err := c.controllerAPI.GetResourceInstance(options) if err != nil { - return nil, errors.Wrap(err, "failed to get cis instances") + return nil, errors.Wrapf(err, "failed to get %s instances", iType) } return resourceInstance, nil } +// GetCISInstance gets a specific Cloud Internet Services by its CRN. +func (c *Client) GetCISInstance(ctx context.Context, crnstr string) (*resourcecontrollerv2.ResourceInstance, error) { + return c.getInstance(ctx, crnstr, CISInstanceType) +} + +// GetDNSInstance gets a specific DNS Services instance by its CRN. +func (c *Client) GetDNSInstance(ctx context.Context, crnstr string) (*resourcecontrollerv2.ResourceInstance, error) { + return c.getInstance(ctx, crnstr, DNSInstanceType) +} + // GetDedicatedHostByName gets dedicated host by name. func (c *Client) GetDedicatedHostByName(ctx context.Context, name string, region string) (*vpcv1.DedicatedHost, error) { err := c.SetVPCServiceURLForRegion(ctx, region) @@ -218,10 +249,9 @@ func (c *Client) GetDNSRecordsByName(ctx context.Context, crnstr string, zoneID return records.Result, nil } -// GetDNSZoneIDByName gets the CIS zone ID from its domain name. -func (c *Client) GetDNSZoneIDByName(ctx context.Context, name string) (string, error) { - - zones, err := c.GetDNSZones(ctx) +// GetDNSZoneIDByName gets the DNS (Internal) or CIS zone ID from its domain name. +func (c *Client) GetDNSZoneIDByName(ctx context.Context, name string, publish types.PublishingStrategy) (string, error) { + zones, err := c.GetDNSZones(ctx, publish) if err != nil { return "", err } @@ -235,11 +265,66 @@ func (c *Client) GetDNSZoneIDByName(ctx context.Context, name string) (string, e return "", fmt.Errorf("DNS zone %q not found", name) } -// GetDNSZones returns all of the active DNS zones managed by CIS. -func (c *Client) GetDNSZones(ctx context.Context) ([]DNSZoneResponse, error) { +// GetDNSZones returns all of the active DNS zones managed by DNS or CIS. +func (c *Client) GetDNSZones(ctx context.Context, publish types.PublishingStrategy) ([]DNSZoneResponse, error) { _, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() + if publish == types.InternalPublishingStrategy { + return c.getDNSDNSZones(ctx) + } + return c.getCISDNSZones(ctx) +} + +func (c *Client) getDNSDNSZones(ctx context.Context) ([]DNSZoneResponse, error) { + options := c.controllerAPI.NewListResourceInstancesOptions() + options.SetResourceID(dnsServiceID) + + listResourceInstancesResponse, _, err := c.controllerAPI.ListResourceInstances(options) + if err != nil { + return nil, errors.Wrap(err, "failed to get dns instance") + } + + var allZones []DNSZoneResponse + for _, instance := range listResourceInstancesResponse.Resources { + authenticator, err := NewIamAuthenticator(c.APIKey) + if err != nil { + return nil, err + } + dnsZoneService, err := dnszonesv1.NewDnsZonesV1(&dnszonesv1.DnsZonesV1Options{ + Authenticator: authenticator, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to list DNS zones") + } + + options := dnsZoneService.NewListDnszonesOptions(*instance.GUID) + result, _, err := dnsZoneService.ListDnszones(options) + if result == nil { + return nil, err + } + + for _, zone := range result.Dnszones { + stateLower := strings.ToLower(*zone.State) + // DNS Zones can be 'pending_network_add' (without a permitted network, added during TF) + if stateLower == dnszonesv1.Dnszone_State_Active || stateLower == dnszonesv1.Dnszone_State_PendingNetworkAdd { + zoneStruct := DNSZoneResponse{ + Name: *zone.Name, + ID: *zone.ID, + InstanceID: *instance.GUID, + InstanceCRN: *instance.CRN, + InstanceName: *instance.Name, + ResourceGroupID: *instance.ResourceGroupID, + } + allZones = append(allZones, zoneStruct) + } + } + } + + return allZones, nil +} + +func (c *Client) getCISDNSZones(ctx context.Context) ([]DNSZoneResponse, error) { options := c.controllerAPI.NewListResourceInstancesOptions() options.SetResourceID(cisServiceID) @@ -275,8 +360,9 @@ func (c *Client) GetDNSZones(ctx context.Context) ([]DNSZoneResponse, error) { zoneStruct := DNSZoneResponse{ Name: *zone.Name, ID: *zone.ID, - CISInstanceCRN: *instance.CRN, - CISInstanceName: *instance.Name, + InstanceID: *instance.GUID, + InstanceCRN: *instance.CRN, + InstanceName: *instance.Name, ResourceGroupID: *instance.ResourceGroupID, } allZones = append(allZones, zoneStruct) diff --git a/pkg/asset/installconfig/ibmcloud/dns.go b/pkg/asset/installconfig/ibmcloud/dns.go index 50d46dffc7c..cde83e2c6fb 100644 --- a/pkg/asset/installconfig/ibmcloud/dns.go +++ b/pkg/asset/installconfig/ibmcloud/dns.go @@ -9,12 +9,15 @@ import ( survey "github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2/core" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) // Zone represents a DNS Zone type Zone struct { Name string - CISInstanceCRN string + ID string + InstanceCRN string ResourceGroupID string } @@ -27,7 +30,9 @@ func GetDNSZone() (*Zone, error) { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) defer cancel() - publicZones, err := client.GetDNSZones(ctx) + // IBM Cloud defaults to External (CIS) publish strategy during domain query + // TODO(cjschaef): Consider also offering Internal (DNS) based domains as well + publicZones, err := client.GetDNSZones(ctx, types.ExternalPublishingStrategy) if err != nil { return nil, errors.Wrap(err, "could not retrieve base domains") } @@ -38,10 +43,11 @@ func GetDNSZone() (*Zone, error) { var options []string var optionToZoneMap = make(map[string]*Zone, len(publicZones)) for _, zone := range publicZones { - option := fmt.Sprintf("%s (%s)", zone.Name, zone.CISInstanceName) + option := fmt.Sprintf("%s (%s)", zone.Name, zone.InstanceName) optionToZoneMap[option] = &Zone{ Name: zone.Name, - CISInstanceCRN: zone.CISInstanceCRN, + ID: zone.ID, + InstanceCRN: zone.InstanceCRN, ResourceGroupID: zone.ResourceGroupID, } options = append(options, option) diff --git a/pkg/asset/installconfig/ibmcloud/metadata.go b/pkg/asset/installconfig/ibmcloud/metadata.go index b91250cdd05..e5006f8a538 100644 --- a/pkg/asset/installconfig/ibmcloud/metadata.go +++ b/pkg/asset/installconfig/ibmcloud/metadata.go @@ -6,6 +6,8 @@ import ( "sync" "github.com/IBM/go-sdk-core/v5/core" + + "github.com/openshift/installer/pkg/types" ) // Metadata holds additional metadata for InstallConfig resources that @@ -22,11 +24,18 @@ type Metadata struct { client *Client computeSubnets map[string]Subnet controlPlaneSubnets map[string]Subnet + dnsInstance *DNSInstance mutex sync.Mutex clientMutex sync.Mutex } +// DNSInstance holds information for a DNS Services instance +type DNSInstance struct { + ID string + CRN string +} + // NewMetadata initializes a new Metadata object. func NewMetadata(baseDomain string, region string, controlPlaneSubnets []string, computeSubnets []string) *Metadata { return &Metadata{ @@ -71,14 +80,14 @@ func (m *Metadata) CISInstanceCRN(ctx context.Context) (string, error) { return "", err } - zones, err := client.GetDNSZones(ctx) + zones, err := client.GetDNSZones(ctx, types.ExternalPublishingStrategy) if err != nil { return "", err } for _, z := range zones { if z.Name == m.BaseDomain { - m.SetCISInstanceCRN(z.CISInstanceCRN) + m.SetCISInstanceCRN(z.InstanceCRN) return m.cisInstanceCRN, nil } } @@ -92,6 +101,45 @@ func (m *Metadata) SetCISInstanceCRN(crn string) { m.cisInstanceCRN = crn } +// DNSInstance returns a DNSInstance holding information about the DNS Services instance +// managing the DNS zone for the base domain. +func (m *Metadata) DNSInstance(ctx context.Context) (*DNSInstance, error) { + if m.dnsInstance != nil { + return m.dnsInstance, nil + } + + m.mutex.Lock() + defer m.mutex.Unlock() + + // Prevent multiple attempts to retrieve (set) the dnsInstance if it hasn't been set (multiple threads reach mutex concurrently) + if m.dnsInstance == nil { + client, err := m.Client() + if err != nil { + return nil, err + } + + zones, err := client.GetDNSZones(ctx, types.InternalPublishingStrategy) + if err != nil { + return nil, err + } + + for _, z := range zones { + if z.Name == m.BaseDomain { + if z.InstanceID == "" || z.InstanceCRN == "" { + return nil, fmt.Errorf("dnsInstance has unknown ID/CRN: %q - %q", z.InstanceID, z.InstanceCRN) + } + m.dnsInstance = &DNSInstance{ + ID: z.InstanceID, + CRN: z.InstanceCRN, + } + return m.dnsInstance, nil + } + } + return nil, fmt.Errorf("dnsInstance unknown due to DNS zone %q not found", m.BaseDomain) + } + return m.dnsInstance, nil +} + // ComputeSubnets gets the Subnet details for compute subnets func (m *Metadata) ComputeSubnets(ctx context.Context) (map[string]Subnet, error) { m.mutex.Lock() diff --git a/pkg/asset/installconfig/ibmcloud/mock/ibmcloudclient_generated.go b/pkg/asset/installconfig/ibmcloud/mock/ibmcloudclient_generated.go index 29fac36e6d2..035e56449ec 100644 --- a/pkg/asset/installconfig/ibmcloud/mock/ibmcloudclient_generated.go +++ b/pkg/asset/installconfig/ibmcloud/mock/ibmcloudclient_generated.go @@ -15,6 +15,7 @@ import ( vpcv1 "github.com/IBM/vpc-go-sdk/vpcv1" gomock "github.com/golang/mock/gomock" ibmcloud "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" + types "github.com/openshift/installer/pkg/types" ) // MockAPI is a mock of API interface. @@ -70,6 +71,21 @@ func (mr *MockAPIMockRecorder) GetCISInstance(ctx, crnstr interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCISInstance", reflect.TypeOf((*MockAPI)(nil).GetCISInstance), ctx, crnstr) } +// GetDNSInstance mocks base method. +func (m *MockAPI) GetDNSInstance(ctx context.Context, crnstr string) (*resourcecontrollerv2.ResourceInstance, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDNSInstance", ctx, crnstr) + ret0, _ := ret[0].(*resourcecontrollerv2.ResourceInstance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDNSInstance indicates an expected call of GetDNSInstance. +func (mr *MockAPIMockRecorder) GetDNSInstance(ctx, crnstr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDNSInstance", reflect.TypeOf((*MockAPI)(nil).GetDNSInstance), ctx, crnstr) +} + // GetDNSRecordsByName mocks base method. func (m *MockAPI) GetDNSRecordsByName(ctx context.Context, crnstr, zoneID, recordName string) ([]dnsrecordsv1.DnsrecordDetails, error) { m.ctrl.T.Helper() @@ -86,33 +102,33 @@ func (mr *MockAPIMockRecorder) GetDNSRecordsByName(ctx, crnstr, zoneID, recordNa } // GetDNSZoneIDByName mocks base method. -func (m *MockAPI) GetDNSZoneIDByName(ctx context.Context, name string) (string, error) { +func (m *MockAPI) GetDNSZoneIDByName(ctx context.Context, name string, publish types.PublishingStrategy) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDNSZoneIDByName", ctx, name) + ret := m.ctrl.Call(m, "GetDNSZoneIDByName", ctx, name, publish) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // GetDNSZoneIDByName indicates an expected call of GetDNSZoneIDByName. -func (mr *MockAPIMockRecorder) GetDNSZoneIDByName(ctx, name interface{}) *gomock.Call { +func (mr *MockAPIMockRecorder) GetDNSZoneIDByName(ctx, name, publish interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDNSZoneIDByName", reflect.TypeOf((*MockAPI)(nil).GetDNSZoneIDByName), ctx, name) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDNSZoneIDByName", reflect.TypeOf((*MockAPI)(nil).GetDNSZoneIDByName), ctx, name, publish) } // GetDNSZones mocks base method. -func (m *MockAPI) GetDNSZones(ctx context.Context) ([]ibmcloud.DNSZoneResponse, error) { +func (m *MockAPI) GetDNSZones(ctx context.Context, publish types.PublishingStrategy) ([]ibmcloud.DNSZoneResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDNSZones", ctx) + ret := m.ctrl.Call(m, "GetDNSZones", ctx, publish) ret0, _ := ret[0].([]ibmcloud.DNSZoneResponse) ret1, _ := ret[1].(error) return ret0, ret1 } // GetDNSZones indicates an expected call of GetDNSZones. -func (mr *MockAPIMockRecorder) GetDNSZones(ctx interface{}) *gomock.Call { +func (mr *MockAPIMockRecorder) GetDNSZones(ctx, publish interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDNSZones", reflect.TypeOf((*MockAPI)(nil).GetDNSZones), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDNSZones", reflect.TypeOf((*MockAPI)(nil).GetDNSZones), ctx, publish) } // GetDedicatedHostByName mocks base method. diff --git a/pkg/asset/installconfig/ibmcloud/validation.go b/pkg/asset/installconfig/ibmcloud/validation.go index 81d03a2ac3c..f4f280b25e6 100644 --- a/pkg/asset/installconfig/ibmcloud/validation.go +++ b/pkg/asset/installconfig/ibmcloud/validation.go @@ -323,9 +323,14 @@ func validateSubnetZone(client API, subnetID string, validZones sets.String, sub return allErrs } -// ValidatePreExitingPublicDNS ensure no pre-existing DNS record exists in the CIS +// ValidatePreExistingPublicDNS ensure no pre-existing DNS record exists in the CIS // DNS zone for cluster's Kubernetes API. -func ValidatePreExitingPublicDNS(client API, ic *types.InstallConfig, metadata *Metadata) error { +func ValidatePreExistingPublicDNS(client API, ic *types.InstallConfig, metadata *Metadata) error { + // If this is an internal cluster, this check is not necessary + if ic.Publish == types.InternalPublishingStrategy { + return nil + } + // Get CIS CRN crn, err := metadata.CISInstanceCRN(context.TODO()) if err != nil { @@ -333,7 +338,7 @@ func ValidatePreExitingPublicDNS(client API, ic *types.InstallConfig, metadata * } // Get CIS zone ID by name - zoneID, err := client.GetDNSZoneIDByName(context.TODO(), ic.BaseDomain) + zoneID, err := client.GetDNSZoneIDByName(context.TODO(), ic.BaseDomain, ic.Publish) if err != nil { return field.InternalError(field.NewPath("baseDomain"), err) } diff --git a/pkg/asset/installconfig/ibmcloud/validation_test.go b/pkg/asset/installconfig/ibmcloud/validation_test.go index d4db1b6dcfb..7f9f648c1d5 100644 --- a/pkg/asset/installconfig/ibmcloud/validation_test.go +++ b/pkg/asset/installconfig/ibmcloud/validation_test.go @@ -418,28 +418,38 @@ func TestValidate(t *testing.T) { } } -func TestValidatePreExitingPublicDNS(t *testing.T) { +func TestValidatePreExistingPublicDNS(t *testing.T) { cases := []struct { name string + internal bool edits editFunctions errorMsg string }{ { - name: "no pre-existing DNS records", + name: "no pre-existing External DNS records", + internal: false, errorMsg: "", }, { - name: "pre-existing DNS records", + name: "pre-existing External DNS records", + internal: false, errorMsg: `^record api\.valid-cluster-name\.valid\.base\.domain already exists in CIS zone \(valid-zone-id\) and might be in use by another cluster, please remove it to continue$`, }, { - name: "cannot get zone ID", + name: "cannot get External zone ID", + internal: false, errorMsg: `^baseDomain: Internal error$`, }, { - name: "cannot get DNS records", + name: "cannot get External DNS records", + internal: false, errorMsg: `^baseDomain: Internal error$`, }, + { + name: "no validation of Internal PublishStrategy", + internal: true, + errorMsg: "", + }, } mockCtrl := gomock.NewController(t) @@ -452,25 +462,28 @@ func TestValidatePreExitingPublicDNS(t *testing.T) { metadata := ibmcloud.NewMetadata(validBaseDomain, "us-south", nil, nil) metadata.SetCISInstanceCRN(validCISInstanceCRN) - // Mocks: no pre-existing DNS records - ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain).Return(validDNSZoneID, nil) + // Mocks: no pre-existing External DNS records + ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain, types.ExternalPublishingStrategy).Return(validDNSZoneID, nil) ibmcloudClient.EXPECT().GetDNSRecordsByName(gomock.Any(), validCISInstanceCRN, validDNSZoneID, dnsRecordName).Return(noDNSRecordsResponse, nil) - // Mocks: pre-existing DNS records - ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain).Return(validDNSZoneID, nil) + // Mocks: pre-existing External DNS records + ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain, types.ExternalPublishingStrategy).Return(validDNSZoneID, nil) ibmcloudClient.EXPECT().GetDNSRecordsByName(gomock.Any(), validCISInstanceCRN, validDNSZoneID, dnsRecordName).Return(existingDNSRecordsResponse, nil) - // Mocks: cannot get zone ID - ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain).Return("", fmt.Errorf("")) + // Mocks: cannot get External zone ID + ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain, types.ExternalPublishingStrategy).Return("", fmt.Errorf("")) - // Mocks: cannot get DNS records - ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain).Return(validDNSZoneID, nil) + // Mocks: cannot get External DNS records + ibmcloudClient.EXPECT().GetDNSZoneIDByName(gomock.Any(), validBaseDomain, types.ExternalPublishingStrategy).Return(validDNSZoneID, nil) ibmcloudClient.EXPECT().GetDNSRecordsByName(gomock.Any(), validCISInstanceCRN, validDNSZoneID, dnsRecordName).Return(nil, fmt.Errorf("")) for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { validInstallConfig := validInstallConfig() - aggregatedErrors := ibmcloud.ValidatePreExitingPublicDNS(ibmcloudClient, validInstallConfig, metadata) + if tc.internal { + validInstallConfig.Publish = types.InternalPublishingStrategy + } + aggregatedErrors := ibmcloud.ValidatePreExistingPublicDNS(ibmcloudClient, validInstallConfig, metadata) if tc.errorMsg != "" { assert.Regexp(t, tc.errorMsg, aggregatedErrors) } else { diff --git a/pkg/asset/installconfig/platformprovisioncheck.go b/pkg/asset/installconfig/platformprovisioncheck.go index 1d3dde7ba69..f0395dd515f 100644 --- a/pkg/asset/installconfig/platformprovisioncheck.go +++ b/pkg/asset/installconfig/platformprovisioncheck.go @@ -100,7 +100,7 @@ func (a *PlatformProvisionCheck) Generate(dependencies asset.Parents) error { if err != nil { return err } - err = ibmcloudconfig.ValidatePreExitingPublicDNS(client, ic.Config, ic.IBMCloud) + err = ibmcloudconfig.ValidatePreExistingPublicDNS(client, ic.Config, ic.IBMCloud) if err != nil { return err } diff --git a/pkg/asset/manifests/dns.go b/pkg/asset/manifests/dns.go index 88045fb8317..20e2bb78317 100644 --- a/pkg/asset/manifests/dns.go +++ b/pkg/asset/manifests/dns.go @@ -148,7 +148,7 @@ func (d *DNS) Generate(dependencies asset.Parents) error { return errors.Wrap(err, "failed to get IBM Cloud client") } - zoneID, err := client.GetDNSZoneIDByName(context.TODO(), installConfig.Config.BaseDomain) + zoneID, err := client.GetDNSZoneIDByName(context.TODO(), installConfig.Config.BaseDomain, installConfig.Config.Publish) if err != nil { return errors.Wrap(err, "failed to get DNS zone ID") } diff --git a/pkg/asset/manifests/infrastructure.go b/pkg/asset/manifests/infrastructure.go index 5705671ea36..3fbd9619dd5 100644 --- a/pkg/asset/manifests/infrastructure.go +++ b/pkg/asset/manifests/infrastructure.go @@ -14,6 +14,7 @@ import ( "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" gcpmanifests "github.com/openshift/installer/pkg/asset/manifests/gcp" + "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/alibabacloud" "github.com/openshift/installer/pkg/types/aws" "github.com/openshift/installer/pkg/types/azure" @@ -166,14 +167,25 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error { }) case ibmcloud.Name: config.Spec.PlatformSpec.Type = configv1.IBMCloudPlatformType - cisInstanceCRN, err := installConfig.IBMCloud.CISInstanceCRN(context.TODO()) - if err != nil { - return errors.Wrap(err, "cannot retrieve IBM Cloud Internet Services instance CRN") + var cisInstanceCRN, dnsInstanceCRN string + if installConfig.Config.Publish == types.InternalPublishingStrategy { + dnsInstance, err := installConfig.IBMCloud.DNSInstance(context.TODO()) + if err != nil { + return errors.Wrap(err, "cannot retrieve IBM DNS Services instance CRN") + } + dnsInstanceCRN = dnsInstance.CRN + } else { + crn, err := installConfig.IBMCloud.CISInstanceCRN(context.TODO()) + if err != nil { + return errors.Wrap(err, "cannot retrieve IBM Cloud Internet Services instance CRN") + } + cisInstanceCRN = crn } config.Status.PlatformStatus.IBMCloud = &configv1.IBMCloudPlatformStatus{ Location: installConfig.Config.Platform.IBMCloud.Region, ResourceGroupName: installConfig.Config.Platform.IBMCloud.ClusterResourceGroupName(clusterID.InfraID), CISInstanceCRN: cisInstanceCRN, + DNSInstanceCRN: dnsInstanceCRN, ProviderType: configv1.IBMCloudProviderTypeVPC, } case libvirt.Name: diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index c603651e194..d23fff9dfba 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -131,7 +131,7 @@ func ValidateInstallConfig(c *types.InstallConfig) field.ErrorList { if c.Publish == types.InternalPublishingStrategy { switch platformName := c.Platform.Name(); platformName { - case aws.Name, azure.Name, gcp.Name, alibabacloud.Name, powervs.Name: + case aws.Name, azure.Name, gcp.Name, alibabacloud.Name, ibmcloud.Name, powervs.Name: default: allErrs = append(allErrs, field.Invalid(field.NewPath("publish"), c.Publish, fmt.Sprintf("Internal publish strategy is not supported on %q platform", platformName))) } From 13a20a7341efc14631275264bdebe6212dd5e52a Mon Sep 17 00:00:00 2001 From: Christopher J Schaefer Date: Mon, 29 Aug 2022 08:26:35 -0500 Subject: [PATCH 2/2] IBMCloud: Add DNS Service support - vendor Update vendor packages for added IBM Cloud DNS Service support. --- .../dnszonesv1/dns_zones_v1.go | 853 ++++++++++++++++++ vendor/modules.txt | 1 + 2 files changed, 854 insertions(+) create mode 100644 vendor/github.com/IBM/networking-go-sdk/dnszonesv1/dns_zones_v1.go diff --git a/vendor/github.com/IBM/networking-go-sdk/dnszonesv1/dns_zones_v1.go b/vendor/github.com/IBM/networking-go-sdk/dnszonesv1/dns_zones_v1.go new file mode 100644 index 00000000000..976ffef228c --- /dev/null +++ b/vendor/github.com/IBM/networking-go-sdk/dnszonesv1/dns_zones_v1.go @@ -0,0 +1,853 @@ +/** + * (C) Copyright IBM Corp. 2020. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Package dnszonesv1 : Operations and models for the DnsZonesV1 service +package dnszonesv1 + +import ( + "encoding/json" + "fmt" + "github.com/IBM/go-sdk-core/v4/core" + common "github.com/IBM/networking-go-sdk/common" + "reflect" +) + +// DnsZonesV1 : DNS Zones +// +// Version: 1.0.0 +type DnsZonesV1 struct { + Service *core.BaseService +} + +// DefaultServiceURL is the default URL to make service requests to. +const DefaultServiceURL = "https://api.dns-svcs.cloud.ibm.com/v1" + +// DefaultServiceName is the default key used to find external configuration information. +const DefaultServiceName = "dns_zones" + +// DnsZonesV1Options : Service options +type DnsZonesV1Options struct { + ServiceName string + URL string + Authenticator core.Authenticator +} + +// NewDnsZonesV1UsingExternalConfig : constructs an instance of DnsZonesV1 with passed in options and external configuration. +func NewDnsZonesV1UsingExternalConfig(options *DnsZonesV1Options) (dnsZones *DnsZonesV1, err error) { + if options.ServiceName == "" { + options.ServiceName = DefaultServiceName + } + + if options.Authenticator == nil { + options.Authenticator, err = core.GetAuthenticatorFromEnvironment(options.ServiceName) + if err != nil { + return + } + } + + dnsZones, err = NewDnsZonesV1(options) + if err != nil { + return + } + + err = dnsZones.Service.ConfigureService(options.ServiceName) + if err != nil { + return + } + + if options.URL != "" { + err = dnsZones.Service.SetServiceURL(options.URL) + } + return +} + +// NewDnsZonesV1 : constructs an instance of DnsZonesV1 with passed in options. +func NewDnsZonesV1(options *DnsZonesV1Options) (service *DnsZonesV1, err error) { + serviceOptions := &core.ServiceOptions{ + URL: DefaultServiceURL, + Authenticator: options.Authenticator, + } + + baseService, err := core.NewBaseService(serviceOptions) + if err != nil { + return + } + + if options.URL != "" { + err = baseService.SetServiceURL(options.URL) + if err != nil { + return + } + } + + service = &DnsZonesV1{ + Service: baseService, + } + + return +} + +// SetServiceURL sets the service URL +func (dnsZones *DnsZonesV1) SetServiceURL(url string) error { + return dnsZones.Service.SetServiceURL(url) +} + +// ListDnszones : List DNS zones +// List the DNS zones for a given service instance. +func (dnsZones *DnsZonesV1) ListDnszones(listDnszonesOptions *ListDnszonesOptions) (result *ListDnszones, response *core.DetailedResponse, err error) { + err = core.ValidateNotNil(listDnszonesOptions, "listDnszonesOptions cannot be nil") + if err != nil { + return + } + err = core.ValidateStruct(listDnszonesOptions, "listDnszonesOptions") + if err != nil { + return + } + + pathSegments := []string{"instances", "dnszones"} + pathParameters := []string{*listDnszonesOptions.InstanceID} + + builder := core.NewRequestBuilder(core.GET) + _, err = builder.ConstructHTTPURL(dnsZones.Service.Options.URL, pathSegments, pathParameters) + if err != nil { + return + } + + for headerName, headerValue := range listDnszonesOptions.Headers { + builder.AddHeader(headerName, headerValue) + } + + sdkHeaders := common.GetSdkHeaders("dns_zones", "V1", "ListDnszones") + for headerName, headerValue := range sdkHeaders { + builder.AddHeader(headerName, headerValue) + } + builder.AddHeader("Accept", "application/json") + if listDnszonesOptions.XCorrelationID != nil { + builder.AddHeader("X-Correlation-ID", fmt.Sprint(*listDnszonesOptions.XCorrelationID)) + } + + if listDnszonesOptions.Offset != nil { + builder.AddQuery("offset", fmt.Sprint(*listDnszonesOptions.Offset)) + } + if listDnszonesOptions.Limit != nil { + builder.AddQuery("limit", fmt.Sprint(*listDnszonesOptions.Limit)) + } + if listDnszonesOptions.VpcID != nil { + builder.AddQuery("vpc_id", fmt.Sprint(*listDnszonesOptions.VpcID)) + } + + request, err := builder.Build() + if err != nil { + return + } + + var rawResponse map[string]json.RawMessage + response, err = dnsZones.Service.Request(request, &rawResponse) + if err != nil { + return + } + err = core.UnmarshalModel(rawResponse, "", &result, UnmarshalListDnszones) + if err != nil { + return + } + response.Result = result + + return +} + +// CreateDnszone : Create a DNS zone +// Create a DNS zone for a given service instance. +func (dnsZones *DnsZonesV1) CreateDnszone(createDnszoneOptions *CreateDnszoneOptions) (result *Dnszone, response *core.DetailedResponse, err error) { + err = core.ValidateNotNil(createDnszoneOptions, "createDnszoneOptions cannot be nil") + if err != nil { + return + } + err = core.ValidateStruct(createDnszoneOptions, "createDnszoneOptions") + if err != nil { + return + } + + pathSegments := []string{"instances", "dnszones"} + pathParameters := []string{*createDnszoneOptions.InstanceID} + + builder := core.NewRequestBuilder(core.POST) + _, err = builder.ConstructHTTPURL(dnsZones.Service.Options.URL, pathSegments, pathParameters) + if err != nil { + return + } + + for headerName, headerValue := range createDnszoneOptions.Headers { + builder.AddHeader(headerName, headerValue) + } + + sdkHeaders := common.GetSdkHeaders("dns_zones", "V1", "CreateDnszone") + for headerName, headerValue := range sdkHeaders { + builder.AddHeader(headerName, headerValue) + } + builder.AddHeader("Accept", "application/json") + builder.AddHeader("Content-Type", "application/json") + if createDnszoneOptions.XCorrelationID != nil { + builder.AddHeader("X-Correlation-ID", fmt.Sprint(*createDnszoneOptions.XCorrelationID)) + } + + body := make(map[string]interface{}) + if createDnszoneOptions.Name != nil { + body["name"] = createDnszoneOptions.Name + } + if createDnszoneOptions.Description != nil { + body["description"] = createDnszoneOptions.Description + } + if createDnszoneOptions.Label != nil { + body["label"] = createDnszoneOptions.Label + } + _, err = builder.SetBodyContentJSON(body) + if err != nil { + return + } + + request, err := builder.Build() + if err != nil { + return + } + + var rawResponse map[string]json.RawMessage + response, err = dnsZones.Service.Request(request, &rawResponse) + if err != nil { + return + } + err = core.UnmarshalModel(rawResponse, "", &result, UnmarshalDnszone) + if err != nil { + return + } + response.Result = result + + return +} + +// DeleteDnszone : Delete a DNS zone +// Delete a DNS zone. +func (dnsZones *DnsZonesV1) DeleteDnszone(deleteDnszoneOptions *DeleteDnszoneOptions) (response *core.DetailedResponse, err error) { + err = core.ValidateNotNil(deleteDnszoneOptions, "deleteDnszoneOptions cannot be nil") + if err != nil { + return + } + err = core.ValidateStruct(deleteDnszoneOptions, "deleteDnszoneOptions") + if err != nil { + return + } + + pathSegments := []string{"instances", "dnszones"} + pathParameters := []string{*deleteDnszoneOptions.InstanceID, *deleteDnszoneOptions.DnszoneID} + + builder := core.NewRequestBuilder(core.DELETE) + _, err = builder.ConstructHTTPURL(dnsZones.Service.Options.URL, pathSegments, pathParameters) + if err != nil { + return + } + + for headerName, headerValue := range deleteDnszoneOptions.Headers { + builder.AddHeader(headerName, headerValue) + } + + sdkHeaders := common.GetSdkHeaders("dns_zones", "V1", "DeleteDnszone") + for headerName, headerValue := range sdkHeaders { + builder.AddHeader(headerName, headerValue) + } + if deleteDnszoneOptions.XCorrelationID != nil { + builder.AddHeader("X-Correlation-ID", fmt.Sprint(*deleteDnszoneOptions.XCorrelationID)) + } + + request, err := builder.Build() + if err != nil { + return + } + + response, err = dnsZones.Service.Request(request, nil) + + return +} + +// GetDnszone : Get a DNS zone +// Get details of a DNS zone. +func (dnsZones *DnsZonesV1) GetDnszone(getDnszoneOptions *GetDnszoneOptions) (result *Dnszone, response *core.DetailedResponse, err error) { + err = core.ValidateNotNil(getDnszoneOptions, "getDnszoneOptions cannot be nil") + if err != nil { + return + } + err = core.ValidateStruct(getDnszoneOptions, "getDnszoneOptions") + if err != nil { + return + } + + pathSegments := []string{"instances", "dnszones"} + pathParameters := []string{*getDnszoneOptions.InstanceID, *getDnszoneOptions.DnszoneID} + + builder := core.NewRequestBuilder(core.GET) + _, err = builder.ConstructHTTPURL(dnsZones.Service.Options.URL, pathSegments, pathParameters) + if err != nil { + return + } + + for headerName, headerValue := range getDnszoneOptions.Headers { + builder.AddHeader(headerName, headerValue) + } + + sdkHeaders := common.GetSdkHeaders("dns_zones", "V1", "GetDnszone") + for headerName, headerValue := range sdkHeaders { + builder.AddHeader(headerName, headerValue) + } + builder.AddHeader("Accept", "application/json") + if getDnszoneOptions.XCorrelationID != nil { + builder.AddHeader("X-Correlation-ID", fmt.Sprint(*getDnszoneOptions.XCorrelationID)) + } + + request, err := builder.Build() + if err != nil { + return + } + + var rawResponse map[string]json.RawMessage + response, err = dnsZones.Service.Request(request, &rawResponse) + if err != nil { + return + } + err = core.UnmarshalModel(rawResponse, "", &result, UnmarshalDnszone) + if err != nil { + return + } + response.Result = result + + return +} + +// UpdateDnszone : Update the properties of a DNS zone +// Update the properties of a DNS zone. +func (dnsZones *DnsZonesV1) UpdateDnszone(updateDnszoneOptions *UpdateDnszoneOptions) (result *Dnszone, response *core.DetailedResponse, err error) { + err = core.ValidateNotNil(updateDnszoneOptions, "updateDnszoneOptions cannot be nil") + if err != nil { + return + } + err = core.ValidateStruct(updateDnszoneOptions, "updateDnszoneOptions") + if err != nil { + return + } + + pathSegments := []string{"instances", "dnszones"} + pathParameters := []string{*updateDnszoneOptions.InstanceID, *updateDnszoneOptions.DnszoneID} + + builder := core.NewRequestBuilder(core.PATCH) + _, err = builder.ConstructHTTPURL(dnsZones.Service.Options.URL, pathSegments, pathParameters) + if err != nil { + return + } + + for headerName, headerValue := range updateDnszoneOptions.Headers { + builder.AddHeader(headerName, headerValue) + } + + sdkHeaders := common.GetSdkHeaders("dns_zones", "V1", "UpdateDnszone") + for headerName, headerValue := range sdkHeaders { + builder.AddHeader(headerName, headerValue) + } + builder.AddHeader("Accept", "application/json") + builder.AddHeader("Content-Type", "application/json") + if updateDnszoneOptions.XCorrelationID != nil { + builder.AddHeader("X-Correlation-ID", fmt.Sprint(*updateDnszoneOptions.XCorrelationID)) + } + + body := make(map[string]interface{}) + if updateDnszoneOptions.Description != nil { + body["description"] = updateDnszoneOptions.Description + } + if updateDnszoneOptions.Label != nil { + body["label"] = updateDnszoneOptions.Label + } + _, err = builder.SetBodyContentJSON(body) + if err != nil { + return + } + + request, err := builder.Build() + if err != nil { + return + } + + var rawResponse map[string]json.RawMessage + response, err = dnsZones.Service.Request(request, &rawResponse) + if err != nil { + return + } + err = core.UnmarshalModel(rawResponse, "", &result, UnmarshalDnszone) + if err != nil { + return + } + response.Result = result + + return +} + +// CreateDnszoneOptions : The CreateDnszone options. +type CreateDnszoneOptions struct { + // The unique identifier of a service instance. + InstanceID *string `json:"instance_id" validate:"required"` + + // Name of DNS zone. + Name *string `json:"name,omitempty"` + + // The text describing the purpose of a DNS zone. + Description *string `json:"description,omitempty"` + + // The label of a DNS zone. + Label *string `json:"label,omitempty"` + + // Uniquely identifying a request. + XCorrelationID *string `json:"X-Correlation-ID,omitempty"` + + // Allows users to set headers on API requests + Headers map[string]string +} + +// NewCreateDnszoneOptions : Instantiate CreateDnszoneOptions +func (*DnsZonesV1) NewCreateDnszoneOptions(instanceID string) *CreateDnszoneOptions { + return &CreateDnszoneOptions{ + InstanceID: core.StringPtr(instanceID), + } +} + +// SetInstanceID : Allow user to set InstanceID +func (options *CreateDnszoneOptions) SetInstanceID(instanceID string) *CreateDnszoneOptions { + options.InstanceID = core.StringPtr(instanceID) + return options +} + +// SetName : Allow user to set Name +func (options *CreateDnszoneOptions) SetName(name string) *CreateDnszoneOptions { + options.Name = core.StringPtr(name) + return options +} + +// SetDescription : Allow user to set Description +func (options *CreateDnszoneOptions) SetDescription(description string) *CreateDnszoneOptions { + options.Description = core.StringPtr(description) + return options +} + +// SetLabel : Allow user to set Label +func (options *CreateDnszoneOptions) SetLabel(label string) *CreateDnszoneOptions { + options.Label = core.StringPtr(label) + return options +} + +// SetXCorrelationID : Allow user to set XCorrelationID +func (options *CreateDnszoneOptions) SetXCorrelationID(xCorrelationID string) *CreateDnszoneOptions { + options.XCorrelationID = core.StringPtr(xCorrelationID) + return options +} + +// SetHeaders : Allow user to set Headers +func (options *CreateDnszoneOptions) SetHeaders(param map[string]string) *CreateDnszoneOptions { + options.Headers = param + return options +} + +// DeleteDnszoneOptions : The DeleteDnszone options. +type DeleteDnszoneOptions struct { + // The unique identifier of a service instance. + InstanceID *string `json:"instance_id" validate:"required"` + + // The unique identifier of a DNS zone. + DnszoneID *string `json:"dnszone_id" validate:"required"` + + // Uniquely identifying a request. + XCorrelationID *string `json:"X-Correlation-ID,omitempty"` + + // Allows users to set headers on API requests + Headers map[string]string +} + +// NewDeleteDnszoneOptions : Instantiate DeleteDnszoneOptions +func (*DnsZonesV1) NewDeleteDnszoneOptions(instanceID string, dnszoneID string) *DeleteDnszoneOptions { + return &DeleteDnszoneOptions{ + InstanceID: core.StringPtr(instanceID), + DnszoneID: core.StringPtr(dnszoneID), + } +} + +// SetInstanceID : Allow user to set InstanceID +func (options *DeleteDnszoneOptions) SetInstanceID(instanceID string) *DeleteDnszoneOptions { + options.InstanceID = core.StringPtr(instanceID) + return options +} + +// SetDnszoneID : Allow user to set DnszoneID +func (options *DeleteDnszoneOptions) SetDnszoneID(dnszoneID string) *DeleteDnszoneOptions { + options.DnszoneID = core.StringPtr(dnszoneID) + return options +} + +// SetXCorrelationID : Allow user to set XCorrelationID +func (options *DeleteDnszoneOptions) SetXCorrelationID(xCorrelationID string) *DeleteDnszoneOptions { + options.XCorrelationID = core.StringPtr(xCorrelationID) + return options +} + +// SetHeaders : Allow user to set Headers +func (options *DeleteDnszoneOptions) SetHeaders(param map[string]string) *DeleteDnszoneOptions { + options.Headers = param + return options +} + +// GetDnszoneOptions : The GetDnszone options. +type GetDnszoneOptions struct { + // The unique identifier of a service instance. + InstanceID *string `json:"instance_id" validate:"required"` + + // The unique identifier of a DNS zone. + DnszoneID *string `json:"dnszone_id" validate:"required"` + + // Uniquely identifying a request. + XCorrelationID *string `json:"X-Correlation-ID,omitempty"` + + // Allows users to set headers on API requests + Headers map[string]string +} + +// NewGetDnszoneOptions : Instantiate GetDnszoneOptions +func (*DnsZonesV1) NewGetDnszoneOptions(instanceID string, dnszoneID string) *GetDnszoneOptions { + return &GetDnszoneOptions{ + InstanceID: core.StringPtr(instanceID), + DnszoneID: core.StringPtr(dnszoneID), + } +} + +// SetInstanceID : Allow user to set InstanceID +func (options *GetDnszoneOptions) SetInstanceID(instanceID string) *GetDnszoneOptions { + options.InstanceID = core.StringPtr(instanceID) + return options +} + +// SetDnszoneID : Allow user to set DnszoneID +func (options *GetDnszoneOptions) SetDnszoneID(dnszoneID string) *GetDnszoneOptions { + options.DnszoneID = core.StringPtr(dnszoneID) + return options +} + +// SetXCorrelationID : Allow user to set XCorrelationID +func (options *GetDnszoneOptions) SetXCorrelationID(xCorrelationID string) *GetDnszoneOptions { + options.XCorrelationID = core.StringPtr(xCorrelationID) + return options +} + +// SetHeaders : Allow user to set Headers +func (options *GetDnszoneOptions) SetHeaders(param map[string]string) *GetDnszoneOptions { + options.Headers = param + return options +} + +// ListDnszonesOptions : The ListDnszones options. +type ListDnszonesOptions struct { + // The unique identifier of a service instance. + InstanceID *string `json:"instance_id" validate:"required"` + + // Uniquely identifying a request. + XCorrelationID *string `json:"X-Correlation-ID,omitempty"` + + // Specify how many DNS zones to skip over, the default value is 0. + Offset *int64 `json:"offset,omitempty"` + + // Specify how many DNS zones are returned, the default value is 10. + Limit *int64 `json:"limit,omitempty"` + + // Specify the VPC instance id. + VpcID *string `json:"vpc_id,omitempty"` + + // Allows users to set headers on API requests + Headers map[string]string +} + +// NewListDnszonesOptions : Instantiate ListDnszonesOptions +func (*DnsZonesV1) NewListDnszonesOptions(instanceID string) *ListDnszonesOptions { + return &ListDnszonesOptions{ + InstanceID: core.StringPtr(instanceID), + } +} + +// SetInstanceID : Allow user to set InstanceID +func (options *ListDnszonesOptions) SetInstanceID(instanceID string) *ListDnszonesOptions { + options.InstanceID = core.StringPtr(instanceID) + return options +} + +// SetXCorrelationID : Allow user to set XCorrelationID +func (options *ListDnszonesOptions) SetXCorrelationID(xCorrelationID string) *ListDnszonesOptions { + options.XCorrelationID = core.StringPtr(xCorrelationID) + return options +} + +// SetOffset : Allow user to set Offset +func (options *ListDnszonesOptions) SetOffset(offset int64) *ListDnszonesOptions { + options.Offset = core.Int64Ptr(offset) + return options +} + +// SetLimit : Allow user to set Limit +func (options *ListDnszonesOptions) SetLimit(limit int64) *ListDnszonesOptions { + options.Limit = core.Int64Ptr(limit) + return options +} + +// SetVpcID : Allow user to set VpcID +func (options *ListDnszonesOptions) SetVpcID(vpcID string) *ListDnszonesOptions { + options.VpcID = core.StringPtr(vpcID) + return options +} + +// SetHeaders : Allow user to set Headers +func (options *ListDnszonesOptions) SetHeaders(param map[string]string) *ListDnszonesOptions { + options.Headers = param + return options +} + +// UpdateDnszoneOptions : The UpdateDnszone options. +type UpdateDnszoneOptions struct { + // The unique identifier of a service instance. + InstanceID *string `json:"instance_id" validate:"required"` + + // The unique identifier of a DNS zone. + DnszoneID *string `json:"dnszone_id" validate:"required"` + + // The text describing the purpose of a DNS zone. + Description *string `json:"description,omitempty"` + + // The label of a DNS zone. + Label *string `json:"label,omitempty"` + + // Uniquely identifying a request. + XCorrelationID *string `json:"X-Correlation-ID,omitempty"` + + // Allows users to set headers on API requests + Headers map[string]string +} + +// NewUpdateDnszoneOptions : Instantiate UpdateDnszoneOptions +func (*DnsZonesV1) NewUpdateDnszoneOptions(instanceID string, dnszoneID string) *UpdateDnszoneOptions { + return &UpdateDnszoneOptions{ + InstanceID: core.StringPtr(instanceID), + DnszoneID: core.StringPtr(dnszoneID), + } +} + +// SetInstanceID : Allow user to set InstanceID +func (options *UpdateDnszoneOptions) SetInstanceID(instanceID string) *UpdateDnszoneOptions { + options.InstanceID = core.StringPtr(instanceID) + return options +} + +// SetDnszoneID : Allow user to set DnszoneID +func (options *UpdateDnszoneOptions) SetDnszoneID(dnszoneID string) *UpdateDnszoneOptions { + options.DnszoneID = core.StringPtr(dnszoneID) + return options +} + +// SetDescription : Allow user to set Description +func (options *UpdateDnszoneOptions) SetDescription(description string) *UpdateDnszoneOptions { + options.Description = core.StringPtr(description) + return options +} + +// SetLabel : Allow user to set Label +func (options *UpdateDnszoneOptions) SetLabel(label string) *UpdateDnszoneOptions { + options.Label = core.StringPtr(label) + return options +} + +// SetXCorrelationID : Allow user to set XCorrelationID +func (options *UpdateDnszoneOptions) SetXCorrelationID(xCorrelationID string) *UpdateDnszoneOptions { + options.XCorrelationID = core.StringPtr(xCorrelationID) + return options +} + +// SetHeaders : Allow user to set Headers +func (options *UpdateDnszoneOptions) SetHeaders(param map[string]string) *UpdateDnszoneOptions { + options.Headers = param + return options +} + +// Dnszone : DNS zone details. +type Dnszone struct { + // Unique identifier of a DNS zone. + ID *string `json:"id,omitempty"` + + // the time when a DNS zone is created. + CreatedOn *string `json:"created_on,omitempty"` + + // the recent time when a DNS zone is modified. + ModifiedOn *string `json:"modified_on,omitempty"` + + // Unique identifier of a service instance. + InstanceID *string `json:"instance_id,omitempty"` + + // Name of DNS zone. + Name *string `json:"name,omitempty"` + + // The text describing the purpose of a DNS zone. + Description *string `json:"description,omitempty"` + + // State of DNS zone. + State *string `json:"state,omitempty"` + + // The label of a DNS zone. + Label *string `json:"label,omitempty"` +} + +// Constants associated with the Dnszone.State property. +// State of DNS zone. +const ( + Dnszone_State_Active = "active" + Dnszone_State_Deleted = "deleted" + Dnszone_State_Disabled = "disabled" + Dnszone_State_PendingDelete = "pending_delete" + Dnszone_State_PendingNetworkAdd = "pending_network_add" +) + + +// UnmarshalDnszone unmarshals an instance of Dnszone from the specified map of raw messages. +func UnmarshalDnszone(m map[string]json.RawMessage, result interface{}) (err error) { + obj := new(Dnszone) + err = core.UnmarshalPrimitive(m, "id", &obj.ID) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "created_on", &obj.CreatedOn) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "modified_on", &obj.ModifiedOn) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "instance_id", &obj.InstanceID) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "name", &obj.Name) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "description", &obj.Description) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "state", &obj.State) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "label", &obj.Label) + if err != nil { + return + } + reflect.ValueOf(result).Elem().Set(reflect.ValueOf(obj)) + return +} + +// FirstHref : href. +type FirstHref struct { + // href. + Href *string `json:"href,omitempty"` +} + + +// UnmarshalFirstHref unmarshals an instance of FirstHref from the specified map of raw messages. +func UnmarshalFirstHref(m map[string]json.RawMessage, result interface{}) (err error) { + obj := new(FirstHref) + err = core.UnmarshalPrimitive(m, "href", &obj.Href) + if err != nil { + return + } + reflect.ValueOf(result).Elem().Set(reflect.ValueOf(obj)) + return +} + +// ListDnszones : List DNS zones response. +type ListDnszones struct { + // An array of DNS zones. + Dnszones []Dnszone `json:"dnszones" validate:"required"` + + // Specify how many DNS zones to skip over, the default value is 0. + Offset *int64 `json:"offset" validate:"required"` + + // Specify how many DNS zones are returned, the default value is 10. + Limit *int64 `json:"limit" validate:"required"` + + // Total number of DNS zones. + TotalCount *int64 `json:"total_count" validate:"required"` + + // href. + First *FirstHref `json:"first" validate:"required"` + + // href. + Next *NextHref `json:"next,omitempty"` +} + + +// UnmarshalListDnszones unmarshals an instance of ListDnszones from the specified map of raw messages. +func UnmarshalListDnszones(m map[string]json.RawMessage, result interface{}) (err error) { + obj := new(ListDnszones) + err = core.UnmarshalModel(m, "dnszones", &obj.Dnszones, UnmarshalDnszone) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "offset", &obj.Offset) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "limit", &obj.Limit) + if err != nil { + return + } + err = core.UnmarshalPrimitive(m, "total_count", &obj.TotalCount) + if err != nil { + return + } + err = core.UnmarshalModel(m, "first", &obj.First, UnmarshalFirstHref) + if err != nil { + return + } + err = core.UnmarshalModel(m, "next", &obj.Next, UnmarshalNextHref) + if err != nil { + return + } + reflect.ValueOf(result).Elem().Set(reflect.ValueOf(obj)) + return +} + +// NextHref : href. +type NextHref struct { + // href. + Href *string `json:"href,omitempty"` +} + + +// UnmarshalNextHref unmarshals an instance of NextHref from the specified map of raw messages. +func UnmarshalNextHref(m map[string]json.RawMessage, result interface{}) (err error) { + obj := new(NextHref) + err = core.UnmarshalPrimitive(m, "href", &obj.Href) + if err != nil { + return + } + reflect.ValueOf(result).Elem().Set(reflect.ValueOf(obj)) + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 4ed1d902b6d..1fd81baf29f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -151,6 +151,7 @@ github.com/IBM/go-sdk-core/v5/core ## explicit; go 1.14 github.com/IBM/networking-go-sdk/common github.com/IBM/networking-go-sdk/dnsrecordsv1 +github.com/IBM/networking-go-sdk/dnszonesv1 github.com/IBM/networking-go-sdk/zonesv1 # github.com/IBM/platform-services-go-sdk v0.18.16 ## explicit; go 1.12