Managing BigAnimal Clusters with BigAnimal’s APIs in Go

March 04, 2022

In case you would like to review details about BigAnimal, you can take a look at a previous blog posting: “Managing BigAnimal Clusters with BigAnimal APIs ”, in which we reviewed and explained what is: 

  • DBaaS
  • BigAnimal
  • BigAnimal Cluster

We also discussed What BigAnimal is, its features and capabilities.

Why Go and BigAnimal?

A few reasons for utilizing Go together with BigAnimal are:

Go

Go, also known as Golang, is an open-source language supported by Google. It is compiled, statically typed,  and cross-platform. Designed at Google by: Robert Griesemer, Rob Pike and Ken Thompson. Even though Go is currently ranked 11th most popular, it is an upcoming language and one that a large number of programmers are interested in learning.

Some of the reasons for learning Go, and utilizing Go with BigAnimal are:

  • Commonly accepted as a first-rate language in Kubernetes
  • Easy to learn
  • Simple
  • Robust standard libraries
  • Growing community and ecosystem
  • Straightforward build process
  • Cross-platform - Compile to other Operating Systems

Prerequisites

Obtaining a Token

A BigAnimal token is created by executing the script ‘get-token.sh’ as shown below:

get-token.sh

After successfully following the instructions displayed on the console successful token that looks somewhat as below:

{
  "access_token": "<yourtoken>",
  "refresh_token": "v1.MZY5PHwcVWeDw82c5C2qkRa5U3Cenp3eD2beagy6DmQCxf7FGU9U9XczyDjWaJmboeoDYwbzgyUBt80lNINMOfk",
  "scope": "openid profile email offline_access",
  "expires_in": 86400,
  "token_type": "Bearer"
}

From the message above, we can tell how long the token will last which is listed in seconds under the “expires_in” setting.

Should there be a need to obtain more tokens the same process can be executed as many times as needed.

Creating a Cluster

Once you have all the prerequisites readily available, we can proceed to edit the “data.json” file with the desired cluster configuration:

{
  "clusterName": "DO-go-1",
  "instanceType": {
    "cpu": 2,
    "id": "azure:Standard_E2s_v3",
    "instanceType": "E2s v3",
    "ram": 16
  },
  "password": "SuperDuper123",
  "pgConfigMap": [
    [
      "max_connections",
      "100"
    ]
  ],
  "postgresType": {
    "dockerImage": "",
    "id": "epas"
  },
  "postgresVersion": "14",
  "privateNetworking": true,
  "provider": {
    "cloudProviderId": "azure"
  },
  "region": {
    "regionId": "westus2"
  },
  "replicas": 3,
  "volumeProperties": "P1",
  "volumeType": {
    "configFieldsList": [
      "secretName",
      "shareName"
    ],
    "displayName": "Azure Premium Storage",
    "id": "azurepremiumstorage",
    "storageClass": "managed-premium"
  },
  "zoneRedundantHa": true
}

The values to be configured should be:

  • Cluster Name
  • Password
  • Postgresql Type
  • Postgresql Version
  • Provider
  • Region
  • Instance Type
  • Volume Type
  • Volume Properties
  • High Availability
  • Networking
  • Confirmation of cluster creation

The next step is to edit the: “create-cluster.go” file and look for the section where you assign the token, which is on line 7. Should look similar to this:

token = "<yourtoken>"

The code to create a cluster is located inside the “create-cluster.go” file, it looks like this:

// Original work by: EnterpriseDB
// https://www.enterprisedb.com/
// Purpose : Provision BigAnimal clusters
// Author  : Doug Ortiz
// Date    : January 28, 2022
// Version : 1.0
// Copyright (c) 2020 EnterpriseDB

package main

import (
  "net/http"
  "fmt"
  "os"
  "io/ioutil"
  )

