vendor: Capturing dependencies for cobbler provider

This commit is contained in:
Joe Topjian 2016-03-31 15:50:07 +00:00 committed by Paul Hinze
parent 831bae8624
commit c0c17ba1d2
28 changed files with 5134 additions and 0 deletions

13
Godeps/Godeps.json generated
View File

@ -565,6 +565,10 @@
"ImportPath": "github.com/dylanmei/winrmtest",
"Rev": "025617847eb2cf9bd1d851bc3b22ed28e6245ce5"
},
{
"ImportPath": "github.com/fatih/structs",
"Rev": "73c4e3dc02a78deaba8640d5f3a8c236ec1352bf"
},
{
"ImportPath": "github.com/fsouza/go-dockerclient",
"Rev": "bf97c77db7c945cbcdbf09d56c6f87a66f54537b"
@ -854,10 +858,19 @@
"ImportPath": "github.com/joyent/gosign/auth",
"Rev": "a1f3aa7d52213987117e47d721bcc9a499994d5f"
},
{
"ImportPath": "github.com/jtopjian/cobblerclient",
"Comment": "v0.3.0-33-g53d1c0a",
"Rev": "53d1c0a0b003aabfa7ecfa848d856606cb481196"
},
{
"ImportPath": "github.com/kardianos/osext",
"Rev": "29ae4ffbc9a6fe9fb2bc5029050ce6996ea1d3bc"
},
{
"ImportPath": "github.com/kolo/xmlrpc",
"Rev": "0826b98aaa29c0766956cb40d45cf7482a597671"
},
{
"ImportPath": "github.com/lib/pq",
"Comment": "go1.0-cutoff-74-g8ad2b29",

23
vendor/github.com/fatih/structs/.gitignore generated vendored Normal file
View File

@ -0,0 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test

11
vendor/github.com/fatih/structs/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,11 @@
language: go
go:
- 1.6
- tip
sudo: false
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
script:
- $HOME/gopath/bin/goveralls -service=travis-ci

21
vendor/github.com/fatih/structs/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Fatih Arslan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

163
vendor/github.com/fatih/structs/README.md generated vendored Normal file
View File

@ -0,0 +1,163 @@
# Structs [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/structs) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/fatih/structs) [![Coverage Status](http://img.shields.io/coveralls/fatih/structs.svg?style=flat-square)](https://coveralls.io/r/fatih/structs)
Structs contains various utilities to work with Go (Golang) structs. It was
initially used by me to convert a struct into a `map[string]interface{}`. With
time I've added other utilities for structs. It's basically a high level
package based on primitives from the reflect package. Feel free to add new
functions or improve the existing code.
## Install
```bash
go get github.com/fatih/structs
```
## Usage and Examples
Just like the standard lib `strings`, `bytes` and co packages, `structs` has
many global functions to manipulate or organize your struct data. Lets define
and declare a struct:
```go
type Server struct {
Name string `json:"name,omitempty"`
ID int
Enabled bool
users []string // not exported
http.Server // embedded
}
server := &Server{
Name: "gopher",
ID: 123456,
Enabled: true,
}
```
```go
// Convert a struct to a map[string]interface{}
// => {"Name":"gopher", "ID":123456, "Enabled":true}
m := structs.Map(server)
// Convert the values of a struct to a []interface{}
// => ["gopher", 123456, true]
v := structs.Values(server)
// Convert the names of a struct to a []string
// (see "Names methods" for more info about fields)
n := structs.Names(server)
// Convert the values of a struct to a []*Field
// (see "Field methods" for more info about fields)
f := structs.Fields(server)
// Return the struct name => "Server"
n := structs.Name(server)
// Check if any field of a struct is initialized or not.
h := structs.HasZero(server)
// Check if all fields of a struct is initialized or not.
z := structs.IsZero(server)
// Check if server is a struct or a pointer to struct
i := structs.IsStruct(server)
```
### Struct methods
The structs functions can be also used as independent methods by creating a new
`*structs.Struct`. This is handy if you want to have more control over the
structs (such as retrieving a single Field).
```go
// Create a new struct type:
s := structs.New(server)
m := s.Map() // Get a map[string]interface{}
v := s.Values() // Get a []interface{}
f := s.Fields() // Get a []*Field
n := s.Names() // Get a []string
f := s.Field(name) // Get a *Field based on the given field name
f, ok := s.FieldOk(name) // Get a *Field based on the given field name
n := s.Name() // Get the struct name
h := s.HasZero() // Check if any field is initialized
z := s.IsZero() // Check if all fields are initialized
```
### Field methods
We can easily examine a single Field for more detail. Below you can see how we
get and interact with various field methods:
```go
s := structs.New(server)
// Get the Field struct for the "Name" field
name := s.Field("Name")
// Get the underlying value, value => "gopher"
value := name.Value().(string)
// Set the field's value
name.Set("another gopher")
// Get the field's kind, kind => "string"
name.Kind()
// Check if the field is exported or not
if name.IsExported() {
fmt.Println("Name field is exported")
}
// Check if the value is a zero value, such as "" for string, 0 for int
if !name.IsZero() {
fmt.Println("Name is initialized")
}
// Check if the field is an anonymous (embedded) field
if !name.IsEmbedded() {
fmt.Println("Name is not an embedded field")
}
// Get the Field's tag value for tag name "json", tag value => "name,omitempty"
tagValue := name.Tag("json")
```
Nested structs are supported too:
```go
addrField := s.Field("Server").Field("Addr")
// Get the value for addr
a := addrField.Value().(string)
// Or get all fields
httpServer := s.Field("Server").Fields()
```
We can also get a slice of Fields from the Struct type to iterate over all
fields. This is handy if you wish to examine all fields:
```go
s := structs.New(server)
for _, f := range s.Fields() {
fmt.Printf("field name: %+v\n", f.Name())
if f.IsExported() {
fmt.Printf("value : %+v\n", f.Value())
fmt.Printf("is zero : %+v\n", f.IsZero())
}
}
```
## Credits
* [Fatih Arslan](https://github.com/fatih)
* [Cihangir Savas](https://github.com/cihangir)
## License
The MIT License (MIT) - see LICENSE.md for more details

133
vendor/github.com/fatih/structs/field.go generated vendored Normal file
View File

@ -0,0 +1,133 @@
package structs
import (
"errors"
"fmt"
"reflect"
)
var (
errNotExported = errors.New("field is not exported")
errNotSettable = errors.New("field is not settable")
)
// Field represents a single struct field that encapsulates high level
// functions around the field.
type Field struct {
value reflect.Value
field reflect.StructField
defaultTag string
}
// Tag returns the value associated with key in the tag string. If there is no
// such key in the tag, Tag returns the empty string.
func (f *Field) Tag(key string) string {
return f.field.Tag.Get(key)
}
// Value returns the underlying value of of the field. It panics if the field
// is not exported.
func (f *Field) Value() interface{} {
return f.value.Interface()
}
// IsEmbedded returns true if the given field is an anonymous field (embedded)
func (f *Field) IsEmbedded() bool {
return f.field.Anonymous
}
// IsExported returns true if the given field is exported.
func (f *Field) IsExported() bool {
return f.field.PkgPath == ""
}
// IsZero returns true if the given field is not initialized (has a zero value).
// It panics if the field is not exported.
func (f *Field) IsZero() bool {
zero := reflect.Zero(f.value.Type()).Interface()
current := f.Value()
return reflect.DeepEqual(current, zero)
}
// Name returns the name of the given field
func (f *Field) Name() string {
return f.field.Name
}
// Kind returns the fields kind, such as "string", "map", "bool", etc ..
func (f *Field) Kind() reflect.Kind {
return f.value.Kind()
}
// Set sets the field to given value v. It returns an error if the field is not
// settable (not addressable or not exported) or if the given value's type
// doesn't match the fields type.
func (f *Field) Set(val interface{}) error {
// we can't set unexported fields, so be sure this field is exported
if !f.IsExported() {
return errNotExported
}
// do we get here? not sure...
if !f.value.CanSet() {
return errNotSettable
}
given := reflect.ValueOf(val)
if f.value.Kind() != given.Kind() {
return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind())
}
f.value.Set(given)
return nil
}
// Zero sets the field to its zero value. It returns an error if the field is not
// settable (not addressable or not exported).
func (f *Field) Zero() error {
zero := reflect.Zero(f.value.Type()).Interface()
return f.Set(zero)
}
// Fields returns a slice of Fields. This is particular handy to get the fields
// of a nested struct . A struct tag with the content of "-" ignores the
// checking of that particular field. Example:
//
// // Field is ignored by this package.
// Field *http.Request `structs:"-"`
//
// It panics if field is not exported or if field's kind is not struct
func (f *Field) Fields() []*Field {
return getFields(f.value, f.defaultTag)
}
// Field returns the field from a nested struct. It panics if the nested struct
// is not exported or if the field was not found.
func (f *Field) Field(name string) *Field {
field, ok := f.FieldOk(name)
if !ok {
panic("field not found")
}
return field
}
// Field returns the field from a nested struct. The boolean returns true if
// the field was found. It panics if the nested struct is not exported or if
// the field was not found.
func (f *Field) FieldOk(name string) (*Field, bool) {
v := strctVal(f.value.Interface())
t := v.Type()
field, ok := t.FieldByName(name)
if !ok {
return nil, false
}
return &Field{
field: field,
value: v.FieldByName(name),
}, true
}

494
vendor/github.com/fatih/structs/structs.go generated vendored Normal file
View File

@ -0,0 +1,494 @@
// Package structs contains various utilities functions to work with structs.
package structs
import (
"fmt"
"reflect"
)
var (
// DefaultTagName is the default tag name for struct fields which provides
// a more granular to tweak certain structs. Lookup the necessary functions
// for more info.
DefaultTagName = "structs" // struct's field default tag name
)
// Struct encapsulates a struct type to provide several high level functions
// around the struct.
type Struct struct {
raw interface{}
value reflect.Value
TagName string
}
// New returns a new *Struct with the struct s. It panics if the s's kind is
// not struct.
func New(s interface{}) *Struct {
return &Struct{
raw: s,
value: strctVal(s),
TagName: DefaultTagName,
}
}
// Map converts the given struct to a map[string]interface{}, where the keys
// of the map are the field names and the values of the map the associated
// values of the fields. The default key string is the struct field name but
// can be changed in the struct field's tag value. The "structs" key in the
// struct's field tag value is the key name. Example:
//
// // Field appears in map as key "myName".
// Name string `structs:"myName"`
//
// A tag value with the content of "-" ignores that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// A tag value with the content of "string" uses the stringer to get the value. Example:
//
// // The value will be output of Animal's String() func.
// // Map will panic if Animal does not implement String().
// Field *Animal `structs:"field,string"`
//
// A tag value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Field is not processed further by this package.
// Field time.Time `structs:"myName,omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// A tag value with the option of "omitempty" ignores that particular field if
// the field value is empty. Example:
//
// // Field appears in map as key "myName", but the field is
// // skipped if empty.
// Field string `structs:"myName,omitempty"`
//
// // Field appears in map as key "Field" (the default), but
// // the field is skipped if empty.
// Field string `structs:",omitempty"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected.
func (s *Struct) Map() map[string]interface{} {
out := make(map[string]interface{})
s.FillMap(out)
return out
}
// FillMap is the same as Map. Instead of returning the output, it fills the
// given map.
func (s *Struct) FillMap(out map[string]interface{}) {
if out == nil {
return
}
fields := s.structFields()
for _, field := range fields {
name := field.Name
val := s.value.FieldByName(name)
var finalVal interface{}
tagName, tagOpts := parseTag(field.Tag.Get(s.TagName))
if tagName != "" {
name = tagName
}
// if the value is a zero value and the field is marked as omitempty do
// not include
if tagOpts.Has("omitempty") {
zero := reflect.Zero(val.Type()).Interface()
current := val.Interface()
if reflect.DeepEqual(current, zero) {
continue
}
}
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
// look out for embedded structs, and convert them to a
// map[string]interface{} too
n := New(val.Interface())
n.TagName = s.TagName
m := n.Map()
if len(m) == 0 {
finalVal = val.Interface()
} else {
finalVal = m
}
} else {
finalVal = val.Interface()
}
if tagOpts.Has("string") {
s, ok := val.Interface().(fmt.Stringer)
if ok {
out[name] = s.String()
}
continue
}
out[name] = finalVal
}
}
// Values converts the given s struct's field values to a []interface{}. A
// struct tag with the content of "-" ignores the that particular field.
// Example:
//
// // Field is ignored by this package.
// Field int `structs:"-"`
//
// A value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Fields is not processed further by this package.
// Field time.Time `structs:",omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// A tag value with the option of "omitempty" ignores that particular field and
// is not added to the values if the field value is empty. Example:
//
// // Field is skipped if empty
// Field string `structs:",omitempty"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected.
func (s *Struct) Values() []interface{} {
fields := s.structFields()
var t []interface{}
for _, field := range fields {
val := s.value.FieldByName(field.Name)
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
// if the value is a zero value and the field is marked as omitempty do
// not include
if tagOpts.Has("omitempty") {
zero := reflect.Zero(val.Type()).Interface()
current := val.Interface()
if reflect.DeepEqual(current, zero) {
continue
}
}
if tagOpts.Has("string") {
s, ok := val.Interface().(fmt.Stringer)
if ok {
t = append(t, s.String())
}
continue
}
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
// look out for embedded structs, and convert them to a
// []interface{} to be added to the final values slice
for _, embeddedVal := range Values(val.Interface()) {
t = append(t, embeddedVal)
}
} else {
t = append(t, val.Interface())
}
}
return t
}
// Fields returns a slice of Fields. A struct tag with the content of "-"
// ignores the checking of that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// It panics if s's kind is not struct.
func (s *Struct) Fields() []*Field {
return getFields(s.value, s.TagName)
}
// Names returns a slice of field names. A struct tag with the content of "-"
// ignores the checking of that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// It panics if s's kind is not struct.
func (s *Struct) Names() []string {
fields := getFields(s.value, s.TagName)
names := make([]string, len(fields))
for i, field := range fields {
names[i] = field.Name()
}
return names
}
func getFields(v reflect.Value, tagName string) []*Field {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
t := v.Type()
var fields []*Field
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if tag := field.Tag.Get(tagName); tag == "-" {
continue
}
f := &Field{
field: field,
value: v.FieldByName(field.Name),
}
fields = append(fields, f)
}
return fields
}
// Field returns a new Field struct that provides several high level functions
// around a single struct field entity. It panics if the field is not found.
func (s *Struct) Field(name string) *Field {
f, ok := s.FieldOk(name)
if !ok {
panic("field not found")
}
return f
}
// Field returns a new Field struct that provides several high level functions
// around a single struct field entity. The boolean returns true if the field
// was found.
func (s *Struct) FieldOk(name string) (*Field, bool) {
t := s.value.Type()
field, ok := t.FieldByName(name)
if !ok {
return nil, false
}
return &Field{
field: field,
value: s.value.FieldByName(name),
defaultTag: s.TagName,
}, true
}
// IsZero returns true if all fields in a struct is a zero value (not
// initialized) A struct tag with the content of "-" ignores the checking of
// that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// A value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Field is not processed further by this package.
// Field time.Time `structs:"myName,omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected. It panics if s's kind is not struct.
func (s *Struct) IsZero() bool {
fields := s.structFields()
for _, field := range fields {
val := s.value.FieldByName(field.Name)
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
ok := IsZero(val.Interface())
if !ok {
return false
}
continue
}
// zero value of the given field, such as "" for string, 0 for int
zero := reflect.Zero(val.Type()).Interface()
// current value of the given field
current := val.Interface()
if !reflect.DeepEqual(current, zero) {
return false
}
}
return true
}
// HasZero returns true if a field in a struct is not initialized (zero value).
// A struct tag with the content of "-" ignores the checking of that particular
// field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// A value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Field is not processed further by this package.
// Field time.Time `structs:"myName,omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected. It panics if s's kind is not struct.
func (s *Struct) HasZero() bool {
fields := s.structFields()
for _, field := range fields {
val := s.value.FieldByName(field.Name)
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
ok := HasZero(val.Interface())
if ok {
return true
}
continue
}
// zero value of the given field, such as "" for string, 0 for int
zero := reflect.Zero(val.Type()).Interface()
// current value of the given field
current := val.Interface()
if reflect.DeepEqual(current, zero) {
return true
}
}
return false
}
// Name returns the structs's type name within its package. For more info refer
// to Name() function.
func (s *Struct) Name() string {
return s.value.Type().Name()
}
// structFields returns the exported struct fields for a given s struct. This
// is a convenient helper method to avoid duplicate code in some of the
// functions.
func (s *Struct) structFields() []reflect.StructField {
t := s.value.Type()
var f []reflect.StructField
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
// we can't access the value of unexported fields
if field.PkgPath != "" {
continue
}
// don't check if it's omitted
if tag := field.Tag.Get(s.TagName); tag == "-" {
continue
}
f = append(f, field)
}
return f
}
func strctVal(s interface{}) reflect.Value {
v := reflect.ValueOf(s)
// if pointer get the underlying element≤
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
panic("not struct")
}
return v
}
// Map converts the given struct to a map[string]interface{}. For more info
// refer to Struct types Map() method. It panics if s's kind is not struct.
func Map(s interface{}) map[string]interface{} {
return New(s).Map()
}
// FillMap is the same as Map. Instead of returning the output, it fills the
// given map.
func FillMap(s interface{}, out map[string]interface{}) {
New(s).FillMap(out)
}
// Values converts the given struct to a []interface{}. For more info refer to
// Struct types Values() method. It panics if s's kind is not struct.
func Values(s interface{}) []interface{} {
return New(s).Values()
}
// Fields returns a slice of *Field. For more info refer to Struct types
// Fields() method. It panics if s's kind is not struct.
func Fields(s interface{}) []*Field {
return New(s).Fields()
}
// Names returns a slice of field names. For more info refer to Struct types
// Names() method. It panics if s's kind is not struct.
func Names(s interface{}) []string {
return New(s).Names()
}
// IsZero returns true if all fields is equal to a zero value. For more info
// refer to Struct types IsZero() method. It panics if s's kind is not struct.
func IsZero(s interface{}) bool {
return New(s).IsZero()
}
// HasZero returns true if any field is equal to a zero value. For more info
// refer to Struct types HasZero() method. It panics if s's kind is not struct.
func HasZero(s interface{}) bool {
return New(s).HasZero()
}
// IsStruct returns true if the given variable is a struct or a pointer to
// struct.
func IsStruct(s interface{}) bool {
v := reflect.ValueOf(s)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// uninitialized zero value of a struct
if v.Kind() == reflect.Invalid {
return false
}
return v.Kind() == reflect.Struct
}
// Name returns the structs's type name within its package. It returns an
// empty string for unnamed types. It panics if s's kind is not struct.
func Name(s interface{}) string {
return New(s).Name()
}

