feat(datasource/metadata): Add datasource for CloudSigma
This commit is contained in:
141
datasource/metadata/cloudsigma/server_context.go
Normal file
141
datasource/metadata/cloudsigma/server_context.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package cloudsigma
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/cloudsigma/cepgo"
|
||||
)
|
||||
|
||||
const (
|
||||
userDataFieldName = "cloudinit-user-data"
|
||||
)
|
||||
|
||||
type serverContextService struct {
|
||||
client interface {
|
||||
All() (interface{}, error)
|
||||
Key(string) (interface{}, error)
|
||||
Meta() (map[string]string, error)
|
||||
FetchRaw(string) ([]byte, error)
|
||||
}
|
||||
}
|
||||
|
||||
func NewServerContextService() *serverContextService {
|
||||
return &serverContextService{
|
||||
client: cepgo.NewCepgo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (_ *serverContextService) IsAvailable() bool {
|
||||
productNameFile, err := os.Open("/sys/class/dmi/id/product_name")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
productName := make([]byte, 10)
|
||||
_, err = productNameFile.Read(productName)
|
||||
return err == nil && string(productName) == "CloudSigma"
|
||||
}
|
||||
|
||||
func (_ *serverContextService) AvailabilityChanges() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (_ *serverContextService) ConfigRoot() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *serverContextService) Type() string {
|
||||
return "server-context"
|
||||
}
|
||||
|
||||
func (scs *serverContextService) FetchMetadata() ([]byte, error) {
|
||||
var (
|
||||
inputMetadata struct {
|
||||
Name string `json:"name"`
|
||||
UUID string `json:"uuid"`
|
||||
Meta map[string]string `json:"meta"`
|
||||
Nics []struct {
|
||||
Runtime struct {
|
||||
InterfaceType string `json:"interface_type"`
|
||||
IPv4 struct {
|
||||
IP string `json:"uuid"`
|
||||
} `json:"ip_v4"`
|
||||
} `json:"runtime"`
|
||||
} `json:"nics"`
|
||||
}
|
||||
outputMetadata struct {
|
||||
Hostname string `json:"name"`
|
||||
PublicKeys map[string]string `json:"public_keys"`
|
||||
LocalIPv4 string `json:"local-ipv4"`
|
||||
PublicIPv4 string `json:"public-ipv4"`
|
||||
}
|
||||
)
|
||||
|
||||
rawMetadata, err := scs.client.FetchRaw("")
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(rawMetadata, &inputMetadata)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
if inputMetadata.Name != "" {
|
||||
outputMetadata.Hostname = inputMetadata.Name
|
||||
} else {
|
||||
outputMetadata.Hostname = inputMetadata.UUID
|
||||
}
|
||||
|
||||
if key, ok := inputMetadata.Meta["ssh_public_key"]; ok {
|
||||
splitted := strings.Split(key, " ")
|
||||
outputMetadata.PublicKeys = make(map[string]string)
|
||||
outputMetadata.PublicKeys[splitted[len(splitted)-1]] = key
|
||||
}
|
||||
|
||||
for _, nic := range inputMetadata.Nics {
|
||||
if nic.Runtime.IPv4.IP != "" {
|
||||
if nic.Runtime.InterfaceType == "public" {
|
||||
outputMetadata.PublicIPv4 = nic.Runtime.IPv4.IP
|
||||
} else {
|
||||
outputMetadata.LocalIPv4 = nic.Runtime.IPv4.IP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(outputMetadata)
|
||||
}
|
||||
|
||||
func (scs *serverContextService) FetchUserdata() ([]byte, error) {
|
||||
metadata, err := scs.client.Meta()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
userData, ok := metadata[userDataFieldName]
|
||||
if ok && isBase64Encoded(userDataFieldName, metadata) {
|
||||
if decodedUserData, err := base64.StdEncoding.DecodeString(userData); err == nil {
|
||||
return decodedUserData, nil
|
||||
} else {
|
||||
return []byte{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return []byte(userData), nil
|
||||
}
|
||||
|
||||
func isBase64Encoded(field string, userdata map[string]string) bool {
|
||||
base64Fields, ok := userdata["base64_fields"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, base64Field := range strings.Split(base64Fields, ",") {
|
||||
if field == base64Field {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Reference in New Issue
Block a user