Giter Site home page Giter Site logo

gsclient-go's Introduction

gridscale Go Client Library

GitHub tag (latest SemVer) PkgGoDev gsclient-go status

This is a client for the gridscale API. It can be used to make an application interact with the gridscale cloud platform to create and manage resources.

Prerequisites

To be able to use this client a number of steps need to be taken. First a gridscale account will be required, which can be created here. Then an API-token should be created.

Installation

First the Go programming language will need to be installed. This can be done by using the official Go installation guide or by using the packages provided by your distribution.

Downloading the gridscale Go client can be done with the following go command:

$ go get github.com/gridscale/gsclient-go/v3

Using the Client

To be able to use the gridscale Go client in an application it can be imported in a go file. This can be done with the following code:

import "github.com/gridscale/gsclient-go/v3"

To get access to the functions of the Go client, a Client type needs to be created. This requires a Config type. Both of these can be created with the following code:

//Using default config
config := gsclient.DefaultConfiguration("User-UUID", "API-token")

//OR Custom config
config := gsclient.NewConfiguration(
            "API-URL",
            "User-UUID",
            "API-token",
            false, //Set debug mode
            true, //Set sync mode
            500, //Delay (in milliseconds) between requests (or retry 503 error code)
            100, //Maximum number of retries when server returns 503 error code
        )
client := gsclient.NewClient(config)

To trace the duration of individual client calls, set logger to Trace level via gsclient.SetLogLevel() function. Other log levels: https://github.com/sirupsen/logrus#level-logging

gsclient.SetLogLevel(logrus.TraceLevel)

Trace message looks like following:

TRAC[2021-03-12T10:32:43+01:00] Successful method="github.com/gridscale/gsclient-go/v3.(*Client).GetServer" requestUUID=035fc625-199d-41da-93c4-f32502d101c1 timeMs=350

Make sure to replace the user-UUID and API-token strings with valid credentials or variables containing valid credentials. It is recommended to use environment variables for them.

Using API endpoints

***Note: context has to be passed to all APIs of gsclient-go as the first parameter. In case you want to set timeout for a specific operation, you can pass a context with timeout (via context.WithTimeout or context.WithDeadline)

After having created a Client type, as shown above, it will be possible to interact with the API. An example would be the Servers Get endpoint:

ctx := context.Background()
servers := client.GetServerList(ctx)

For creating and updating/patching objects in gridscale, it will be required to use the respective CreateRequest and UpdateRequest types. For creating an IP that would be IPCreateRequest and IPUpdateRequest. Here an example:

ctx := context.Background()
requestBody := gsclient.IPCreateRequest{
    Name:       "IPTest",
    Family:     gsclient.IPv6Type,
    Failover:   false,
    ReverseDNS: "my-reverse-dns-entry.tld",
    Labels:     []string{"MyLabel"},
}

client.CreateIP(ctx, requestBody)

For updating/scaling server resources you could use:

myServerUuid := "[Server UUID]"
backgroundContext := context.Background()

// No hotplug available for scaling resources down, shutdown server first via ACPI
shutdownErr := client.ShutdownServer(backgroundContext, myServerUuid)
if shutdownErr != nil{
    log.Error("Shutdown server failed", shutdownErr)
    return
}

// Update servers resources
requestBody := gsclient.ServerUpdateRequest{
    Memory:          12,
    Cores:           4,
}

updateErr := client.UpdateServer(backgroundContext, myServerUuid, requestBody)
if updateErr != nil{
    log.Error("Serverupdate failed", updateErr)
    return
}

// Start server again
poweronErr := client.StartServer(backgroundContext, myServerUuid)
if poweronErr != nil{
    log.Error("Start server failed", poweronErr)
    return
}

What options are available for each create and update request can be found in the source code. After installing it should be located in $GOPATH/src/github.com/gridscale/gsclient-go.

Examples

Examples on how to use each resource can be found in the examples folder:

  • Firewall (firewall.go)
  • IP (ip.go)
  • ISO-image (isoimage.go)
  • Loadbalancer (loadbalancer.go)
  • Network (network.go)
  • Object Storage (objectstorage.go)
  • PaaS service (paas.go)
  • Server (server.go)
  • Storage (storage.go)
  • Storage snapshot (snapshot.go)
  • Storage snapshot schedule (snapshotschedule.go)
  • SSH-key (sshkey.go)
  • Template (template.go)

