1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
package packet
import (
"fmt"
"log"
"os"
"strings"
"github.com/packethost/packngo"
)
const baseURL = "https://api.packet.net/"
// Provider struct
type Provider struct {
userAgent string
}
// SetUserAgent setter
func (p *Provider) SetUserAgent(s string) {
p.userAgent = s
}
// Help function
func (p *Provider) Help() string {
return `Packet:
provider: "packet"
project: UUID of packet project. Required
auth_token: Packet authentication token. Required
url: Packet REST URL. Optional
address_type: "private_v4", "public_v4" or "public_v6". Defaults to "private_v4". Optional
facility: Filter for specific facility (Examples: "ewr1,ams1")
tag: Filter by tag (Examples: "tag1,tag2")
Variables can also be provided by environmental variables:
export PACKET_PROJECT for project
export PACKET_URL for url
export PACKET_AUTH_TOKEN for auth_token
`
}
// Addrs function
func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error) {
authToken := argsOrEnv(args, "auth_token", "PACKET_AUTH_TOKEN")
projectID := argsOrEnv(args, "project", "PACKET_PROJECT")
packetURL := argsOrEnv(args, "url", "PACKET_URL")
addressType := args["address_type"]
packetFacilities := args["facility"]
packetTags := args["tag"]
if addressType != "private_v4" && addressType != "public_v4" && addressType != "public_v6" {
l.Printf("[INFO] discover-packet: Address type %s is not supported. Valid values are {private_v4,public_v4,public_v6}. Falling back to 'private_v4'", addressType)
addressType = "private_v4"
}
includeFacilities := includeArgs(packetFacilities)
includeTags := includeArgs(packetTags)
c, err := client(p.userAgent, packetURL, authToken)
if err != nil {
return nil, fmt.Errorf("discover-packet: Initializing Packet client failed: %s", err)
}
var devices []packngo.Device
if projectID == "" {
return nil, fmt.Errorf("discover-packet: 'project' parameter must be provider")
}
devices, _, err = c.Devices.List(projectID, nil)
if err != nil {
return nil, fmt.Errorf("discover-packet: Fetching Packet devices failed: %s", err)
}
var addrs []string
for _, d := range devices {
if len(includeFacilities) > 0 && !Include(includeFacilities, d.Facility.Code) {
continue
}
if len(includeTags) > 0 && !Any(d.Tags, func(v string) bool { return Include(includeTags, v) }) {
continue
}
addressFamily := 4
if addressType == "public_v6" {
addressFamily = 6
}
for _, n := range d.Network {
if (n.Public == (addressType == "public_v4" || addressType == "public_v6")) && n.AddressFamily == addressFamily {
addrs = append(addrs, n.Address)
}
}
}
return addrs, nil
}
func client(useragent, url, token string) (*packngo.Client, error) {
if url == "" {
url = baseURL
}
return packngo.NewClientWithBaseURL(useragent, token, nil, url)
}
func argsOrEnv(args map[string]string, key, env string) string {
if value := args[key]; value != "" {
return value
}
return os.Getenv(env)
}
func includeArgs(s string) []string {
var include []string
for _, localstring := range strings.Split(s, ",") {
if len(localstring) > 0 {
include = append(include, localstring)
}
}
return include
}
// Index returns the first index of the target string t, or -1 if no match is found.
func Index(vs []string, t string) int {
for i, v := range vs {
if v == t {
return i
}
}
return -1
}
// Include returns true if the target string t is in the slice.
func Include(vs []string, t string) bool {
return Index(vs, t) >= 0
}
//Any returns true if one of the strings in the slice satisfies the predicate f.
func Any(vs []string, f func(string) bool) bool {
for _, v := range vs {
if f(v) {
return true
}
}
return false
}
|