diff --git a/providers/telekom.go b/providers/telekom.go index 76c2aaa..1f70293 100644 --- a/providers/telekom.go +++ b/providers/telekom.go @@ -1,61 +1,39 @@ -//Telekom Cloud OTC DNS management for the BBB autoscaler implementation -//Creation of a new OTC DNS record -//Deletion of a existing OTC DNS record -//Updating of the IP in a OTC DNS record -package otcdns +// Telekom Cloud OTC DNS management for the BBB autoscaler implementation +// Config of Telekom Cloud +// Creation of a new OTC DNS record +// Deletion of a existing OTC DNS record +// Updating of the IP in a OTC DNS record +package providers import ( "fmt" otc "github.com/opentelekomcloud/gophertelekomcloud" - otcos "github.com/opentelekomcloud/gophertelekomcloud/openstack" "github.com/opentelekomcloud/gophertelekomcloud/openstack/dns/v2/recordsets" "github.com/opentelekomcloud/gophertelekomcloud/openstack/dns/v2/zones" ) const ( - dnsRecordTypeA string = "A" + dnsRecordTypeA string = "A" dnsRecordDescription string = "BBB Autoscaler" ) -// +type Telekom struct { + Config ProviderConfig `yaml:"-"` +} + // The DNS client we use to trigger our DNS actions. -// type OtcDnsClient struct { Sc *otc.ServiceClient } -func NewDNSV2Client() (*OtcDnsClient, error) { - cloudsConfig, err := getCloud() - if err != nil { - return nil, err - } - endpointOpts := otc.EndpointOpts{ - Region: cloudsConfig.RegionName, - } - - providerClient, err := getProviderClient() - if err != nil { - return nil, err - } - - serviceClient, err := otcos.NewDNSV2(providerClient, endpointOpts) - if err != nil { - return nil, err - } - - return &OtcDnsClient{Sc: serviceClient}, nil -} - // =========================================================================== // Zones // =========================================================================== -// // Retrieves a Zone data structure by its name. // https://pkg.go.dev/github.com/opentelekomcloud/gophertelekomcloud@v0.3.2/openstack/dns/v2/zones // github.com/opentelekomcloud/gophertelekomcloud/openstack/dns/v2/zones -// func (dnsClient *OtcDnsClient) GetHostedZone(zoneName string) (*zones.Zone, error) { listOpts := zones.ListOpts{ @@ -89,8 +67,8 @@ func (dnsClient *OtcDnsClient) GetHostedZone(zoneName string) (*zones.Zone, erro // RecordSets // =========================================================================== -//Get Recordset by DNS Name -func (dnsClient *OtcDnsClient) GetARecordSet(zone *zones.Zone, dnsName string) (*recordsets.RecordSet, error) { +// Get Recordset by DNS Name +func (dnsClient *OtcDnsClient) GetARecordSet(zone *zones.Zone, dnsName string) *recordsets.RecordSet { listOpts := recordsets.ListOpts{ Type: dnsRecordTypeA, Name: dnsName, @@ -98,12 +76,14 @@ func (dnsClient *OtcDnsClient) GetARecordSet(zone *zones.Zone, dnsName string) ( allPages, err := recordsets.ListByZone(dnsClient.Sc, zone.ID, listOpts).AllPages() if err != nil { - return nil, fmt.Errorf("list records failed for dns entry %s: %s", dnsName, err) + fmt.Printf("list records failed for dns entry %s: %s", dnsName, err) + return nil } allRRs, err := recordsets.ExtractRecordSets(allPages) if err != nil { - return nil, fmt.Errorf("extract recordset failed for dns entry %s: %s", dnsName, err) + fmt.Printf("extract recordset failed for dns entry %s: %s", dnsName, err) + return nil } // Debug @@ -113,69 +93,63 @@ func (dnsClient *OtcDnsClient) GetARecordSet(zone *zones.Zone, dnsName string) ( if len(allRRs) == 1 { // We need exactly 1 recordset to operate on - return &allRRs[0], nil + return &allRRs[0] } else if len(allRRs) == 0 { // Query was successful, but no results - return nil, nil + return nil } else { // More than 1 result. - return nil, fmt.Errorf("query with %s returned %d recordsets. Expected: 1", dnsName, len(allRRs)) + fmt.Printf("query with %s returned %d recordsets. Expected: 1", dnsName, len(allRRs)) + return nil } } -// -//Create new A DNS RecordSet with DNS Name and IP -// -func (dnsClient *OtcDnsClient) CreateRecordSet (zone *zones.Zone, dnsName string, ipValue string) (*recordsets.RecordSet, error) { +// Create new A DNS RecordSet with DNS Name and IP +func (dnsClient *OtcDnsClient) CreateRecordSet(zone *zones.Zone, dnsName string, ipValue string) (*recordsets.RecordSet, error) { createOpts := recordsets.CreateOpts{ - Name: dnsName, + Name: dnsName, Description: dnsRecordDescription, - Type: dnsRecordTypeA, - Records: []string{ipValue}, - TTL: 300, + Type: dnsRecordTypeA, + Records: []string{ipValue}, + TTL: 300, } var pCreatedRecordset *recordsets.RecordSet pCreatedRecordset, err := recordsets.Create(dnsClient.Sc, zone.ID, createOpts).Extract() - if err != nil { - fmt.Printf("Error creating DNS record: %v\n", err) - return - } + if err != nil { + fmt.Printf("Error creating DNS record: %v\n", err) + return nil, err + } return pCreatedRecordset, nil } -// -//Delete a RecordSet by DNS Name -// -func (dnsClient *OtcDnsClient) DeleteRecordSet (zone *zones.Zone, dnsName string) { +// Delete a RecordSet by DNS Name +func (dnsClient *OtcDnsClient) DeleteRecordSet(zone *zones.Zone, dnsName string) error { //get DNS details - recordSet, err := dnsClient.GetARecordSet(zone.ID, dnsName) - + recordSet := dnsClient.GetARecordSet(zone, dnsName) //Call delete function err := recordsets.Delete(dnsClient.Sc, zone.ID, recordSet.ID).ExtractErr() if err != nil { - return fmt.Errorf("deletion of record with zoneId %s and recordsetId %s failed: %s", zone.ID, recordset.ID, err) + fmt.Printf("deletion of record with zoneId %s and recordsetId %s failed: %s", zone.ID, recordSet.ID, err) + return err } - return nil } -// -//Updating a RecordSet IP by DNS Name -// +// Updating a RecordSet IP by DNS Name TODO cant use the same client? func (dnsClient *OtcDnsClient) UpdateRecordSet(zone *zones.Zone, dnsName string, newIPValue string) (*recordsets.RecordSet, error) { - //get DNS details - recordSet, err := dnsClient.GetARecordSet(zone.ID, dnsName) + //get DNS details + recordSet := dnsClient.GetARecordSet(zone, dnsName) updateOpts := recordsets.UpdateOpts{ - Records: []string{newIPValue}, - } - - updatedRecordSet, err := recordsets.Update(dnsClient, zone.ID, recordSet.ID, updateOpts).Extract() - if err != nil { - fmt.Printf("Error updating DNS record: %v\n", err) - return nil, err - } - return updatedRecordSet, nil -} \ No newline at end of file + Records: []string{newIPValue}, + } + + updatedRecordSet, err := recordsets.Update(dnsClient.Sc, zone.ID, recordSet.ID, updateOpts).Extract() + if err != nil { + fmt.Printf("Error updating DNS record: %v\n", err) + return nil, err + } + return updatedRecordSet, nil +} diff --git a/providers/telekom_config.go b/providers/telekom_config.go new file mode 100644 index 0000000..6bf0525 --- /dev/null +++ b/providers/telekom_config.go @@ -0,0 +1,118 @@ +// Config of Telekom Cloud +package providers + +import ( + "encoding/json" + "fmt" + + otc "github.com/opentelekomcloud/gophertelekomcloud" + otcos "github.com/opentelekomcloud/gophertelekomcloud/openstack" +) + +const ( + envPrefix string = "OS_" + OtcProfileNameUser string = "otcuser" + OtcProfileNameAkSk string = "otcaksk" +) + +var EnvOS = otcos.NewEnv(envPrefix) + +// =========================================================================== +// Configs +// =========================================================================== + +// Creates a new DNSv2 ServiceClient. +// See also gophertelekomcloud/acceptance/clients/clients.go +func NewDNSV2ClientWithAuth(authOpts otc.AuthOptionsProvider, endpointOpts otc.EndpointOpts) (*OtcDnsClient, error) { + + providerClient, err := getProviderClientWithAccessKeyAuth(authOpts) + if err != nil { + return nil, fmt.Errorf("cannot create providerClient. %s", err) + } + + serviceClient, err := otcos.NewDNSV2(providerClient, endpointOpts) + if err != nil { + return nil, fmt.Errorf("cannot create serviceClient. %s", err) + } + + return &OtcDnsClient{Sc: serviceClient}, nil +} + +func getProviderClientWithAccessKeyAuth(authOpts otc.AuthOptionsProvider) (*otc.ProviderClient, error) { + provider, err := otcos.AuthenticatedClient(authOpts) + if err != nil { + return nil, fmt.Errorf("provider creation has failed: %s", err) + } + return provider, nil +} + +func getCloud() (*otcos.Cloud, error) { + return getCloudProfile(OtcProfileNameUser) +} + +func copyCloud(src *otcos.Cloud) (*otcos.Cloud, error) { + srcJson, err := json.Marshal(src) + if err != nil { + return nil, fmt.Errorf("error marshalling cloud: %s", err) + } + + res := new(otcos.Cloud) + if err := json.Unmarshal(srcJson, res); err != nil { + return nil, fmt.Errorf("error unmarshalling cloud: %s", err) + } + + return res, nil +} + +func getCloudProfile(otcProfileName string) (*otcos.Cloud, error) { + + cloud, err := EnvOS.Cloud(otcProfileName) + if err != nil { + return nil, fmt.Errorf("error constructing cloud configuration: %s", err) + } + + cloud, err = copyCloud(cloud) + if err != nil { + return nil, fmt.Errorf("error copying cloud: %s", err) + } + + return cloud, nil +} + +func getProviderClient() (*otc.ProviderClient, error) { + return getProviderClientProfile(OtcProfileNameUser) +} + +func getProviderClientProfile(otcProfileName string) (*otc.ProviderClient, error) { + + client, err := EnvOS.AuthenticatedClient(otcProfileName) + if err != nil { + return nil, fmt.Errorf("cloud and provider creation has failed: %s", err) + } + + return client, nil +} + +// Creates a new DNSv2 ServiceClient. +// See also gophertelekomcloud/acceptance/clients/clients.go +func NewDNSV2Client() (*OtcDnsClient, error) { + cloudsConfig, err := getCloud() + if err != nil { + return nil, err + } + endpointOpts := otc.EndpointOpts{ + Region: cloudsConfig.RegionName, + } + + providerClient, err := getProviderClient() + if err != nil { + return nil, err + } + + serviceClient, err := otcos.NewDNSV2(providerClient, endpointOpts) + if err != nil { + return nil, err + } + + return &OtcDnsClient{Sc: serviceClient}, nil +}