Implemented API Endpoints

Not all endpoints have been implemented in this client, but new ones will be added in the future. Here is the current list of implemented endpoints and their respective function written like endpoint (function):

  • Servers
    • Servers Get (GetServerList)
    • Server Get (GetServer)
    • Server Create (CreateServer)
    • Server Patch (UpdateServer)
    • Server Delete (DeleteServer)
    • Server Events Get (GetServerEventList)
    • Server Metrics Get (GetServerMetricList)
    • ACPI Shutdown (ShutdownServer) NOTE: ShutdownServer() will not run StopServer() when it fails to shutdown a server
    • Server On/Off (StartServer, StopServer)
    • Server's Storages Get (GetServerStorageList)
    • Server's Storage Get (GetServerStorage)
    • Server's Storage Create (CreateServerStorage)
    • Server's Storage Update (UpdateServerStorage)
    • Server's Storage Delete (DeleteServerStorage)
    • Link Storage (LinkStorage)
    • Unlink Storage (UnlinkStorage)
    • Server's Networks Get (GetServerNetworkList)
    • Server's Network Get (GetServerNetwork)
    • Server's Network Create (CreateServerNetwork)
    • Server's Network Update (UpdateServerNetwork)
    • Server's Network Delete (DeleteServerNetwork)
    • Link Network (LinkNetwork)
    • Unlink Network (UnlinkNetwork)
    • Server's IPs Get (GetServerNetworkList)
    • Server's IP Get (GetServerNetwork)
    • Server's IP Create (CreateServerNetwork)
    • Server's IP Update (UpdateServerNetwork)
    • Server's IP Delete (DeleteServerNetwork)
    • Link IP (LinkIP)
    • Unlink IP (UnlinkIP)
    • Server's ISO images Get (GetServerIsoImageList)
    • Server's ISO image Get (GetServerIsoImage)
    • Server's ISO image Create (CreateServerIsoImage)
    • Server's ISO image Update (UpdateServerIsoImage)
    • Server's ISO image Delete (DeleteServerIsoImage)
    • Link ISO image (LinkIsoimage)
    • Unlink ISO image (UnlinkIsoimage)
  • Storages
    • Storages Get (GetStorageList)
    • Storage Get (GetStorage)
    • Storage Create (CreateStorage)
    • Storage Create From A Backup (CreateStorageFromBackup)
    • Storage Clone (CloneStorage)
    • Storage Patch (UpdateStorage)
    • Storage Delete (DeleteStorage)
    • Storage's events Get (GetStorageEventList)
  • Networks
    • Networks Get (GetNetworkList)
    • Network Get (GetNetwork)
    • Network Create (CreateNetwork)
    • Network Patch (UpdateNetwork)
    • Network Delete (DeleteNetwork)
    • Network Events Get (GetNetworkEventList)
    • (GetNetworkPublic) No official endpoint, but gives the Public Network
  • Load balancers
    • LoadBalancers Get (GetLoadBalancerList)
    • LoadBalancer Get (GetLoadBalancer)
    • LoadBalancer Create (CreateLoadBalancer)
    • LoadBalancer Patch (UpdateLoadBalancer)
    • LoadBalancer Delete (DeleteLoadBalancer)
    • LoadBalancerEvents Get (GetLoadBalancerEventList)
  • IPs
    • IPs Get (GetIPList)
    • IP Get (GetIP)
    • IP Create (CreateIP)
    • IP Patch (UpdateIP)
    • IP Delete (DeleteIP)
    • IP Events Get (GetIPEventList)
    • IP Version Get (GetIPVersion)
  • SSH-Keys
    • SSH-Keys Get (GetSshkeyList)
    • SSH-Key Get (GetSshkey)
    • SSH-Key Create (CreateSshkey)
    • SSH-Key Patch (UpdateSshkey)
    • SSH-Key Delete (DeleteSshkey)
    • SSH-Key's events Get (GetSshkeyEventList)
  • Template
    • Templates Get (GetTemplateList)
    • Template Get (GetTemplate)
    • (GetTemplateByName) No official endpoint, but gives a template which matches the exact name given.
    • Template Create (CreateTemplate)
    • Template Update (UpdateTemplate)
    • Template Delete (DeleteTemplate)
    • Template's events Get (GetTemplateEventList)
  • PaaS
    • PaaS services Get (GetPaaSServiceList)
    • PaaS service Get (GetPaaSService)
    • PaaS service Create (CreatePaaSService)
    • PaaS service Update (UpdatePaaSService)
    • PaaS service Delete (DeletePaaSService)
    • PaaS service metrics Get (GetPaaSServiceMetrics)
    • PaaS service templates Get (GetPaaSTemplateList)
    • PaaS service security zones Get (GetPaaSSecurityZoneList)
    • Paas service security zone Get (GetPaaSSecurityZone)
    • PaaS service security zone Create (CreatePaaSSecurityZone)
    • PaaS service security zone Update (UpdatePaaSSecurityZone)
    • PaaS service security zone Delete (DeletePaaSSecurityZone)
  • ISO Image
    • ISO Images Get (GetISOImageList)
    • ISO Image Get (GetISOImage)
    • ISO Image Create (CreateISOImage)
    • ISO Image Update (UpdateISOImage)
    • ISO Image Delete (DeleteISOImage)
    • ISO Image Events Get (GetISOImageEventList)
  • Object Storage
    • Object Storage's Access Keys Get (GetObjectStorageAccessKeyList)
    • Object Storage's Access Key Get (GetObjectStorageAccessKey)
    • Object Storage's Access Key Create (CreateObjectStorageAccessKey)
    • Object Storage's Access Key Delete (DeleteObjectStorageAccessKey)
    • Object Storage's Buckets Get (GetObjectStorageBucketList)
  • Storage Snapshot Scheduler
    • Storage Snapshot Schedules Get (GetStorageSnapshotScheduleList)
    • Storage Snapshot Schedule Get (GetStorageSnapshotSchedule)
    • Storage Snapshot Schedule Create (CreateStorageSnapshotSchedule)
    • Storage Snapshot Schedule Update (UpdateStorageSnapshotSchedule)
    • Storage Snapshot Schedule Delete (DeleteStorageSnapshotSchedule)
  • Storage Snapshot
    • Storage Snapshots Get (GetStorageSnapshotList)
    • Storage Snapshot Get (GetStorageSnapshot)
    • Storage Snapshot Create (CreateStorageSnapshot)
    • Storage Snapshot Update (UpdateStorageSnapshot)
    • Storage Snapshot Delete (DeleteStorageSnapshot)
    • Storage Rollback (RollbackStorage)
    • Storage Snapshot Export to S3 (ExportStorageSnapshotToS3)
  • Storage Backup
    • Storage Backups Get (GetStorageBackupList)
    • Storage Backup Delete (DeleteStorageBackup)
    • Storage Backup Rollback (RollbackStorageBackup)
  • Storage Backup Schedule
    • Storage Backup Schedules Get (GetStorageBackupScheduleList)
    • Storage Backup Schedule Get (GetStorageBackupSchedule)
    • Storage Backup Schedule Create (CreateStorageBackupSchedule)
    • Storage Backup Schedule Update (UpdateStorageBackupSchedule)
    • Storage Backup Schedule Delete (DeleteStorageBackupSchedule)
  • Firewall
    • Firewalls Get (GetFirewallList)
    • Firewall Get (GetFirewall)
    • Firewall Create (CreateFirewall)
    • Firewall Update (UpdateFirewall)
    • Firewall Delete (DeleteFirewall)
    • Firewall Events Get (GetFirewallEventList)
  • Marketplace Application
    • Marketplace Applications Get (GetMarketplaceApplicationList)
    • Marketplace Application Get (GetMarketplaceApplication)
    • Marketplace Application Create (CreateMarketplaceApplication)
    • Marketplace Application Import (ImportMarketplaceApplication)
    • Marketplace Application Update (UpdateMarketplaceApplication)
    • Marketplace Application Delete (DeleteMarketplaceApplication)
    • Marketplace Application Events Get (GetMarketplaceApplicationEventList)
  • Event
    • Events Get (GetEventList)
  • Label
    • Labels Get (GetLabelList)
  • Location
    • Locations Get (GetLocationList)
    • Location Get (GetLocation)
    • Location IPs Get (GetIPsByLocation)
    • Location ISO Images Get (GetISOImagesByLocation)
    • Location Networks Get (GetNetworksByLocation)
    • Location Servers Get (GetServersByLocation)
    • Location Snapshots Get (GetSnapshotsByLocation)
    • Location Storages Get (GetStoragesByLocation)
    • Location Templates Get (GetTemplatesByLocation)
  • Deleted
    • Deleted IPs Get (GetDeletedIPs)
    • Deleted ISO Images Get (GetDeletedISOImages)
    • Deleted Networks Get (GetDeletedNetworks)
    • Deleted Servers Get (GetDeletedServers)
    • Deleted Snapshots Get (GetDeletedSnapshots)
    • Deleted Storages Get (GetDeletedStorages)
    • Deleted Templates Get (GetDeletedTemplates)
    • Deleted PaaS Services Get (GetDeletedPaaSServices)
  • SSL certificate
    • SSL certificates Get (GetSSLCertificateList)
    • SSL certificate Get (GetSSLCertificate)
    • SSL certificate Create (CreateSSLCertificate)
    • SSL certificate Delete (DeleteSSLCertificate)

