* Add Virtual Kubelet provider for VIC Initial virtual kubelet provider for VMware VIC. This provider currently handles creating and starting of a pod VM via the VIC portlayer and persona server. Image store handling via the VIC persona server. This provider currently requires the feature/wolfpack branch of VIC. * Added pod stop and delete. Also added node capacity. Added the ability to stop and delete pod VMs via VIC. Also retrieve node capacity information from the VCH. * Cleanup and readme file Some file clean up and added a Readme.md markdown file for the VIC provider. * Cleaned up errors, added function comments, moved operation code 1. Cleaned up error handling. Set standard for creating errors. 2. Added method prototype comments for all interface functions. 3. Moved PodCreator, PodStarter, PodStopper, and PodDeleter to a new folder. * Add mocking code and unit tests for podcache, podcreator, and podstarter Used the unit test framework used in VIC to handle assertions in the provider's unit test. Mocking code generated using OSS project mockery, which is compatible with the testify assertion framework. * Vendored packages for the VIC provider Requires feature/wolfpack branch of VIC and a few specific commit sha of projects used within VIC. * Implementation of POD Stopper and Deleter unit tests (#4) * Updated files for initial PR
194 lines
5.3 KiB
Go
194 lines
5.3 KiB
Go
package objx
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
"io/ioutil"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// MSIConvertable is an interface that defines methods for converting your
|
|
// custom types to a map[string]interface{} representation.
|
|
type MSIConvertable interface {
|
|
// MSI gets a map[string]interface{} (msi) representing the
|
|
// object.
|
|
MSI() map[string]interface{}
|
|
}
|
|
|
|
// Map provides extended functionality for working with
|
|
// untyped data, in particular map[string]interface (msi).
|
|
type Map map[string]interface{}
|
|
|
|
// Value returns the internal value instance
|
|
func (m Map) Value() *Value {
|
|
return &Value{data: m}
|
|
}
|
|
|
|
// Nil represents a nil Map.
|
|
var Nil = New(nil)
|
|
|
|
// New creates a new Map containing the map[string]interface{} in the data argument.
|
|
// If the data argument is not a map[string]interface, New attempts to call the
|
|
// MSI() method on the MSIConvertable interface to create one.
|
|
func New(data interface{}) Map {
|
|
if _, ok := data.(map[string]interface{}); !ok {
|
|
if converter, ok := data.(MSIConvertable); ok {
|
|
data = converter.MSI()
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
return Map(data.(map[string]interface{}))
|
|
}
|
|
|
|
// MSI creates a map[string]interface{} and puts it inside a new Map.
|
|
//
|
|
// The arguments follow a key, value pattern.
|
|
//
|
|
// Panics
|
|
//
|
|
// Panics if any key argument is non-string or if there are an odd number of arguments.
|
|
//
|
|
// Example
|
|
//
|
|
// To easily create Maps:
|
|
//
|
|
// m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
|
|
//
|
|
// // creates an Map equivalent to
|
|
// m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
|
|
func MSI(keyAndValuePairs ...interface{}) Map {
|
|
newMap := make(map[string]interface{})
|
|
keyAndValuePairsLen := len(keyAndValuePairs)
|
|
if keyAndValuePairsLen%2 != 0 {
|
|
panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
|
|
}
|
|
|
|
for i := 0; i < keyAndValuePairsLen; i = i + 2 {
|
|
key := keyAndValuePairs[i]
|
|
value := keyAndValuePairs[i+1]
|
|
|
|
// make sure the key is a string
|
|
keyString, keyStringOK := key.(string)
|
|
if !keyStringOK {
|
|
panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.")
|
|
}
|
|
newMap[keyString] = value
|
|
}
|
|
return New(newMap)
|
|
}
|
|
|
|
// ****** Conversion Constructors
|
|
|
|
// MustFromJSON creates a new Map containing the data specified in the
|
|
// jsonString.
|
|
//
|
|
// Panics if the JSON is invalid.
|
|
func MustFromJSON(jsonString string) Map {
|
|
o, err := FromJSON(jsonString)
|
|
if err != nil {
|
|
panic("objx: MustFromJSON failed with error: " + err.Error())
|
|
}
|
|
return o
|
|
}
|
|
|
|
// FromJSON creates a new Map containing the data specified in the
|
|
// jsonString.
|
|
//
|
|
// Returns an error if the JSON is invalid.
|
|
func FromJSON(jsonString string) (Map, error) {
|
|
var data interface{}
|
|
err := json.Unmarshal([]byte(jsonString), &data)
|
|
if err != nil {
|
|
return Nil, err
|
|
}
|
|
return New(data), nil
|
|
}
|
|
|
|
// FromBase64 creates a new Obj containing the data specified
|
|
// in the Base64 string.
|
|
//
|
|
// The string is an encoded JSON string returned by Base64
|
|
func FromBase64(base64String string) (Map, error) {
|
|
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
|
|
decoded, err := ioutil.ReadAll(decoder)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return FromJSON(string(decoded))
|
|
}
|
|
|
|
// MustFromBase64 creates a new Obj containing the data specified
|
|
// in the Base64 string and panics if there is an error.
|
|
//
|
|
// The string is an encoded JSON string returned by Base64
|
|
func MustFromBase64(base64String string) Map {
|
|
result, err := FromBase64(base64String)
|
|
if err != nil {
|
|
panic("objx: MustFromBase64 failed with error: " + err.Error())
|
|
}
|
|
return result
|
|
}
|
|
|
|
// FromSignedBase64 creates a new Obj containing the data specified
|
|
// in the Base64 string.
|
|
//
|
|
// The string is an encoded JSON string returned by SignedBase64
|
|
func FromSignedBase64(base64String, key string) (Map, error) {
|
|
parts := strings.Split(base64String, SignatureSeparator)
|
|
if len(parts) != 2 {
|
|
return nil, errors.New("objx: Signed base64 string is malformed")
|
|
}
|
|
|
|
sig := HashWithKey(parts[0], key)
|
|
if parts[1] != sig {
|
|
return nil, errors.New("objx: Signature for base64 data does not match")
|
|
}
|
|
return FromBase64(parts[0])
|
|
}
|
|
|
|
// MustFromSignedBase64 creates a new Obj containing the data specified
|
|
// in the Base64 string and panics if there is an error.
|
|
//
|
|
// The string is an encoded JSON string returned by Base64
|
|
func MustFromSignedBase64(base64String, key string) Map {
|
|
result, err := FromSignedBase64(base64String, key)
|
|
if err != nil {
|
|
panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
|
|
}
|
|
return result
|
|
}
|
|
|
|
// FromURLQuery generates a new Obj by parsing the specified
|
|
// query.
|
|
//
|
|
// For queries with multiple values, the first value is selected.
|
|
func FromURLQuery(query string) (Map, error) {
|
|
vals, err := url.ParseQuery(query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m := make(map[string]interface{})
|
|
for k, vals := range vals {
|
|
m[k] = vals[0]
|
|
}
|
|
return New(m), nil
|
|
}
|
|
|
|
// MustFromURLQuery generates a new Obj by parsing the specified
|
|
// query.
|
|
//
|
|
// For queries with multiple values, the first value is selected.
|
|
//
|
|
// Panics if it encounters an error
|
|
func MustFromURLQuery(query string) Map {
|
|
o, err := FromURLQuery(query)
|
|
if err != nil {
|
|
panic("objx: MustFromURLQuery failed with error: " + err.Error())
|
|
}
|
|
return o
|
|
}
|