func main() {
     // Assign variables values
     // Set 'token'
     var token = "<yourtoken>"
     // URL
     var url = "https://portal.biganimal.com/api/v1/clusters"

     // Read 'data.json' BigAnimal configuration parameters file
     jsonFile, errJsonFile := os.Open("data.json")
     
     // Check for errors
     if errJsonFile != nil {
       panic(errJsonFile)
     }

     // POST API Request
     request, errorHttp := http.NewRequest("POST", url, jsonFile)
     request.Header.Set("Accept", "application/json")
     request.Header.Set("Authorization", "Bearer " + token)
     request.Header.Set("Content-Type", "application/json")

     // Perform client call
     client := &http.Client{}
     response, errorHttp := client.Do(request)
     
     // Check for errors
     if errorHttp != nil {
       panic(errorHttp)
     }

     // Close response
     defer response.Body.Close()

     // Provide status
     fmt.Println("Response Status: ", response.Status)
     respBody, _ := ioutil.ReadAll(response.Body)
     fmt.Println("Response Body: ", string(respBody))
}

The code above: 

  • Assigns the token, headers, and url to variables
  • Performs a POST request
  • Displays the status from the request, and the response data.

A few items to note:

  • The token must be assigned where the “token” variable is defined
  • Basic error handling can be improved
  • The status of the API call is displayed at the end of the code

The next step in the process is to execute the go code:

go run create-cluster.go

A successful cluster creation will provide a message that looks somewhat as below:

Response Status:  202 Accepted
Response Body:  {"pgId":"p-t98bphxfhm"}

Listing Clusters

Listing clusters is accomplished by assigning the token in the “get-clusters.go” file along with setting the filter for:

  • name
  • provider
  • pgType: Can be one of two values - epas or pg
  • pgVersion
  • sort

The code to list a cluster is located inside the “get-clusters.go” file, it looks like this:

// Original work by: EnterpriseDB
// https://www.enterprisedb.com/
// Purpose : List BigAnimal clusters
// Author  : Doug Ortiz
// Date    : January 28, 2022
// Version : 1.0
// Copyright (c) 2020 EnterpriseDB

package main

import (
  "net/http"
  "fmt"
  "io/ioutil"
  )

func main() {
     // Assign variables values
     // Set 'token'
     var token = "<yourtoken>"
     // URL
     var url = "https://portal.biganimal.com/api/v1/clusters"
     // Provide filter for cluster name, provider, postgres type, postgres version and sort by cluster name
     filter := "?name=DO-go&provider=azure&pgType=epas&pgVersion=14&sort=%2Bname"
     filteredurl := url + filter
     fmt.Println("Filter: ", filteredurl)

     // GET API Request
     request, errorHttp := http.NewRequest("GET", filteredurl, nil)
     if errorHttp != nil {
       panic(errorHttp)
     }
     request.Header.Set("Accept", "application/json")
     request.Header.Set("Authorization", "Bearer " + token)

     // Perform client call
     client := &http.Client{}
     response, errorHttp := client.Do(request)
     // Check for errors
     if errorHttp != nil {
       panic(errorHttp)
     }

     // Close response
     defer response.Body.Close()

     // Provide status
     fmt.Println("Response Status: ", response.Status)
     respBody, _ := ioutil.ReadAll(response.Body)
     fmt.Println("Response Body: ", string(respBody))
}

Similar to the previous code file, the code above:

  • Assigns the token, headers, url, and filter to variables
  • Performs a GET request
  • Displays the status from the request, and the response data.

Notice the items below in the code above:

  • The token must be assigned where the “token” variable is defined
  • The “filter” variable might need some adjusting to fit the parameters of the clusters to list. It is not needed to include: provider, pgType, pgVersion, nor the sort parameters

The execution command to list the clusters available to the current credentials is:

go run get-clusters.go

Listing clusters results:

Filter:  https://portal.biganimal.com/api/v1/clusters?name=DO-go&provider=azure&pgType=epas&pgVersion=14&sort=%2Bname
Response Status:  200 OK
Response Body:  [{"name":"DO-go-1","instance":0,"currentPrimary":"","targetPrimary":"","pvcCount":0,"jobCount":0,"licenceStatus":"","writeService":"","readService":"","phase":"Cluster creation request received","phaseReason":"","description":"","imageName":"","postgresConfig":"","maintainanceWindowNode":"","backupDestinationPath":"","backupEndpointUrl":"","instanceType":{"id":"azure:Standard_E2s_v3","ram":16,"cpu":2,"instanceType":"E2s v3","description":"","familyName":"","name":""},"pgId":"p-t98bphxfhm","pgType":{"id":"epas","name":"EDB Postgres Advanced Server","description":"","dockerImage":""},"pgVersion":{"versionId":"14","versionName":"14","description":""},"clusterLocation":{"cloudProvider":{"cloudProviderId":"azure","cloudProviderName":"Azure","description":""},"region":{"regionId":"westus2","regionName":"(US) West US 2","description":""},"k8ClusterId":"34cdcbdc-7248-5c15-89e6-d0cd627c8f2a"},"privateNetworking":true,"clusterStorageParameters":{"storageClass":"managed-premium","size":"4 Gi","autoscale":false,"paramsMap":[["secretName",""],["shareName",""]],"volumeTypeId":"azurepremiumstorage","volumePropertiesId":"P1"},"pgConfigMap":[["max_connections","100"]],"zoneRedundantHa":false,"numberOfBackups":0,"profileType":"","deleteDetails":"","replicas":3,"storageAccountName":"","createTime":{"seconds":1643307739,"nanos":684919000},"backupRetentionPeriod":"30d","allowIpRangeMap":[["0.0.0.0/0","To allow all access"]],"sourcePgId":"","orgId":"org_QsBILBa3HlGP1VQr","instanceTypeId":"azure:Standard_E2s_v3","postgresTypeId":"epas","providerId":"azure","regionId":"westus2"}]

Deleting Clusters

To delete the BigAnimal clusters, we need to update the token and the pgId in the “delete-cluster.go” code file. 

The code to delete a cluster is located inside the “delete-cluster.go” file, it looks like this:

// Original work by: EnterpriseDB
// https://www.enterprisedb.com/
// Purpose : Delete BigAnimal clusters
// Author  : Doug Ortiz
// Date    : January 28, 2022
// Version : 1.0
// Copyright (c) 2020 EnterpriseDB

package main

import (
  "net/http"
  "fmt"
  )

func main() {
     // Assign variables values
     // Set 'token'
     var token = "<yourtoken>"
     // URL, Cluster ID, and Postgres Cluster ID
     var url = "https://portal.biganimal.com/api/v1/clusters"
     pgId := "<yourbiganimalclusterid>"
     filter := "/" + pgId
     filteredurl := url + filter
     fmt.Println("Filter: ", filteredurl)

     // DELETE API Request
     request, errorHttp := http.NewRequest("DELETE", filteredurl, nil)
     if errorHttp != nil {
       panic(errorHttp)
     }
     request.Header.Set("Accept", "*/*")
     request.Header.Set("Authorization", "Bearer " + token)

     // Perform client call
     client := &http.Client{}
     response, errorHttp := client.Do(request)
     // Check for errors
     if errorHttp != nil {
       panic(errorHttp)
     }

     // Close response
     defer response.Body.Close()

     // Provide status
     fmt.Println("Successfully deleted cluster: " + pgId + " !")
}

In the delete code file, the code above:

  • Assigns the token, headers, pgId, url, and filter to variables
  • Performs a DELETE request
  • Displays the status from the request, and the response data.

Notice the items below in the code above:

  • As the other code files, the token must be assigned where the “token” variable is defined
  • The BigAnimal Cluster Id must also be assigned

The execution command to delete a cluster is:

go run delete-cluster.go

A successful cluster deletion will provide a message that looks somewhat as below:

Filter:  https://portal.biganimal.com/api/v1/clusters/p-t98bphxfhm
Successfully deleted cluster: p-t98bphxfhm !

Inspecting how it all works together

Now that we know what each code file accomplishes, we can stop and take a look at the underlying technologies and how all the pieces fall into place.

BigAnimal Cluster Management

The top block provides the BigAnimal API services to the bottom block that assembles the json and token into a message that is returned the the API call itself. It is very easy to overlook every step that occurs and while not all inclusive the diagram above does provide a deeper view at what happens behind the scenes.

Conclusion

In this blog we used Go and learned how to: 

  • Obtain a BigAnimal token
  • Create a BigAnimal cluster
  • List BigAnimal clusters
  • Delete a BigAnimal cluster

Try it out for yourself in our BigAnimal test drive environment.

See you in the next blog post!

Share this