Note: The functions in this list can be called with a Client type.

gsclient-go's People

Contributors

berwaluk avatar bkircher avatar dependabot[bot] avatar fkr avatar itakouna avatar marcharriss avatar nikstuckenbrock avatar nvthongswansea avatar rockkeeper avatar sharkwouter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gsclient-go's Issues

Is a CLI client planned?

Hi there!

Is a CLI client planned, similar to how Azure CLi and so on work?

I ask since I would be interested in such a tool and would maybe like to contribute if you created this one open source.

Please excuse me asking this on the Go Client. I just figured the Go client would be a great starting point for a CLI tool ๐Ÿ˜‰

Obfuscate user ID and API token used in debug mode

When printing debug output with gsclient-go, it prints out all headers including API token and user ID. Alas, this is not incorrect it is also not necessary.

Proposal: Obfuscate the output, so that only the first 6 characters are printed and the rest is omitted (indicated by ellipses or something).

This would allow users to just copy and paste their debug output into pastebin or whatever without accidentally publishing credentials. At the same time, it allows users to verify that the credentials are the expected ones when comparing.

Example: create a new client with debugMode set to true. Then do a simple API call. It will print something like

DEBU[2021-02-15T14:48:01+01:00] Request headers: map[Content-Type:[application/json] User-Agent:[gsclient-go/3.3.2 (darwin)] X-Auth-Token:[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] X-Auth-Userid:[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]]