32
vendor/github.com/fatih/structs/tags.go generated vendored Normal file
View File

@ -0,0 +1,32 @@
package structs
import "strings"
// tagOptions contains a slice of tag options
type tagOptions []string
// Has returns true if the given optiton is available in tagOptions
func (t tagOptions) Has(opt string) bool {
for _, tagOpt := range t {
if tagOpt == opt {
return true
}
}
return false
}
// parseTag splits a struct field's tag into its name and a list of options
// which comes after a name. A tag is in the form of: "name,option1,option2".
// The name can be neglectected.
func parseTag(tag string) (string, tagOptions) {
// tag is one of followings:
// ""
// "name"
// "name,opt"
// "name,opt,opt2"
// ",opt"
res := strings.Split(tag, ",")
return res[0], res[1:]
}

1
vendor/github.com/jtopjian/cobblerclient/.gitignore generated vendored Normal file
View File

@ -0,0 +1 @@
**/*.swp

202
vendor/github.com/jtopjian/cobblerclient/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

20
vendor/github.com/jtopjian/cobblerclient/Makefile generated vendored Normal file
View File

@ -0,0 +1,20 @@
# Copyright 2015 Container Solutions
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
build:
@go build .
test:
@go test -v .

2
vendor/github.com/jtopjian/cobblerclient/README.md generated vendored Normal file
View File

@ -0,0 +1,2 @@
# cobblerclient
Cobbler Client written in Go

View File

@ -0,0 +1,198 @@
/*
Copyright 2015 Container Solutions
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cobblerclient
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"reflect"
"strings"
"github.com/kolo/xmlrpc"
"github.com/mitchellh/mapstructure"
)
const bodyTypeXML = "text/xml"
type HTTPClient interface {
Post(string, string, io.Reader) (*http.Response, error)
}
type Client struct {
httpClient HTTPClient
config ClientConfig
Token string
}
type ClientConfig struct {
Url string
Username string
Password string
}
func NewClient(httpClient HTTPClient, c ClientConfig) Client {
return Client{
httpClient: httpClient,
config: c,
}
}
func (c *Client) Call(method string, args ...interface{}) (interface{}, error) {
var result interface{}
reqBody, err := xmlrpc.EncodeMethodCall(method, args...)
if err != nil {
return nil, err
}
r := fmt.Sprintf("%s\n", string(reqBody))
res, err := c.httpClient.Post(c.config.Url, bodyTypeXML, bytes.NewReader([]byte(r)))
if err != nil {
return nil, err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
resp := xmlrpc.NewResponse(body)
if err := resp.Unmarshal(&result); err != nil {
return nil, err
}
if resp.Failed() {
return nil, resp.Err()
}
return result, nil
}
// Performs a login request to Cobbler using the credentials provided
// in the configuration in the initializer.
func (c *Client) Login() (bool, error) {
result, err := c.Call("login", c.config.Username, c.config.Password)
if err != nil {
return false, err
}
c.Token = result.(string)
return true, nil
}
// Sync the system.
// Returns an error if anything went wrong
func (c *Client) Sync() error {
_, err := c.Call("sync", c.Token)
return err
}
// GetItemHandle gets the internal ID of a Cobbler item.
func (c *Client) GetItemHandle(what, name string) (string, error) {
result, err := c.Call("get_item_handle", what, name, c.Token)
if err != nil {
return "", err
} else {
return result.(string), err
}
}
// cobblerDataHacks is a hook for the mapstructure decoder. It's only used by
// decodeCobblerItem and should never be invoked directly.
// It's used to smooth out issues with converting fields and types from Cobbler.
func cobblerDataHacks(f, t reflect.Kind, data interface{}) (interface{}, error) {
dataVal := reflect.ValueOf(data)
// Cobbler uses ~ internally to mean None/nil
if dataVal.String() == "~" {
return map[string]interface{}{}, nil
}
if f == reflect.Int64 && t == reflect.Bool {
if dataVal.Int() > 0 {
return true, nil
} else {
return false, nil
}
}
return data, nil
}
// decodeCobblerItem is a custom mapstructure decoder to handler Cobbler's uniqueness.
func decodeCobblerItem(raw interface{}, result interface{}) (interface{}, error) {
var metadata mapstructure.Metadata
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Metadata: &metadata,
Result: result,
WeaklyTypedInput: true,
DecodeHook: cobblerDataHacks,
})
if err != nil {
return nil, err
}
if err := decoder.Decode(raw); err != nil {
return nil, err
}
return result, nil
}
// updateCobblerFields updates all fields in a Cobbler Item structure.
func (c *Client) updateCobblerFields(what string, item reflect.Value, id string) error {
method := fmt.Sprintf("modify_%s", what)
typeOfT := item.Type()
for i := 0; i < item.NumField(); i++ {
v := item.Field(i)
tag := typeOfT.Field(i).Tag
field := tag.Get("mapstructure")
cobblerTag := tag.Get("cobbler")
if cobblerTag == "noupdate" {
continue
}
if field == "" {
continue
}
var value interface{}
switch v.Type().String() {
case "string", "bool", "int64", "int":
value = v.Interface()
case "[]string":
value = strings.Join(v.Interface().([]string), " ")
}
//fmt.Printf("%s, %s, %s\n", id, field, value)
if result, err := c.Call(method, id, field, value, c.Token); err != nil {
return err
} else {
if result.(bool) == false && value != false {
return fmt.Errorf("Error updating %s to %s.", field, value)
}
}
}
return nil
}

145
vendor/github.com/jtopjian/cobblerclient/distro.go generated vendored Normal file
View File

@ -0,0 +1,145 @@
/*
Copyright 2015 Container Solutions
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cobblerclient
import (
"fmt"
"reflect"
)
// Distro is a created distro.
type Distro struct {
// These are internal fields and cannot be modified.
Ctime float64 `mapstructure:"ctime" cobbler:"noupdate"` // TODO: convert to time
Depth int `mapstructure:"depth" cobbler:"noupdate"`
ID string `mapstructure:"uid" cobbler:"noupdate"`
Mtime float64 `mapstructure:"mtime" cobbler:"noupdate"` // TODO: convert to time
TreeBuildTime string `mapstructure:tree_build_time" cobbler:"noupdate"`
Arch string `mapstructure:"arch"`
Breed string `mapstructure:"breed"`
BootFiles string `mapstructure:"boot_files"`
Comment string `mapstructure:"comment"`
FetchableFiles string `mapstructure:"fetchable_files"`
Kernel string `mapstructure:"kernel"`
KernelOptions string `mapstructure:"kernel_options"`
KernelOptionsPost string `mapstructure:"kernel_options_post"`
Initrd string `mapstructure:"initrd"`
MGMTClasses []string `mapstructure:"mgmt_classes"`
Name string `mapstructure:"name"`
OSVersion string `mapstructure:"os_version"`
Owners []string `mapstructure:"owners"`
RedHatManagementKey string `mapstructure:"redhat_management_key"`
RedHatManagementServer string `mapstructure:"redhat_management_server"`
TemplateFiles string `mapstructure:"template_files"`
//KSMeta string `mapstructure:"ks_meta"`
//SourceRepos []string `mapstructure:"source_repos"`
}
// GetDistros returns all systems in Cobbler.
func (c *Client) GetDistros() ([]*Distro, error) {
var distros []*Distro
result, err := c.Call("get_distros", "-1", c.Token)
if err != nil {
return nil, err
}
for _, d := range result.([]interface{}) {
var distro Distro
decodedResult, err := decodeCobblerItem(d, &distro)
if err != nil {
return nil, err
}
distros = append(distros, decodedResult.(*Distro))
}
return distros, nil
}
// GetDistro returns a single distro obtained by its name.
func (c *Client) GetDistro(name string) (*Distro, error) {
var distro Distro
result, err := c.Call("get_distro", name, c.Token)
if result == "~" {
return nil, fmt.Errorf("Distro %s not found.", name)
}
if err != nil {
return nil, err
}
decodeResult, err := decodeCobblerItem(result, &distro)
if err != nil {
return nil, err
}
return decodeResult.(*Distro), nil
}
// CreateDistro creates a distro.
func (c *Client) CreateDistro(distro Distro) (*Distro, error) {
// Make sure a distro with the same name does not already exist
if _, err := c.GetDistro(distro.Name); err == nil {
return nil, fmt.Errorf("A Distro with the name %s already exists.", distro.Name)
}
result, err := c.Call("new_distro", c.Token)
if err != nil {
return nil, err
}
newId := result.(string)
item := reflect.ValueOf(&distro).Elem()
if err := c.updateCobblerFields("distro", item, newId); err != nil {
return nil, err
}
if _, err := c.Call("save_distro", newId, c.Token); err != nil {
return nil, err
}
return c.GetDistro(distro.Name)
}
// UpdateDistro updates a single distro.
func (c *Client) UpdateDistro(distro *Distro) error {
item := reflect.ValueOf(distro).Elem()
id, err := c.GetItemHandle("distro", distro.Name)
if err != nil {
return err
}
if err := c.updateCobblerFields("distro", item, id); err != nil {
return err
}
if _, err := c.Call("save_distro", id, c.Token); err != nil {
return err
}
return nil
}
// DeleteDistro deletes a single distro by its name.
func (c *Client) DeleteDistro(name string) error {
_, err := c.Call("remove_distro", name, c.Token)
return err
}

View File

@ -0,0 +1,56 @@
/*
Copyright 2015 Container Solutions
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cobblerclient
type KickstartFile struct {
Name string // The name the kickstart file will be saved in Cobbler
Body string // The contents of the kickstart file
}
// Creates a kickstart file in Cobbler.
// Takes a KickstartFile struct as input.
// Returns true/false and error if creation failed.
func (c *Client) CreateKickstartFile(f KickstartFile) error {
_, err := c.Call("read_or_write_kickstart_template", f.Name, false, f.Body, c.Token)
return err
}
// Gets a kickstart file in Cobbler.
// Takes a kickstart file name as input.
// Returns *KickstartFile and error if read failed.
func (c *Client) GetKickstartFile(ksName string) (*KickstartFile, error) {
result, err := c.Call("read_or_write_kickstart_template", ksName, true, "", c.Token)
if err != nil {
return nil, err
}
ks := KickstartFile{
Name: ksName,
Body: result.(string),
}
return &ks, nil
}
// Deletes a kickstart file in Cobbler.
// Takes a kickstart file name as input.
// Returns error if delete failed.
func (c *Client) DeleteKickstartFile(name string) error {
_, err := c.Call("read_or_write_kickstart_template", name, false, -1, c.Token)
return err
}

1990
vendor/github.com/jtopjian/cobblerclient/methods.txt generated vendored Normal file

File diff suppressed because it is too large Load Diff

230
vendor/github.com/jtopjian/cobblerclient/profile.go generated vendored Normal file
View File

@ -0,0 +1,230 @@
/*
Copyright 2015 Container Solutions
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cobblerclient
import (
"fmt"
"reflect"
)
// Profile is a created profile.
type Profile struct {
// These are internal fields and cannot be modified.
Ctime float64 `mapstructure:"ctime" cobbler:"noupdate"` // TODO: convert to time
Depth int `mapstructure:"depth" cobbler:"noupdate"`
ID string `mapstructure:"uid" cobbler:"noupdate"`
Mtime float64 `mapstructure:"mtime" cobbler:"noupdate"` // TODO: convert to time
ReposEnabled bool `mapstructure:"repos_enabled" cobbler:"noupdate"`
BootFiles string `mapstructure:"boot_files"`
Comment string `mapstructure:"comment"`
Distro string `mapstructure:"distro"`
EnableGPXE bool `mapstructure:"enable_gpxe"`
EnableMenu bool `mapstructure:"enable_menu"`
FetchableFiles string `mapstructure:"fetchable_files"`
KernelOptions string `mapstructure:"kernel_options"`
KernelOptionsPost string `mapstructure:"kernel_options_post"`
Kickstart string `mapstructure:"kickstart"`
KSMeta string `mapstructure:"ks_meta"`
MGMTClasses []string `mapstructure:"mgmt_classes"`
MGMTParameters string `mapstructure:"mgmt_parameters"`
Name string `mapstructure:"name"`
NameServersSearch []string `mapstructure:"name_servers_search"`
NameServers []string `mapstructure:"name_servers"`
Owners []string `mapstructure:"owners"`
Parent string `mapstructure:"parent"`
Proxy string `mapstructure:"proxy"`
RedHatManagementKey string `mapstructure:"redhat_management_key"`
RedHatManagementServer string `mapstructure:"redhat_management_server"`
Repos []string `mapstructure:"repos"`
Server string `mapstructure:"server"`
TemplateFiles string `mapstructure:"template_files"`
TemplateRemoteKickstarts int `mapstructure:"template_remote_kickstarts"`
VirtAutoBoot string `mapstructure:"virt_auto_boot"`
VirtBridge string `mapstructure:"virt_bridge"`
VirtCPUs string `mapstructure:"virt_cpus"`
VirtDiskDriver string `mapstructure:"virt_disk_driver"`
VirtFileSize string `mapstructure:"virt_file_size"`
VirtPath string `mapstructure:"virt_path"`
VirtRam string `mapstructure:"virt_ram"`
VirtType string `mapstructure:"virt_type"`
Client
}
// GetProfiles returns all systems in Cobbler.
func (c *Client) GetProfiles() ([]*Profile, error) {
var profiles []*Profile
result, err := c.Call("get_profiles", "-1", c.Token)
if err != nil {
return nil, err
}
for _, p := range result.([]interface{}) {
var profile Profile
decodedResult, err := decodeCobblerItem(p, &profile)
if err != nil {
return nil, err
}
decodedProfile := decodedResult.(*Profile)
decodedProfile.Client = *c
profiles = append(profiles, decodedProfile)
}
return profiles, nil
}
// GetProfile returns a single profile obtained by its name.
func (c *Client) GetProfile(name string) (*Profile, error) {
var profile Profile
result, err := c.Call("get_profile", name, c.Token)
if err != nil {
return &profile, err
}
if result == "~" {
return nil, fmt.Errorf("Profile %s not found.", name)
}
decodeResult, err := decodeCobblerItem(result, &profile)
if err != nil {
return nil, err
}
s := decodeResult.(*Profile)
s.Client = *c
return s, nil
}
// CreateProfile creates a system.
// It ensures that a Distro is set and then sets other default values.
func (c *Client) CreateProfile(profile Profile) (*Profile, error) {
// Check if a profile with the same name already exists
if _, err := c.GetProfile(profile.Name); err == nil {
return nil, fmt.Errorf("A profile with the name %s already exists.", profile.Name)
}
if profile.Distro == "" {
return nil, fmt.Errorf("A profile must have a distro set.")
}
/*
// Set default values. I guess these aren't taken care of by Cobbler?
if system.BootFiles == "" {
system.BootFiles = "<<inherit>>"
}
if system.FetchableFiles == "" {
system.FetchableFiles = "<<inherit>>"
}
*/
if profile.MGMTParameters == "" {
profile.MGMTParameters = "<<inherit>>"
}
if profile.VirtAutoBoot == "" {
profile.VirtAutoBoot = "0"
}
if profile.VirtRam == "" {
profile.VirtRam = "<<inherit>>"
}
if profile.VirtType == "" {
profile.VirtType = "<<inherit>>"
}
/*
if system.PowerType == "" {
system.PowerType = "ipmilan"
}
if system.Status == "" {
system.Status = "production"
}
if system.VirtCPUs == "" {
system.VirtCPUs = "<<inherit>>"
}
if system.VirtDiskDriver == "" {
system.VirtDiskDriver = "<<inherit>>"
}
if system.VirtFileSize == "" {
system.VirtFileSize = "<<inherit>>"
}
if system.VirtPath == "" {
system.VirtPath = "<<inherit>>"
}
*/
// To create a profile via the Cobbler API, first call new_profile to obtain an ID
result, err := c.Call("new_profile", c.Token)
if err != nil {
return nil, err
}
newId := result.(string)
// Set the value of all fields
item := reflect.ValueOf(&profile).Elem()
if err := c.updateCobblerFields("profile", item, newId); err != nil {
return nil, err
}
// Save the final profile
if _, err := c.Call("save_profile", newId, c.Token); err != nil {
return nil, err
}
// Return a clean copy of the profile
return c.GetProfile(profile.Name)
}
// UpdateProfile updates a single profile.
func (c *Client) UpdateProfile(profile *Profile) error {
item := reflect.ValueOf(profile).Elem()
id, err := c.GetItemHandle("profile", profile.Name)
if err != nil {
return err
}
if err := c.updateCobblerFields("profile", item, id); err != nil {
return err
}
// Save the final profile
if _, err := c.Call("save_profile", id, c.Token); err != nil {
return err
}
return nil
}
// DeleteProfile deletes a single profile by its name.
func (c *Client) DeleteProfile(name string) error {
_, err := c.Call("remove_profile", name, c.Token)
return err
}

