packngo
A Golang client for the Equinix Metal API. (Packet is now Equinix Metal)
Installation
To import this library into your Go project:
import "github.com/packethost/packngo"
Reference a particular version with:
go get github.com/packethost/packngo@v0.2.0
Stability and Compatibility
This repository is Maintained meaning that this software is supported by Equinix Metal and its community - available to use in production environments.
Packngo is currently provided with a major version of v0. We'll try to avoid breaking changes to this library, but they will certainly happen as we work towards a stable v1 library. See CHANGELOG.md for details on the latest additions, removals, fixes, and breaking changes.
While packngo provides an interface to most of the Equinix Metal API, the API is regularly adding new features. To request or contribute support for more API end-points or added fields, create an issue.
See SUPPORT.md for any other issues.
Usage
To authenticate to the Equinix Metal API, you must have your API token exported in env var PACKET_AUTH_TOKEN
.
This code snippet initializes Equinix Metal API client, and lists your Projects:
package main
import (
"log"
"github.com/packethost/packngo"
)
func main() {
c, err := packngo.NewClient()
if err != nil {
log.Fatal(err)
}
ps, _, err := c.Projects.List(nil)
if err != nil {
log.Fatal(err)
}
for _, p := range ps {
log.Println(p.ID, p.Name)
}
}
This library is used by the official terraform-provider-packet.
You can also learn a lot from the *_test.go
sources. Almost all out tests touch the Equinix Metal API, so you can see how auth, querying and POSTing works. For example devices_test.go.
Linked Resources
Linked resources in Get* and List* functions
The Equinix Metal API includes references to related entities for a wide selection of resource types, indicated by href
fields. The Equinix Metal API allows for these entities to be included in the API response, saving the user from making more round-trip API requests. This is useful for linked resources, e.g members of a project, devices in a project. Similarly, by excluding entities that are included by default, you can reduce the API response time and payload size.
Control of this behavior is provided through common attributes that can be used to toggle, by field name, which referenced resources will be included as values in API responses. The API exposes this feature through ?include=
and ?exclude=
query parameters which accept a comma-separated list of field names. These field names can be dotted to reference nested entities.
Most of the packngo Get
functions take references to GetOptions
parameters (or ListOptions
for List
functions). These types include an Include
and Exclude
slice that will be converted to query parameters upon request.
For example, if you want to list users in a project, you can fetch the project via Projects.Get(pid, nil)
call. The result of this call will be a Project
which has a Users []User
attribute. The items in the []User
slice only have a non-zero URL attribute, the rest of the fields will be type defaults. You can then parse the ID of the User resources and fetch them consequently.
Optionally, you can use the ListOptions struct in the project fetch call to include the Users (members
JSON tag). Then, every item in the []User
slice will have all (not only the Href
) attributes populated.
Projects.Get(pid, &packngo.ListOptions{Includes: []{'members'}})
The following is a more comprehensive illustration of Includes and Excludes.
import (
"log"
"github.com/packethost/packngo"
)
func listProjectsAndUsers(lo *packngo.ListOptions) {
c, err := packngo.NewClient()
if err != nil {
log.Fatal(err)
}
ps, _, err := c.Projects.List(lo)
if err != nil {
log.Fatal(err)
}
log.Printf("Listing for listOptions %+v\n", lo)
for _, p := range ps {
log.Printf("project resource %s has %d users", p.Name, len(p.Users))
for _, u := range p.Users {
if u.Email != "" && u.FullName != "" {
log.Printf(" user %s has email %s\n", u.FullName, u.Email)
} else {
log.Printf(" only got user link %s\n", u.URL)
}
}
}
}
func main() {
loMembers := &packngo.ListOptions{Includes: []string{"members"}}
loMembersOut := &packngo.ListOptions{Excludes: []string{"members"}}
listProjectsAndUsers(loMembers)
listProjectsAndUsers(nil)
listProjectsAndUsers(loMembersOut)
}
Deprecation and Sunset
If the Equinix Metal API returns a RFC-8594 Deprecation
or Sunset
header, packngo will log this header to stderr with any accompanied Link
headers.
Example:
WARNING: "POST /deprecate-and-sunset" reported deprecation
WARNING: "POST /deprecate-and-sunset" reported sunsetting on Sat, 1 Aug 2020 23:59:59 GMT
WARNING: See <https://api.example.com/deprecation/field-a> for deprecation details
WARNING: See <https://api.example.com/sunset/value-a> for sunset details
WARNING: See <https://api.example.com/sunset> for sunset details
WARNING: See <https://api.example.com/deprecation> for deprecation details
Contributing
See CONTIBUTING.md.