where the Xs are real credentials.

Allow tracing of request durations

Something that would be nice to have in gsclient-go is a way to easily trace how long an API call needs from request โ†’ to fulfillment.

With fulfillment I mean: I'm not interested in timings for each individual API call (e.g. HTTP request โ†’ HTTP response) but rather in "create storage" โ†’ "storage created"; how long did this take?

I thought about specifying a log-level in the client configuration, e.g., TRACE (or whatever logrus is using). This log-level should only be used for tracing the individual requests and their timings. One line per API request, printed when the request has finished. Output format should be JSON so that it can be processed further easily.

Example: If log level is set to TRACE, you would see something like this on stderr:

{
  "message": "Finished request CreateStorage",
  "requestId": "d8260ce6-7439-4543-85c4-794592a34346",
  "request": "CreateStorage",
  "success": true,
  "timeMs": 3042
}

timeMs is the time in milliseconds that has elapsed. success would be false when this errors, but I would still see timeMs.

What do you guys think? @fkr @nvthongswansea

Make Q35 the default profile

When creating servers and ServerCreateRequest.ServerHardwareProfile is omitted the resulting profile is pc-i440fx-2.4 which is a weird choice for a default.

When doing the same thing in the panel, I get pc-q35-2.10 ("q35" in the API docs) which is a much saner choice. Please consider changing default profile and set it explicitly to "q35". Also update the docs for ServerCreateRequest.ServerHardwareProfile, "HardwareProfile is not set => server hardware is normal type" is really not saying anything at all.