56
vendor/github.com/jtopjian/cobblerclient/snippet.go generated vendored Normal file
View File

@ -0,0 +1,56 @@
/*
Copyright 2015 Container Solutions
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cobblerclient
type Snippet struct {
Name string // The name the snippet file will be saved in Cobbler
Body string // The contents of the kickstart file
}
// Creates a snippet in Cobbler.
// Takes a Snippet struct as input
// Returns true/false and error if creation failed.
func (c *Client) CreateSnippet(s Snippet) error {
_, err := c.Call("read_or_write_snippet", s.Name, false, s.Body, c.Token)
return err
}
// Gets a snippet file in Cobbler.
// Takes a snippet file name as input.
// Returns *Snippet and error if read failed.
func (c *Client) GetSnippet(name string) (*Snippet, error) {
result, err := c.Call("read_or_write_snippet", name, true, "", c.Token)
if err != nil {
return nil, err
}
snippet := Snippet{
Name: name,
Body: result.(string),
}
return &snippet, nil
}
// Gets a snippet file in Cobbler.
// Takes a snippet file name as input.
// Returns error if delete failed.
func (c *Client) DeleteSnippet(name string) error {
_, err := c.Call("read_or_write_snippet", name, false, -1, c.Token)
return err
}

336
vendor/github.com/jtopjian/cobblerclient/system.go generated vendored Normal file
View File

@ -0,0 +1,336 @@
/*
Copyright 2015 Container Solutions
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cobblerclient
import (
"fmt"
"reflect"
"github.com/fatih/structs"
"github.com/mitchellh/mapstructure"
)
// System is a created system.
type System struct {
// These are internal fields and cannot be modified.
Ctime float64 `mapstructure:"ctime" cobbler:"noupdate"` // TODO: convert to time
Depth int `mapstructure:"depth" cobbler:"noupdate"`
ID string `mapstructure:"uid" cobbler:"noupdate"`
IPv6Autoconfiguration bool `mapstructure:"ipv6_autoconfiguration" cobbler:"noupdate"`
Mtime float64 `mapstructure:"mtime" cobbler:"noupdate"` // TODO: convert to time
ReposEnabled bool `mapstructure:"repos_enabled" cobbler:"noupdate"`
BootFiles string `mapstructure:"boot_files"`
Comment string `mapstructure:"comment"`
EnableGPXE bool `mapstructure:"enable_gpxe"`
FetchableFiles string `mapstructure:"fetchable_files"`
Gateway string `mapstructure:"gateway"`
Hostname string `mapstructure:"hostname"`
Image string `mapstructure:"image"`
Interfaces map[string]interface{} `mapstructure:"interfaces" cobbler:"noupdate"`
IPv6DefaultDevice string `mapstructure:"ipv6_default_device"`
KernelOptions string `mapstructure:"kernel_options"`
KernelOptionsPost string `mapstructure:"kernel_options_post"`
Kickstart string `mapstructure:"kickstart"`
KSMeta string `mapstructure:"ks_meta"`
LDAPEnabled bool `mapstructure:"ldap_enabled"`
LDAPType string `mapstructure:"ldap_type"`
MGMTClasses []string `mapstructure:"mgmt_classes"`
MGMTParameters string `mapstructure:"mgmt_parameters"`
MonitEnabled bool `mapstructure:"monit_enabled"`
Name string `mapstructure:"name"`
NameServersSearch []string `mapstructure:"name_servers_search"`
NameServers []string `mapstructure:"name_servers"`
NetbootEnabled bool `mapstructure:"netboot_enabled"`
Owners []string `mapstructure:"owners"`
PowerAddress string `mapstructure:"power_address"`
PowerID string `mapstructure:"power_id"`
PowerPass string `mapstructure:"power_pass"`
PowerType string `mapstructure:"power_type"`
PowerUser string `mapstructure:"power_user"`
Profile string `mapstructure:"profile"`
Proxy string `mapstructure:"proxy"`
RedHatManagementKey string `mapstructure:"redhat_management_key"`
RedHatManagementServer string `mapstructure:"redhat_management_server"`
Status string `mapstructure:"status"`
TemplateFiles string `mapstructure:"template_files"`
TemplateRemoteKickstarts int `mapstructure:"template_remote_kickstarts"`
VirtAutoBoot string `mapstructure:"virt_auto_boot"`
VirtCPUs string `mapstructure:"virt_cpus"`
VirtDiskDriver string `mapstructure:"virt_disk_driver"`
VirtFileSize string `mapstructure:"virt_file_size"`
VirtPath string `mapstructure:"virt_path"`
VirtPXEBoot int `mapstructure:"virt_pxe_boot"`
VirtRam string `mapstructure:"virt_ram"`
VirtType string `mapstructure:"virt_type"`
Client
}
// Interface is an interface in a system.
type Interface struct {
CNAMEs []string `mapstructure:"cnames" structs:"cnames"`
DHCPTag string `mapstructure:"dhcp_tag" structs:"dhcp_tag"`
DNSName string `mapstructure:"dns_name" structs:"dns_name"`
BondingOpts string `mapstructure:"bonding_opts" structs:"bonding_opts"`
BridgeOpts string `mapstructure:"bridge_opts" structs:"bridge_opts"`
Gateway string `mapstructure:"if_gateway" structs:"if_gateway"`
InterfaceType string `mapstructure:"interface_type" structs:"interface_type"`
InterfaceMaster string `mapstructure:"interface_master" structs:"interface_master"`
IPAddress string `mapstructure:"ip_address" structs:"ip_address"`
IPv6Address string `mapstructure:"ipv6_address" structs:"ipv6_address"`
IPv6Secondaries []string `mapstructure:"ipv6_secondaries" structs:"ipv6_secondaries"`
IPv6MTU string `mapstructure:"ipv6_mtu" structs:"ipv6_mtu"`
IPv6StaticRoutes []string `mapstructure:"ipv6_static_routes" structs:"ipv6_static_routes"`
IPv6DefaultGateway string `mapstructure:"ipv6_default_gateway structs:"ipv6_default_gateway"`
MACAddress string `mapstructure:"mac_address" structs:"mac_address"`
Management bool `mapstructure:"management" structs:"managment"`
Netmask string `mapstructure:"netmask" structs:"netmask"`
Static bool `mapstructure:"static" structs:"static"`
StaticRoutes []string `mapstructure:"static_routes" structs:"static_routes"`
VirtBridge string `mapstructure:"virt_bridge" structs:"virt_bridge"`
}
// Interfaces is a collection of interfaces in a system.
type Interfaces map[string]Interface
// GetSystems returns all systems in Cobbler.
func (c *Client) GetSystems() ([]*System, error) {
var systems []*System
result, err := c.Call("get_systems", "", c.Token)
if err != nil {
return nil, err
}
for _, s := range result.([]interface{}) {
var system System
decodedResult, err := decodeCobblerItem(s, &system)
if err != nil {
return nil, err
}
decodedSystem := decodedResult.(*System)
decodedSystem.Client = *c
systems = append(systems, decodedSystem)
}
return systems, nil
}
// GetSystem returns a single system obtained by its name.
func (c *Client) GetSystem(name string) (*System, error) {
var system System
result, err := c.Call("get_system", name, c.Token)
if err != nil {
return &system, err
}
if result == "~" {
return nil, fmt.Errorf("System %s not found.", name)
}
decodeResult, err := decodeCobblerItem(result, &system)
if err != nil {
return nil, err
}
s := decodeResult.(*System)
s.Client = *c
return s, nil
}
// CreateSystem creates a system.
// It ensures that either a Profile or Image are set and then sets other default values.
func (c *Client) CreateSystem(system System) (*System, error) {
// Check if a system with the same name already exists
if _, err := c.GetSystem(system.Name); err == nil {
return nil, fmt.Errorf("A system with the name %s already exists.", system.Name)
}
if system.Profile == "" && system.Image == "" {
return nil, fmt.Errorf("A system must have a profile or image set.")
}
// Set default values. I guess these aren't taken care of by Cobbler?
if system.BootFiles == "" {
system.BootFiles = "<<inherit>>"
}
if system.FetchableFiles == "" {
system.FetchableFiles = "<<inherit>>"
}
if system.MGMTParameters == "" {
system.MGMTParameters = "<<inherit>>"
}
if system.PowerType == "" {
system.PowerType = "ipmilan"
}
if system.Status == "" {
system.Status = "production"
}
if system.VirtAutoBoot == "" {
system.VirtAutoBoot = "0"
}
if system.VirtCPUs == "" {
system.VirtCPUs = "<<inherit>>"
}
if system.VirtDiskDriver == "" {
system.VirtDiskDriver = "<<inherit>>"
}
if system.VirtFileSize == "" {
system.VirtFileSize = "<<inherit>>"
}
if system.VirtPath == "" {
system.VirtPath = "<<inherit>>"
}
if system.VirtRam == "" {
system.VirtRam = "<<inherit>>"
}
if system.VirtType == "" {
system.VirtType = "<<inherit>>"
}
// To create a system via the Cobbler API, first call new_system to obtain an ID
result, err := c.Call("new_system", c.Token)
if err != nil {
return nil, err
}
newId := result.(string)
// Set the value of all fields
item := reflect.ValueOf(&system).Elem()
if err := c.updateCobblerFields("system", item, newId); err != nil {
return nil, err
}
// Save the final system
if _, err := c.Call("save_system", newId, c.Token); err != nil {
return nil, err
}
// Return a clean copy of the system
return c.GetSystem(system.Name)
}
// UpdateSystem updates a single system.
func (c *Client) UpdateSystem(system *System) error {
item := reflect.ValueOf(system).Elem()
id, err := c.GetItemHandle("system", system.Name)
if err != nil {
return err
}
return c.updateCobblerFields("system", item, id)
}
// DeleteSystem deletes a single system by its name.
func (c *Client) DeleteSystem(name string) error {
_, err := c.Call("remove_system", name, c.Token)
return err
}
func (s *System) CreateInterface(name string, iface Interface) error {
i := structs.Map(iface)
nic := make(map[string]interface{})
for key, value := range i {
attrName := fmt.Sprintf("%s-%s", key, name)
nic[attrName] = value
}
systemId, err := s.Client.GetItemHandle("system", s.Name)
if err != nil {
return err
}
if _, err := s.Client.Call("modify_system", systemId, "modify_interface", nic, s.Client.Token); err != nil {
return err
}
// Save the final system
if _, err := s.Client.Call("save_system", systemId, s.Client.Token); err != nil {
return err
}
return nil
}
// GetInterfaces returns all interfaces in a System.
func (s *System) GetInterfaces() (Interfaces, error) {
nics := make(Interfaces)
for nicName, nicData := range s.Interfaces {
var nic Interface
if err := mapstructure.Decode(nicData, &nic); err != nil {
return nil, err
}
nics[nicName] = nic
}
return nics, nil
}
// GetInterface returns a single interface in a System.
func (s *System) GetInterface(name string) (Interface, error) {
nics := make(Interfaces)
var iface Interface
for nicName, nicData := range s.Interfaces {
var nic Interface
if err := mapstructure.Decode(nicData, &nic); err != nil {
return iface, err
}
nics[nicName] = nic
}
if iface, ok := nics[name]; ok {
return iface, nil
} else {
return iface, fmt.Errorf("Interface %s not found.", name)
}
}
// DeleteInterface deletes a single interface in a System.
func (s *System) DeleteInterface(name string) error {
if _, err := s.GetInterface(name); err != nil {
return err
}
systemId, err := s.Client.GetItemHandle("system", s.Name)
if err != nil {
return err
}
if _, err := s.Client.Call("modify_system", systemId, "delete_interface", name, s.Client.Token); err != nil {
return err
}
// Save the final system
if _, err := s.Client.Call("save_system", systemId, s.Client.Token); err != nil {
return err
}
return nil
}

19
vendor/github.com/kolo/xmlrpc/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (C) 2012 Dmitry Maksimov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

79
vendor/github.com/kolo/xmlrpc/README.md generated vendored Normal file
View File

@ -0,0 +1,79 @@
## Overview
xmlrpc is an implementation of client side part of XMLRPC protocol in Go language.
## Installation
To install xmlrpc package run `go get github.com/kolo/xmlrpc`. To use
it in application add `"github.com/kolo/xmlrpc"` string to `import`
statement.
## Usage
client, _ := xmlrpc.NewClient("https://bugzilla.mozilla.org/xmlrpc.cgi", nil)
result := struct{
Version string `xmlrpc:"version"`
}{}
client.Call("Bugzilla.version", nil, &result)
fmt.Printf("Version: %s\n", result.Version) // Version: 4.2.7+
Second argument of NewClient function is an object that implements
[http.RoundTripper](http://golang.org/pkg/net/http/#RoundTripper)
interface, it can be used to get more control over connection options.
By default it initialized by http.DefaultTransport object.
### Arguments encoding
xmlrpc package supports encoding of native Go data types to method
arguments.
Data types encoding rules:
* int, int8, int16, int32, int64 encoded to int;
* float32, float64 encoded to double;
* bool encoded to boolean;
* string encoded to string;
* time.Time encoded to datetime.iso8601;
* xmlrpc.Base64 encoded to base64;
* slice decoded to array;
Structs decoded to struct by following rules:
* all public field become struct members;
* field name become member name;
* if field has xmlrpc tag, its value become member name.
Server method can accept few arguments, to handle this case there is
special approach to handle slice of empty interfaces (`[]interface{}`).
Each value of such slice encoded as separate argument.
### Result decoding
Result of remote function is decoded to native Go data type.
Data types decoding rules:
* int, i4 decoded to int, int8, int16, int32, int64;
* double decoded to float32, float64;
* boolean decoded to bool;
* string decoded to string;
* array decoded to slice;
* structs decoded following the rules described in previous section;
* datetime.iso8601 decoded as time.Time data type;
* base64 decoded to string.
## Implementation details
xmlrpc package contains clientCodec type, that implements [rpc.ClientCodec](http://golang.org/pkg/net/rpc/#ClientCodec)
interface of [net/rpc](http://golang.org/pkg/net/rpc) package.
xmlrpc package works over HTTP protocol, but some internal functions
and data type were made public to make it easier to create another
implementation of xmlrpc that works over another protocol. To encode
request body there is EncodeMethodCall function. To decode server
response Response data type can be used.
## Contribution
Feel free to fork the project, submit pull requests, ask questions.
## Authors
Dmitry Maksimov (dmtmax@gmail.com)

144
vendor/github.com/kolo/xmlrpc/client.go generated vendored Normal file
View File

@ -0,0 +1,144 @@
package xmlrpc
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/rpc"
"net/url"
)
type Client struct {
*rpc.Client
}
// clientCodec is rpc.ClientCodec interface implementation.
type clientCodec struct {
// url presents url of xmlrpc service
url *url.URL
// httpClient works with HTTP protocol
httpClient *http.Client
// cookies stores cookies received on last request
cookies http.CookieJar
// responses presents map of active requests. It is required to return request id, that
// rpc.Client can mark them as done.
responses map[uint64]*http.Response
response *Response
// ready presents channel, that is used to link request and it`s response.
ready chan uint64
}
func (codec *clientCodec) WriteRequest(request *rpc.Request, args interface{}) (err error) {
httpRequest, err := NewRequest(codec.url.String(), request.ServiceMethod, args)
if codec.cookies != nil {
for _, cookie := range codec.cookies.Cookies(codec.url) {
httpRequest.AddCookie(cookie)
}
}
if err != nil {
return err
}
var httpResponse *http.Response
httpResponse, err = codec.httpClient.Do(httpRequest)
if err != nil {
return err
}
if codec.cookies != nil {
codec.cookies.SetCookies(codec.url, httpResponse.Cookies())
}
codec.responses[request.Seq] = httpResponse
codec.ready <- request.Seq
return nil
}
func (codec *clientCodec) ReadResponseHeader(response *rpc.Response) (err error) {
seq := <-codec.ready
httpResponse := codec.responses[seq]
if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
return fmt.Errorf("request error: bad status code - %d", httpResponse.StatusCode)
}
respData, err := ioutil.ReadAll(httpResponse.Body)
if err != nil {
return err
}
httpResponse.Body.Close()
resp := NewResponse(respData)
if resp.Failed() {
response.Error = fmt.Sprintf("%v", resp.Err())
}
codec.response = resp
response.Seq = seq
delete(codec.responses, seq)
return nil
}
func (codec *clientCodec) ReadResponseBody(v interface{}) (err error) {
if v == nil {
return nil
}
if err = codec.response.Unmarshal(v); err != nil {
return err
}
return nil
}
func (codec *clientCodec) Close() error {
transport := codec.httpClient.Transport.(*http.Transport)
transport.CloseIdleConnections()
return nil
}
// NewClient returns instance of rpc.Client object, that is used to send request to xmlrpc service.
func NewClient(requrl string, transport http.RoundTripper) (*Client, error) {
if transport == nil {
transport = http.DefaultTransport
}
httpClient := &http.Client{Transport: transport}
jar, err := cookiejar.New(nil)
if err != nil {
return nil, err
}
u, err := url.Parse(requrl)
if err != nil {
return nil, err
}
codec := clientCodec{
url: u,
httpClient: httpClient,
ready: make(chan uint64),
responses: make(map[uint64]*http.Response),
cookies: jar,
}
return &Client{rpc.NewClientWithCodec(&codec)}, nil
}

449
vendor/github.com/kolo/xmlrpc/decoder.go generated vendored Normal file
View File

@ -0,0 +1,449 @@
package xmlrpc
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"io"
"reflect"
"strconv"
"strings"
"time"
)
const iso8601 = "20060102T15:04:05"
var (
// CharsetReader is a function to generate reader which converts a non UTF-8
// charset into UTF-8.
CharsetReader func(string, io.Reader) (io.Reader, error)
invalidXmlError = errors.New("invalid xml")
)
type TypeMismatchError string
func (e TypeMismatchError) Error() string { return string(e) }
type decoder struct {
*xml.Decoder
}
func unmarshal(data []byte, v interface{}) (err error) {
dec := &decoder{xml.NewDecoder(bytes.NewBuffer(data))}
if CharsetReader != nil {
dec.CharsetReader = CharsetReader
}
var tok xml.Token
for {
if tok, err = dec.Token(); err != nil {
return err
}
if t, ok := tok.(xml.StartElement); ok {
if t.Name.Local == "value" {
val := reflect.ValueOf(v)
if val.Kind() != reflect.Ptr {
return errors.New("non-pointer value passed to unmarshal")
}
if err = dec.decodeValue(val.Elem()); err != nil {
return err
}
break
}
}
}
// read until end of document
err = dec.Skip()
if err != nil && err != io.EOF {
return err
}
return nil
}
func (dec *decoder) decodeValue(val reflect.Value) error {
var tok xml.Token
var err error
if val.Kind() == reflect.Ptr {
if val.IsNil() {
val.Set(reflect.New(val.Type().Elem()))
}
val = val.Elem()
}
var typeName string
for {
if tok, err = dec.Token(); err != nil {
return err
}
if t, ok := tok.(xml.EndElement); ok {
if t.Name.Local == "value" {
return nil
} else {
return invalidXmlError
}
}
if t, ok := tok.(xml.StartElement); ok {
typeName = t.Name.Local
break
}
// Treat value data without type identifier as string
if t, ok := tok.(xml.CharData); ok {
if value := strings.TrimSpace(string(t)); value != "" {
if err = checkType(val, reflect.String); err != nil {
return err
}
val.SetString(value)
return nil
}
}
}
switch typeName {
case "struct":
ismap := false
pmap := val
valType := val.Type()
if err = checkType(val, reflect.Struct); err != nil {
if checkType(val, reflect.Map) == nil {
if valType.Key().Kind() != reflect.String {
return fmt.Errorf("only maps with string key type can be unmarshalled")
}
ismap = true
} else if checkType(val, reflect.Interface) == nil && val.IsNil() {
var dummy map[string]interface{}
pmap = reflect.New(reflect.TypeOf(dummy)).Elem()
valType = pmap.Type()
ismap = true
} else {
return err
}
}
var fields map[string]reflect.Value
if !ismap {
fields = make(map[string]reflect.Value)
for i := 0; i < valType.NumField(); i++ {
field := valType.Field(i)
fieldVal := val.FieldByName(field.Name)
if fieldVal.CanSet() {
if fn := field.Tag.Get("xmlrpc"); fn != "" {
fields[fn] = fieldVal
} else {
fields[field.Name] = fieldVal
}
}
}
} else {
// Create initial empty map
pmap.Set(reflect.MakeMap(valType))
}
// Process struct members.
StructLoop:
for {
if tok, err = dec.Token(); err != nil {
return err
}
switch t := tok.(type) {
case xml.StartElement:
if t.Name.Local != "member" {
return invalidXmlError
}
tagName, fieldName, err := dec.readTag()
if err != nil {
return err
}
if tagName != "name" {
return invalidXmlError
}
var fv reflect.Value
ok := true
if !ismap {
fv, ok = fields[string(fieldName)]
} else {
fv = reflect.New(valType.Elem())
}
if ok {
for {
if tok, err = dec.Token(); err != nil {
return err
}
if t, ok := tok.(xml.StartElement); ok && t.Name.Local == "value" {
if err = dec.decodeValue(fv); err != nil {
return err
}
// </value>
if err = dec.Skip(); err != nil {
return err
}
break
}
}
}
// </member>
if err = dec.Skip(); err != nil {
return err
}
if ismap {
pmap.SetMapIndex(reflect.ValueOf(string(fieldName)), reflect.Indirect(fv))
val.Set(pmap)
}
case xml.EndElement:
break StructLoop
}
}
case "array":
pslice := val
if checkType(val, reflect.Interface) == nil && val.IsNil() {
var dummy []interface{}
pslice = reflect.New(reflect.TypeOf(dummy)).Elem()
} else if err = checkType(val, reflect.Slice); err != nil {
return err
}
ArrayLoop:
for {
if tok, err = dec.Token(); err != nil {
return err
}
switch t := tok.(type) {
case xml.StartElement:
if t.Name.Local != "data" {
return invalidXmlError
}
slice := reflect.MakeSlice(pslice.Type(), 0, 0)
DataLoop:
for {
if tok, err = dec.Token(); err != nil {
return err
}
switch tt := tok.(type) {
case xml.StartElement:
if tt.Name.Local != "value" {
return invalidXmlError
}
v := reflect.New(pslice.Type().Elem())
if err = dec.decodeValue(v); err != nil {
return err
}
slice = reflect.Append(slice, v.Elem())
// </value>
if err = dec.Skip(); err != nil {
return err
}
case xml.EndElement:
pslice.Set(slice)
val.Set(pslice)
break DataLoop
}
}
case xml.EndElement:
break ArrayLoop
}
}
default:
if tok, err = dec.Token(); err != nil {
return err
}
var data []byte
switch t := tok.(type) {
case xml.EndElement:
return nil
case xml.CharData:
data = []byte(t.Copy())
default:
return invalidXmlError
}
switch typeName {
case "int", "i4", "i8":
if checkType(val, reflect.Interface) == nil && val.IsNil() {
i, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
return err
}
pi := reflect.New(reflect.TypeOf(i)).Elem()
pi.SetInt(i)
val.Set(pi)
} else if err = checkType(val, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64); err != nil {
return err
} else {
i, err := strconv.ParseInt(string(data), 10, val.Type().Bits())
if err != nil {
return err
}
val.SetInt(i)
}
case "string", "base64":
str := string(data)
if checkType(val, reflect.Interface) == nil && val.IsNil() {
pstr := reflect.New(reflect.TypeOf(str)).Elem()
pstr.SetString(str)
val.Set(pstr)
} else if err = checkType(val, reflect.String); err != nil {
return err
} else {
val.SetString(str)
}
case "dateTime.iso8601":
t, err := time.Parse(iso8601, string(data))
if err != nil {
return err
}
if checkType(val, reflect.Interface) == nil && val.IsNil() {
ptime := reflect.New(reflect.TypeOf(t)).Elem()
ptime.Set(reflect.ValueOf(t))
val.Set(ptime)
} else if _, ok := val.Interface().(time.Time); !ok {
return TypeMismatchError(fmt.Sprintf("error: type mismatch error - can't decode %v to time", val.Kind()))
} else {
val.Set(reflect.ValueOf(t))
}
case "boolean":
v, err := strconv.ParseBool(string(data))
if err != nil {
return err
}
if checkType(val, reflect.Interface) == nil && val.IsNil() {
pv := reflect.New(reflect.TypeOf(v)).Elem()
pv.SetBool(v)
val.Set(pv)
} else if err = checkType(val, reflect.Bool); err != nil {
return err
} else {
val.SetBool(v)
}
case "double":
if checkType(val, reflect.Interface) == nil && val.IsNil() {
i, err := strconv.ParseFloat(string(data), 64)
if err != nil {
return err
}
pdouble := reflect.New(reflect.TypeOf(i)).Elem()
pdouble.SetFloat(i)
val.Set(pdouble)
} else if err = checkType(val, reflect.Float32, reflect.Float64); err != nil {
return err
} else {
i, err := strconv.ParseFloat(string(data), val.Type().Bits())
if err != nil {
return err
}
val.SetFloat(i)
}
default:
return errors.New("unsupported type")
}
// </type>
if err = dec.Skip(); err != nil {
return err
}
}
return nil
}
func (dec *decoder) readTag() (string, []byte, error) {
var tok xml.Token
var err error
var name string
for {
if tok, err = dec.Token(); err != nil {
return "", nil, err
}
if t, ok := tok.(xml.StartElement); ok {
name = t.Name.Local
break
}
}
value, err := dec.readCharData()
if err != nil {
return "", nil, err
}
return name, value, dec.Skip()
}
func (dec *decoder) readCharData() ([]byte, error) {
var tok xml.Token
var err error
if tok, err = dec.Token(); err != nil {
return nil, err
}
if t, ok := tok.(xml.CharData); ok {
return []byte(t.Copy()), nil
} else {
return nil, invalidXmlError
}
}
func checkType(val reflect.Value, kinds ...reflect.Kind) error {
if len(kinds) == 0 {
return nil
}
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
match := false
for _, kind := range kinds {
if val.Kind() == kind {
match = true
break
}
}
if !match {
return TypeMismatchError(fmt.Sprintf("error: type mismatch - can't unmarshal %v to %v",
val.Kind(), kinds[0]))
}
return nil
}

164
vendor/github.com/kolo/xmlrpc/encoder.go generated vendored Normal file
View File

@ -0,0 +1,164 @@
package xmlrpc
import (
"bytes"
"encoding/xml"
"fmt"
"reflect"
"strconv"
"time"
)
type encodeFunc func(reflect.Value) ([]byte, error)
func marshal(v interface{}) ([]byte, error) {
if v == nil {
return []byte{}, nil
}
val := reflect.ValueOf(v)
return encodeValue(val)
}
func encodeValue(val reflect.Value) ([]byte, error) {
var b []byte
var err error
if val.Kind() == reflect.Ptr || val.Kind() == reflect.Interface {
if val.IsNil() {
return []byte("<value/>"), nil
}
val = val.Elem()
}
switch val.Kind() {
case reflect.Struct:
switch val.Interface().(type) {
case time.Time:
t := val.Interface().(time.Time)
b = []byte(fmt.Sprintf("<dateTime.iso8601>%s</dateTime.iso8601>", t.Format(iso8601)))
default:
b, err = encodeStruct(val)
}
case reflect.Map:
b, err = encodeMap(val)
case reflect.Slice:
b, err = encodeSlice(val)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
b = []byte(fmt.Sprintf("<int>%s</int>", strconv.FormatInt(val.Int(), 10)))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
b = []byte(fmt.Sprintf("<i4>%s</i4>", strconv.FormatUint(val.Uint(), 10)))
case reflect.Float32, reflect.Float64:
b = []byte(fmt.Sprintf("<double>%s</double>",
strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits())))
case reflect.Bool:
if val.Bool() {
b = []byte("<boolean>1</boolean>")
} else {
b = []byte("<boolean>0</boolean>")
}
case reflect.String:
var buf bytes.Buffer
xml.Escape(&buf, []byte(val.String()))
if _, ok := val.Interface().(Base64); ok {
b = []byte(fmt.Sprintf("<base64>%s</base64>", buf.String()))
} else {
b = []byte(fmt.Sprintf("<string>%s</string>", buf.String()))
}
default:
return nil, fmt.Errorf("xmlrpc encode error: unsupported type")
}
if err != nil {
return nil, err
}
return []byte(fmt.Sprintf("<value>%s</value>", string(b))), nil
}
func encodeStruct(val reflect.Value) ([]byte, error) {
var b bytes.Buffer
b.WriteString("<struct>")
t := val.Type()
for i := 0; i < t.NumField(); i++ {
b.WriteString("<member>")
f := t.Field(i)
name := f.Tag.Get("xmlrpc")
if name == "" {
name = f.Name
}
b.WriteString(fmt.Sprintf("<name>%s</name>", name))
p, err := encodeValue(val.FieldByName(f.Name))
if err != nil {
return nil, err
}
b.Write(p)
b.WriteString("</member>")
}
b.WriteString("</struct>")
return b.Bytes(), nil
}
func encodeMap(val reflect.Value) ([]byte, error) {
var t = val.Type()
if t.Key().Kind() != reflect.String {
return nil, fmt.Errorf("xmlrpc encode error: only maps with string keys are supported")
}
var b bytes.Buffer
b.WriteString("<struct>")
keys := val.MapKeys()
for i := 0; i < val.Len(); i++ {
key := keys[i]
kval := val.MapIndex(key)
b.WriteString("<member>")
b.WriteString(fmt.Sprintf("<name>%s</name>", key.String()))
p, err := encodeValue(kval)
if err != nil {
return nil, err
}
b.Write(p)
b.WriteString("</member>")
}
b.WriteString("</struct>")
return b.Bytes(), nil
}
func encodeSlice(val reflect.Value) ([]byte, error) {
var b bytes.Buffer
b.WriteString("<array><data>")
for i := 0; i < val.Len(); i++ {
p, err := encodeValue(val.Index(i))
if err != nil {
return nil, err
}
b.Write(p)
}
b.WriteString("</data></array>")
return b.Bytes(), nil
}

57
vendor/github.com/kolo/xmlrpc/request.go generated vendored Normal file
View File

@ -0,0 +1,57 @@
package xmlrpc
import (
"bytes"
"fmt"
"net/http"
)
func NewRequest(url string, method string, args interface{}) (*http.Request, error) {
var t []interface{}
var ok bool
if t, ok = args.([]interface{}); !ok {
if args != nil {
t = []interface{}{args}
}
}
body, err := EncodeMethodCall(method, t...)
if err != nil {
return nil, err
}
request, err := http.NewRequest("POST", url, bytes.NewReader(body))
if err != nil {
return nil, err
}
request.Header.Set("Content-Type", "text/xml")
request.Header.Set("Content-Length", fmt.Sprintf("%d", len(body)))
return request, nil
}
func EncodeMethodCall(method string, args ...interface{}) ([]byte, error) {
var b bytes.Buffer
b.WriteString(`<?xml version="1.0" encoding="UTF-8"?>`)
b.WriteString(fmt.Sprintf("<methodCall><methodName>%s</methodName>", method))
if args != nil {
b.WriteString("<params>")
for _, arg := range args {
p, err := marshal(arg)
if err != nil {
return nil, err
}
b.WriteString(fmt.Sprintf("<param>%s</param>", string(p)))
}
b.WriteString("</params>")
}
b.WriteString("</methodCall>")
return b.Bytes(), nil
}

52
vendor/github.com/kolo/xmlrpc/response.go generated vendored Normal file
View File

@ -0,0 +1,52 @@
package xmlrpc
import (
"regexp"
)
var (
faultRx = regexp.MustCompile(`<fault>(\s|\S)+</fault>`)
)
type failedResponse struct {
Code int `xmlrpc:"faultCode"`
Error string `xmlrpc:"faultString"`
}
func (r *failedResponse) err() error {
return &xmlrpcError{
code: r.Code,
err: r.Error,
}
}
type Response struct {
data []byte
}
func NewResponse(data []byte) *Response {
return &Response{
data: data,
}
}
func (r *Response) Failed() bool {
return faultRx.Match(r.data)
}
func (r *Response) Err() error {
failedResp := new(failedResponse)
if err := unmarshal(r.data, failedResp); err != nil {
return err
}
return failedResp.err()
}
func (r *Response) Unmarshal(v interface{}) error {
if err := unmarshal(r.data, v); err != nil {
return err
}
return nil
}

25
vendor/github.com/kolo/xmlrpc/test_server.rb generated vendored Normal file
View File

@ -0,0 +1,25 @@
# encoding: utf-8
require "xmlrpc/server"
class Service
def time
Time.now
end
def upcase(s)
s.upcase
end
def sum(x, y)
x + y
end
def error
raise XMLRPC::FaultException.new(500, "Server error")
end
end
server = XMLRPC::Server.new 5001, 'localhost'
server.add_handler "service", Service.new
server.serve

19
vendor/github.com/kolo/xmlrpc/xmlrpc.go generated vendored Normal file
View File

@ -0,0 +1,19 @@
package xmlrpc
import (
"fmt"
)
// xmlrpcError represents errors returned on xmlrpc request.
type xmlrpcError struct {
code int
err string
}
// Error() method implements Error interface
func (e *xmlrpcError) Error() string {
return fmt.Sprintf("error: \"%s\" code: %d", e.err, e.code)
}
// Base64 represents value in base64 encoding
type Base64 string