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))) } 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