Move away from git flow

Ditch git flow, use GitHub regular work flow. Will make releases much easier and we can automate with tools like GoReleaser.

TODO:

  • update CONTRIBUTING.md
  • update release-checklist.md
  • add goreleaser YAML
  • remote stale release branches from repository (origin/release/*)
  • remove develop branch, make master default

API addition in events payload

GET /objects/servers//events as well as GET /objects/events and all other events end-points now include an additional key "initiator" whose value is a string.

From the docs, initiator is "The user that triggered the event. Usually the user's email if the event was triggered by request of a user, otherwise a short descriptive name of the system component responsible."

Docs here: https://gridscale.io/en/api-documentation/index.html#operation/getServerEvents

Please add this to EventProperties struct.

Add storage backup location

  • Retrieve location where backups of a backup schedule are stored.
  • Set location for all backups of a backup schedule.

API addition in GET /objects/paas/service_templates

A heads up. There will be some updates to the GET /objects/paas/service_templates response.

A new release parameter will be included, and the version parameter will be modified from version="10.3" to version="10.3-gs1".

For a postgres template example, it will look like:

"9008f1f1-190e-4887-99f7-8a3e72fdd1f8": {
      "object_uuid": "9008f1f1-190e-4887-99f7-8a3e72fdd1f8",
      "release": "10.3",
      "version": "10.3-gs1",
      "name": "PostgreSQL 10.3 16GB (Gen 1)",

Current docs here: https://gridscale.io/en/api-documentation/index.html#operation/getPaasServiceTemplates

So I think we want to include that?

Fix up source code comments

Cool thing is that gsclient-go documentation coverage is quiet good. But there are some corners that could need some polishing.

Go through package and docs for public types and functions in gsclient-go and follow suggestions in this article. Also make sure every package has a dedicated doc string.

image

Add support for projects

There is no support in the API client yet that supports workflows with multiple projects in gridscale. I suppose, new objects are always added to the first project (named 'default').

Also, current gridscale API Specification (1.0.3) doesn't expose projects yet. So this would be needed first.

Remove CurrentPrice from properties

CurrentPrice (current_price in the API) is deprecated in the public API. We should remove this field from all property structs when we bump the major version.

Add a way to set HTTP headers

Searching for a way to conveniently overwrite existing or add new HTTP headers to requests.

Right now I can create a new config.Config with config.NewConfiguration or config.DefaultConfiguration but I'm only allowed to specify URL, user id, and token. The returned config will have config.Config.userAgent set for me automatically which is just one HTTP header.

Is there a convenient way for me to specify any custom header that is made during requests?

Access location of PaaS resource

We are currently in the process of developing a Prometheus exporter to make our Gridscale cloud costs transparent. In the context of this exporter, among others, we expose the running PaaS resources as metrics by periodically scraping the Gridscale API. To be able to determine the cost of a resource, as far as I am aware, we need the products it's using via the product number and in which location it is running. Usages can be retrieved via the usage API, but, in contrast to other resource types, such as servers, PaaS resources do not seem to expose a location attribute via the API.

Is it viable to indirectly determine the location of the PaaS resource via the connected network, or is there another mechanism to retrieve this information from the API?

Switch default branch to main

We want to switch the default branch name from master to main for all gridscale Open Source projects including this repository.

This involves:

  • Switching the default branch name here on GitHub
  • Updating all references of the master branch name in GH Actions and other CI/CD pipelines and scripts
  • Giving contributors a bit of info on how to update their remotes in their local copies of the repo

Would be nice to do this coordinated and in "one go" so that contributors are not surprised by inconsistent naming or repositories not having switched yet. If you want to help out here contact @bkircher

Handle 409

Sometime resources are locked in the backend, and we have no control in the client-side. Some PATCH/DELETE requests cannot be applied to those resources, that causes 409. We should retry the requests if we get this error code.

Report request errors to gridscale

To improve stability of our services, we need to identify issues and bottlenecks first.

In the past, when encountering issues in API reliability that were temporary in nature, we have implemented retry mechanisms into gsclient-go and the gridscale-terraform-plugin where applicable to improve the stability of the overall process. Also, underlying issues have been identified and, where possible, solved accordingly.

These retry mechanisms have the side-effect that, once in place, they mask underyling issues. To improve quality for everyone, we need to make them visible again.

This can be tackled from either the client or the server-side. For the latter, the APIs would provide metrics of request success. This does not make all issues visible though. In front of the actual APIs, there is an application server. In front of that, a web server. In front of that a reverse proxy. In front of that a firewall. In front of that a router. Etc. Issues in these layers, or the rolling deployment of the APIs itself, would not be visible in API-level metrics. Instead, we want our SDKs to report errors to us - with an opt-out functionality.

gsclient-go has been selected as the first prototype - mainly, because it is used by terraform as well. Terraform, in return, makes use of higher concurrency than many other clients do and tends to trigger deficiencies in provisioning more efficiently.

The idea is to send these reports to a publically available sentry instance. Networking errors (connection reset f.e.) and provisioning errors (Storage creation error f.e.) alike. To investigate issues, I presume we need

  • X-Request-Id, if available
  • Error message/classifier
  • Accessed resource type URL (f.e. /objects/servers) for aggregation
  • Access method (GET, POST, PATCH, DELETE, etc) for aggregation
  • Time

These reports shall also be sent when the requests is retried. They shall not block the SDK and, as such, shall send reports asynchronously. Users must be able to opt-out.

What are your thoughts?

Fix handling of retry-able requests 429 and 503

A rate-limited request should be retried until the rate-limit is reset and the request is processed successfully. If the request is delayed again (due to rate-limit is reached again), keep retrying.

gsclient-go seem not to follow 301 redirects from the api

Hi, I was debugging an Issue with my code that turned out, I've missed the https protocol in the endpoint.

This

func main() {
	token := "XXXXXXXXXXXXXXXXXXXXXX"
	user := "ZZZZZZZZZZZZZZZZZZZZZZZZ"
	endpoint := "http://api.gridscale.io"
	emptyCtx := context.Background()

	// config := gsclient.DefaultConfiguration(user, token)
	config := gsclient.NewConfiguration(endpoint, user, token, true, true, 1000, 5)
	client := gsclient.NewClient(config)

	// err := apiAlive(token, user, endpoint, client)
	serverCreateRequest := gsclient.ServerCreateRequest{
		Name:   "api-tests",
		Memory: 1,
		Cores:  2,
	}
	cServer, err := client.CreateServer(emptyCtx, serverCreateRequest)
	if err != nil {
		panic(err)
	}


	fmt.Printf("%v", cServer)
	if err != nil {
		panic(err)
	}
}

results in

DEBU[2021-02-15T14:47:58+01:00] Preparing POST request sent to URL: http://api.gridscale.io/objects/servers
DEBU[2021-02-15T14:47:58+01:00] Request body: {{"name":"api-tests","memory":1,"cores":2}
}
DEBU[2021-02-15T14:47:58+01:00] Request headers: map[Content-Type:[application/json] User-Agent:[gsclient-go/3.3.2 (darwin)] X-Auth-Token:[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] X-Auth-Userid:[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]]
DEBU[2021-02-15T14:48:00+01:00] Status code: 200. Request UUID: 6e99e9a2-8c19-45d8-a416-c21e550f751d. Headers: map[Access-Control-Allow-Credentials:[true] Access-Control-Allow-Headers:[Origin, X-Requested-With, Content-Type, Accept, X-Auth-UserId, X-Auth-Token, X-Exec-Time, X-API-Version, X-Api-Client, X-API-Identity, X-Auth-ContractId] Access-Control-Allow-Methods:[GET, POST, PUT, PATCH, DELETE, OPTIONS] Access-Control-Allow-Origin:[*] Access-Control-Expose-Headers:[X-Exec-Time, X-API-Version, X-Request-Id, X-API-Identity] Cache-Control:[no-cache] Content-Length:[3708] Content-Type:[application/json] Date:[Mon, 15 Feb 2021 13:48:00 GMT] Etag:["W/e315f3cacb4e7a3a538f7a85dcb5d46f0f245264"] Ratelimit-Limit:[210] Ratelimit-Remaining:[208] Ratelimit-Reset:[1613396894217] X-Api-Identity:[2] X-Request-Id:[6e99e9a2-8c19-45d8-a416-c21e550f751d] X-Time-Provisioning:[0.547547]]
DEBU[2021-02-15T14:48:00+01:00] Response body: {"servers": {"28c1371a-cb47-498c-b852-cadbecbfda89": {"console_token": "e36965689121ac9a80aaaa8f1069edee5df7b5a9cfbaded9c5b9fe9714e9b90e1fe1d45b3923b2d7f217009e532e6bf2", "labels": [], "create_time": "2021-02-01T09:08:18Z", "change_time": "2021-02-01T09:15:14Z", "location_uuid": "45ed677b-3702-4b36-be2a-a2eab9827950", "name": "4dx-dashboard", "hardware_profile": "q35", "availability_zone": null, "memory": 2, "auto_recovery": true, "location_iata": "fra", "cores": 1, "power": true, "location_name": "de/fra", "object_uuid": "28c1371a-cb47-498c-b852-cadbecbfda89", "location_country": "de", "legacy": false, "status": "active", "relations": {"storages": [{"bus": 0, "controller": 0, "create_time": "2021-02-01T09:08:18Z", "target": 0, "bootdevice": true, "last_used_template": "fd65f8ce-e2c6-40af-8fc3-92efa0d4eecb", "lun": 0, "storage_type": "storage", "object_uuid": "79f10e8b-33b2-4973-99ce-40aa20747734", "object_name": "4dx-dashboard", "capacity": 10, "license_product_no": null}], "networks": [{"vxlan": null, "create_time": "2021-02-01T09:08:18Z", "ordering": 0, "public_net": true, "network_uuid": "23e0345d-4313-4307-b7b9-9eb666dfac43", "firewall_template_uuid": null, "bootdevice": false, "vlan": null, "l3security": [], "network_type": "network", "firewall": null, "mac": "16:40:87:d7:f8:01", "mcast": null, "object_uuid": "23e0345d-4313-4307-b7b9-9eb666dfac43", "l2security": true, "partner_uuid": "95a2980b-7012-43dd-81f2-07577cfcb9f0", "object_name": "Public Network"}], "public_ips": [{"create_time": "2021-02-01T09:08:18Z", "object_uuid": "cb47368e-723d-4b06-ac00-3967151a4fcd", "ip": "2a06:2380:0:1::4bb", "family": 6, "prefix": "2a06:2380:0:1::4bb/128"}, {"create_time": "2021-02-01T09:08:18Z", "object_uuid": "c10af4e6-4855-45cb-a56a-93ea7df51d84", "ip": "45.12.51.119", "family": 4, "prefix": "45.12.51.119/32"}], "isoimages": []}, "current_price": 99.99, "usage_in_minutes_cores": 20432, "usage_in_minutes_memory": 40864}, "e3e89eb2-963a-4f73-8090-ca5c97b74941": {"console_token": "5c8f74843e29917b3bf6d7bfe33d99f1d85360fe123062dca9c809ccfa33fe36f4ffc6bf28f714315234399babb74176", "labels": [], "create_time": "2021-01-08T23:24:30Z", "change_time": "2021-02-15T13:47:37Z", "location_uuid": "45ed677b-3702-4b36-be2a-a2eab9827950", "name": "gs-test", "hardware_profile": "q35", "availability_zone": null, "memory": 2, "auto_recovery": true, "location_iata": "fra", "cores": 1, "power": true, "location_name": "de/fra", "object_uuid": "e3e89eb2-963a-4f73-8090-ca5c97b74941", "location_country": "de", "legacy": false, "status": "active", "relations": {"storages": [{"bus": 0, "controller": 0, "create_time": "2021-01-08T23:24:30Z", "target": 0, "bootdevice": true, "last_used_template": "fd65f8ce-e2c6-40af-8fc3-92efa0d4eecb", "lun": 0, "storage_type": "storage_insane", "object_uuid": "6f826003-b32b-46ab-adc0-cccdf4698fa6", "object_name": "gs-test", "capacity": 10, "license_product_no": null}], "networks": [{"vxlan": null, "create_time": "2021-01-08T23:24:30Z", "ordering": 0, "public_net": true, "network_uuid": "23e0345d-4313-4307-b7b9-9eb666dfac43", "firewall_template_uuid": null, "bootdevice": false, "vlan": null, "l3security": [], "network_type": "network", "firewall": null, "mac": "22:cc:c9:3d:52:01", "mcast": null, "object_uuid": "23e0345d-4313-4307-b7b9-9eb666dfac43", "l2security": true, "partner_uuid": "95a2980b-7012-43dd-81f2-07577cfcb9f0", "object_name": "Public Network"}], "public_ips": [{"create_time": "2021-01-08T23:24:30Z", "object_uuid": "d0485231-935c-4ad6-9890-0010e4b35a2e", "ip": "185.201.144.29", "family": 4, "prefix": "185.201.144.29/32"}], "isoimages": []}, "current_price": 99.99, "usage_in_minutes_cores": 54140, "usage_in_minutes_memory": 108280}}}
DEBU[2021-02-15T14:48:01+01:00] Preparing GET request sent to URL: http://api.gridscale.io/requests/6e99e9a2-8c19-45d8-a416-c21e550f751d
DEBU[2021-02-15T14:48:01+01:00] Request body: {}
DEBU[2021-02-15T14:48:01+01:00] Request headers: map[Content-Type:[application/json] User-Agent:[gsclient-go/3.3.2 (darwin)] X-Auth-Token:[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] X-Auth-Userid:[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]]
DEBU[2021-02-15T14:48:02+01:00] Status code: 404. Request UUID: b9f05ddd-e0bf-4e86-9121-6a657bfb9f15. Headers: map[Access-Control-Allow-Credentials:[true] Access-Control-Allow-Headers:[Origin, X-Requested-With, Content-Type, Accept, X-Auth-UserId, X-Auth-Token, X-Exec-Time, X-API-Version, X-Api-Client, X-API-Identity, X-Auth-ContractId] Access-Control-Allow-Methods:[GET, POST, PUT, PATCH, DELETE, OPTIONS] Access-Control-Allow-Origin:[*] Access-Control-Expose-Headers:[X-Exec-Time, X-API-Version, X-Request-Id, X-API-Identity] Cache-Control:[no-cache] Content-Length:[154] Content-Type:[application/json] Date:[Mon, 15 Feb 2021 13:48:03 GMT] Etag:["W/502812e75a4eec35693a6554365702233177fd4f"] Ratelimit-Limit:[210] Ratelimit-Remaining:[207] Ratelimit-Reset:[1613396894217] Vary:[Accept] X-Api-Identity:[2] X-Request-Id:[b9f05ddd-e0bf-4e86-9121-6a657bfb9f15]]
ERRO[2021-02-15T14:48:02+01:00] Error message: {'type': 'HTTPError', 'status_code': 404, 'message': "(404, 'There is no Request for the given Request UUID.')"}. Title: 404 Code. Code: 404. Request UUID: b9f05ddd-e0bf-4e86-9121-6a657bfb9f15.
panic: Status code: 404. Error: {'type': 'HTTPError', 'status_code': 404, 'message': "(404, 'There is no Request for the given Request UUID.')"}. Request UUID: b9f05ddd-e0bf-4e86-9121-6a657bfb9f15.

Clarify layer 3 security property

Hey hey. README.md says in the Known Issues section:

* L3security isn't read in the network relation of a server.

Is this still relevant? Should we create a bug for this and actually tackle this? @nvthongswansea

Make GSTime a type definition

Don't use embedded struct for GSTime. Right now it is

type GSTime struct {
  time.Time
}

Make it

type GSTime time.Time

so that we can use type conversion.

Optional field with json tag "omitempty" should be type of pointer.

Optional field with json tag "omitempty" should be type of pointer, since the optional fields usually accepts 3 types of input: nil (omitted when the field is nil), empty (Should not be omitted. eg: "" for string, 0 for int), and not empty. E.g:
Labels []string json:"labels,omitempty"

should be

Labels *[]string json:"labels,omitempty"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.