1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-04 17:47:00 +03:00

F 3219 template rework (#3837)

- fix template unmarshalling
 - rework and add template helpers
 - make template fully dynamic and add keys
 - enable marshalling of XML structs

Signed-off-by: Pierre Lafievre <pierre.lafievre@iguanesolutions.com>
This commit is contained in:
Pierre Lafievre 2019-11-06 16:00:15 +01:00 committed by Ruben S. Montero
parent b61cb55126
commit 548ac12a0a
92 changed files with 3160 additions and 963 deletions

View File

@ -26,7 +26,7 @@ func main() {
} }
// Retrieve zone informations // Retrieve zone informations
zone, err := controller.Zone(id).Info() zone, err := controller.Zone(id).Info(false)
if err != nil { if err != nil {
log.Fatalf("Zone id %d: %s", id, err) log.Fatalf("Zone id %d: %s", id, err)
} }

View File

@ -5,7 +5,9 @@ import (
"log" "log"
"github.com/OpenNebula/one/src/oca/go/src/goca" "github.com/OpenNebula/one/src/oca/go/src/goca"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm/keys"
) )
func main() { func main() {
@ -17,16 +19,19 @@ func main() {
// Build a string template. (No XML-RPC call done) // Build a string template. (No XML-RPC call done)
// To make a VM from an existing OpenNebula template, // To make a VM from an existing OpenNebula template,
// use template "Instantiate" method instead // use template "Instantiate" method instead
tpl := dyn.NewTemplateBuilder() tpl := vm.NewTemplate()
tpl.AddValue("name", "this-is-a-vm") tpl.Add(keys.Name, "this-is-a-vm")
tpl.AddValue("cpu", 1) tpl.CPU(1).Memory(64).VCPU(2)
tpl.AddValue("vcpu", "2")
tpl.AddValue("memory", "64")
// The image ID should exist to make this example work // The image ID should exist to make this example work
vec := tpl.NewVector("disk") disk := tpl.AddDisk()
vec.AddValue("image_id", "119") disk.Add(shared.ImageID, "119")
vec.AddValue("dev_prefix", "vd") disk.Add(shared.DevPrefix, "vd")
// The network ID should exist to make this example work
nic := tpl.AddNIC()
nic.Add(shared.NetworkID, "3")
nic.Add(shared.Model, "virtio")
// Create VM from template // Create VM from template
vmID, err := controller.VMs().Create(tpl.String(), false) vmID, err := controller.VMs().Create(tpl.String(), false)
@ -37,7 +42,7 @@ func main() {
vmCtrl := controller.VM(vmID) vmCtrl := controller.VM(vmID)
// Fetch informations of the created VM // Fetch informations of the created VM
vm, err := vmCtrl.Info() vm, err := vmCtrl.Info(false)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -20,7 +20,7 @@ func main() {
} }
// Fetch VM informations // Fetch VM informations
vm, err := controller.VM(id).Info() vm, err := controller.VM(id).Info(false)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -22,7 +22,7 @@ func main() {
for i := 0; i < len(vms.VMs); i++ { for i := 0; i < len(vms.VMs); i++ {
// This Info method, per VM instance, give us detailed informations on the instance // This Info method, per VM instance, give us detailed informations on the instance
// Check xsd files to see the difference // Check xsd files to see the difference
vm, err := controller.VM(vms.VMs[i].ID).Info() vm, err := controller.VM(vms.VMs[i].ID).Info(false)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -114,7 +114,7 @@ func (cc *ClusterController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds cluster content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.

View File

@ -118,8 +118,8 @@ func (dc *DatastoreController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update replaces the datastore contents.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new datastore contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (dc *DatastoreController) Update(tpl string, uType parameters.UpdateType) error { func (dc *DatastoreController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -145,8 +145,8 @@ func (dc *DocumentController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds document content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new document contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (dc *DocumentController) Update(tpl string, uType parameters.UpdateType) error { func (dc *DocumentController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -17,72 +17,72 @@
package dynamic package dynamic
import ( import (
"errors" "encoding/xml"
"fmt" "fmt"
"strconv"
"strings" "strings"
) )
// TemplateBuilder represents an OpenNebula syntax template. There is no XML-RPC call done. // Template represents an OpenNebula syntax template
type TemplateBuilder struct { type Template struct {
elements []TemplateBuilderElement Elements []Element
} }
// TemplateBuilderElement is an interface that must implement the String // Element is an interface that must implement the String
// function // function
type TemplateBuilderElement interface { type Element interface {
String() string String() string
Key() string
} }
// TemplateBuilderPair is a key / value pair // Pair is a key / value pair
type TemplateBuilderPair struct { type Pair struct {
key string XMLName xml.Name
value string Value string `xml:",innerxml"`
} }
// TemplateBuilderVector contains an array of keyvalue pairs // Vector contains an array of keyvalue pairs
type TemplateBuilderVector struct { type Vector struct {
key string XMLName xml.Name
pairs []TemplateBuilderPair Pairs []Pair
} }
// NewTemplateBuilder returns a new TemplateBuilder object type TemplateAny struct {
func NewTemplateBuilder() *TemplateBuilder { Template
return &TemplateBuilder{}
} }
// NewVector creates a new vector in the template // Key return the pair key
func (t *TemplateBuilder) NewVector(key string) *TemplateBuilderVector { func (t *Pair) Key() string { return t.XMLName.Local }
vector := &TemplateBuilderVector{key: key}
t.elements = append(t.elements, vector)
return vector
}
// String prints the TemplateBuilder in OpenNebula syntax // Key return the vector key
func (t *TemplateBuilder) String() string { func (t *Vector) Key() string { return t.XMLName.Local }
s := ""
// String prints the Template in OpenNebula syntax
func (t *Template) String() string {
var s strings.Builder
endToken := "\n" endToken := "\n"
for i, element := range t.elements { for i, element := range t.Elements {
if i == len(t.elements)-1 { if i == len(t.Elements)-1 {
endToken = "" endToken = ""
} }
s += element.String() + endToken s.WriteString(element.String() + endToken)
} }
return s return s.String()
} }
// String prints a TemplateBuilderPair in OpenNebula syntax // String prints a Pair in OpenNebula syntax
func (t *TemplateBuilderPair) String() string { func (p *Pair) String() string {
return fmt.Sprintf("%s=\"%s\"", t.key, t.value) return fmt.Sprintf("%s=\"%s\"", p.XMLName.Local, p.Value)
} }
func (t *TemplateBuilderVector) String() string { func (v *Vector) String() string {
s := fmt.Sprintf("%s=[\n", strings.ToUpper(t.key)) s := fmt.Sprintf("%s=[\n", strings.ToUpper(v.XMLName.Local))
endToken := ",\n" endToken := ",\n"
for i, pair := range t.pairs { for i, pair := range v.Pairs {
if i == len(t.pairs)-1 { if i == len(v.Pairs)-1 {
endToken = "" endToken = ""
} }
@ -94,40 +94,346 @@ func (t *TemplateBuilderVector) String() string {
return s return s
} }
// AddValue adds a new pair to a TemplateBuilder objects // GetPair retrieve a pair by it's key
func (t *TemplateBuilder) AddValue(key string, v interface{}) error { func (t *Template) GetPairs(key string) []*Pair {
pairs := make([]*Pair, 0, 1)
for i, _ := range t.Elements {
pair, ok := t.Elements[i].(*Pair)
if !ok {
continue
}
if pair.XMLName.Local != key {
continue
}
pairs = append(pairs, pair)
}
return pairs
}
// GetPair retrieve a pair by it's key
func (v *Vector) GetPairs(key string) []*Pair {
pairs := make([]*Pair, 0, 1)
for i, _ := range v.Pairs {
if v.Pairs[i].XMLName.Local != key {
continue
}
pairs = append(pairs, &v.Pairs[i])
}
return pairs
}
// GetPair retrieve a pair by key
func (t *Template) GetPair(key string) (*Pair, error) {
pairs := t.GetPairs(key)
switch len(pairs) {
case 0:
return nil, fmt.Errorf("Template GetPair: key %s not found", key)
case 1:
return pairs[0], nil
}
return nil, fmt.Errorf("Template GetPair: multiple key %s found", key)
}
// GetPair retrieve a pair by it's key
func (v *Vector) GetPair(key string) (*Pair, error) {
pairs := v.GetPairs(key)
switch len(pairs) {
case 0:
return nil, fmt.Errorf("Template GetPair: key %s not found", key)
case 1:
return pairs[0], nil
}
return nil, fmt.Errorf("Template GetPair: multiple key %s found", key)
}
// GetVectors retrieve slice of vectors by key
func (t *Template) GetVectors(key string) []*Vector {
vecs := make([]*Vector, 0, 1)
for i, _ := range t.Elements {
vec, ok := t.Elements[i].(*Vector)
if !ok {
continue
}
if vec.XMLName.Local != key {
continue
}
vecs = append(vecs, vec)
}
return vecs
}
// GetVector retrieve a vector by key
func (t *Template) GetVector(key string) (*Vector, error) {
vectors := t.GetVectors(key)
switch len(vectors) {
case 0:
return nil, fmt.Errorf("Template GetVector: key %s not found", key)
case 1:
return vectors[0], nil
}
return nil, fmt.Errorf("Template GetVector: multiple key %s found", key)
}
// GetStr allow to retrieve the value of a pair
func (t *Template) GetStr(key string) (string, error) {
pair, err := t.GetPair(key)
if err != nil {
return "", err
}
return pair.Value, nil
}
// GetStr allow to retrieve the value of a pair
func (t *Vector) GetStr(key string) (string, error) {
pair, err := t.GetPair(key)
if err != nil {
return "", err
}
return pair.Value, nil
}
// GetStrs allow to retrieve a slice of string from pairs with the same key
func (t *Template) GetStrs(key string) []string {
pairs := t.GetPairs(key)
strs := make([]string, len(pairs))
for i, p := range pairs {
strs[i] = p.Value
}
return strs
}
// GetStrs allow to retrieve a slice of string from pairs with the same key
func (v *Vector) GetStrs(key string) []string {
pairs := v.GetPairs(key)
strs := make([]string, len(pairs))
for i, p := range pairs {
strs[i] = p.Value
}
return strs
}
// GetInt returns a pair value as an int
func (t *Template) GetInt(key string) (int, error) {
pair, err := t.GetPair(key)
if err != nil {
return -1, err
}
intVal, err := strconv.ParseInt(pair.Value, 10, 0)
if err != nil {
return -1, err
}
return int(intVal), nil
}
// GetInt returns a pair value as an int
func (t *Vector) GetInt(key string) (int, error) {
pair, err := t.GetPair(key)
if err != nil {
return -1, err
}
intVal, err := strconv.ParseInt(pair.Value, 10, 0)
if err != nil {
return -1, err
}
return int(intVal), nil
}
// GetInts allow to retrieve a slice of int from pairs with the same key
func (t *Template) GetInts(key string) []int {
pairs := t.GetPairs(key)
ints := make([]int, 0, len(pairs))
for _, p := range pairs {
intVal, err := strconv.ParseInt(p.Value, 10, 0)
if err != nil {
continue
}
ints = append(ints, int(intVal))
}
return ints
}
// GetInts allow to retrieve a slice of int from pairs with the same key
func (v *Vector) GetInts(key string) []int {
pairs := v.GetPairs(key)
ints := make([]int, 0, len(pairs))
for _, p := range pairs {
intVal, err := strconv.ParseInt(p.Value, 10, 0)
if err != nil {
continue
}
ints = append(ints, int(intVal))
}
return ints
}
// GetFloat returns a pair value as an float
func (t *Template) GetFloat(key string) (float64, error) {
pair, err := t.GetPair(key)
if err != nil {
return -1, err
}
id, err := strconv.ParseFloat(pair.Value, 64)
if err != nil {
return -1, err
}
return id, nil
}
// GetFloat returns a pair value as an float
func (t *Vector) GetFloat(key string) (float64, error) {
pair, err := t.GetPair(key)
if err != nil {
return -1, err
}
id, err := strconv.ParseFloat(pair.Value, 64)
if err != nil {
return -1, err
}
return id, nil
}
// GetStrFromVec returns a pair value contained from a vector
func (t *Template) GetStrFromVec(vecKey, key string) (string, error) {
vector, err := t.GetVector(vecKey)
if err != nil {
return "", err
}
pair, err := vector.GetPair(key)
if err != nil {
return "", err
}
return pair.Value, nil
}
// template building
// NewTemplate returns a new Template object
func NewTemplate() *Template {
return &Template{}
}
// AddVector creates a new vector in the template
func (t *Template) AddVector(key string) *Vector {
vector := &Vector{XMLName: xml.Name{Local: key}}
t.Elements = append(t.Elements, vector)
return vector
}
// AddPair adds a new pair to a Template objects
func (t *Template) AddPair(key string, v interface{}) error {
var val string var val string
switch v := v.(type) { switch v := v.(type) {
default: default:
return errors.New("Unexpected type") return fmt.Errorf("AddPair: Unexpected type")
case float32, float64:
val = fmt.Sprintf("%f", v)
case int, uint: case int, uint:
val = fmt.Sprintf("%d", v) val = fmt.Sprintf("%d", v)
case string: case string:
val = v val = v
} }
pair := &TemplateBuilderPair{strings.ToUpper(key), val} pair := &Pair{XMLName: xml.Name{Local: strings.ToUpper(key)}, Value: val}
t.elements = append(t.elements, pair) t.Elements = append(t.Elements, pair)
return nil return nil
} }
// AddValue adds a new pair to a TemplateBuilderVector // AddPair adds a new pair to a Template
func (t *TemplateBuilderVector) AddValue(key string, v interface{}) error { func (t *Vector) AddPair(key string, v interface{}) error {
var val string var val string
switch v := v.(type) { switch v := v.(type) {
default: default:
return errors.New("Unexpected type") return fmt.Errorf("AddPair: Unexpected type")
case float32, float64:
val = fmt.Sprintf("%f", v)
case int, uint: case int, uint:
val = fmt.Sprintf("%d", v) val = fmt.Sprintf("%d", v)
case string: case string:
val = v val = v
} }
pair := TemplateBuilderPair{strings.ToUpper(key), val} pair := Pair{XMLName: xml.Name{Local: strings.ToUpper(key)}, Value: val}
t.pairs = append(t.pairs, pair) t.Pairs = append(t.Pairs, pair)
return nil return nil
} }
func (t *Template) AddPairToVec(vecKey, key string, value interface{}) error {
var vector *Vector
vectors := t.GetVectors(vecKey)
switch len(vectors) {
case 0:
vector = t.AddVector(vecKey)
case 1:
vector = vectors[0]
default:
return fmt.Errorf("Can't add pair to vector: multiple entries with key %s", key)
}
return vector.AddPair(key, value)
}
// Del remove an element from Template objects
func (t *Template) Del(key string) {
for i := 0; i < len(t.Elements); i++ {
if t.Elements[i].Key() != key {
continue
}
t.Elements = append(t.Elements[:i], t.Elements[i+1:]...)
}
}
// Del remove a pair from Template
func (t *Vector) Del(key string) {
for i := 0; i < len(t.Pairs); i++ {
if t.Pairs[i].XMLName.Local != key {
continue
}
t.Pairs = append(t.Pairs[:i], t.Pairs[i+1:]...)
}
}

View File

@ -21,7 +21,7 @@ import (
) )
func Example() { func Example() {
template := NewTemplateBuilder() template := NewTemplate()
// Main // Main
template.AddValue("cpu", 1) template.AddValue("cpu", 1)

View File

@ -0,0 +1,256 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 dynamic
import (
"encoding/xml"
"fmt"
"io"
)
// Dynamic template parsing
// There is two type of data in a TEMPLATE, Pair and Vector.
// A Vector contains a collection of Pair.
//
// In order to parse dynamically a TEMPLATE, we need to look at three next token
// to distinguish between these types.
//
// There is three types of tokens: StartElement, CharData, EndElement.
// While parsing a TEMPLATE, a problem may occur: when there is some chars between two opening tokens.
//
// Here is the two cases we want to avoid:
// tokPrev tok tokNext
// CharData StartElement StartElement
// StartElement CharData StartElement
// xmlPair contains temporary pair informations
type xmlPair struct {
XMLName xml.Name
Content string `xml:",chardata"`
}
// UnmarshalXML parse dynamically a template under the TEMPLATE token
func (t *Template) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// Ensure that first token is a StartElement
for {
tok, err := d.Token()
if err != nil {
if err.Error() == io.EOF.Error() {
break
}
return err
}
tokPrev := xml.CopyToken(tok)
switch tokPrev.(type) {
case xml.CharData:
// CharData X X
case xml.StartElement:
// StartElement X X
startTokPrev, _ := tokPrev.(xml.StartElement)
err := unmarshalTemplateElement(d, startTokPrev, t)
if err != nil {
return err
}
case xml.EndElement:
// EndElement X X
break
}
}
return nil
}
// unmarshalTemplateElement unmarshal only one element, a pair, or a vector
func unmarshalTemplateElement(d *xml.Decoder, tokPrev xml.StartElement, t *Template) error {
// Ensure that (tok, tokNext) != (Chardata, StartElement)
// if tokNext is a start element, then we should have a vector
tok, err := d.Token()
if err != nil {
if err.Error() == io.EOF.Error() {
return nil
}
return err
}
switch tok.(type) {
case xml.EndElement:
// StartElement EndElement X
case xml.StartElement:
// StartElement StartElement X --> it's a vector
var pair xmlPair
tokPairStart, ok := tok.(xml.StartElement)
if !ok {
return fmt.Errorf("unmarshalTemplateElement UnmarshalXML: start element attended")
}
vec := t.AddVector(tokPrev.Name.Local)
// Add first pair from tok
err := d.DecodeElement(&pair, &tokPairStart)
if err != nil {
return err
}
vec.AddPair(pair.XMLName.Local, pair.Content)
// unmarshal the rest of the vector
err = vec.UnmarshalXML(d, tokPrev)
if err != nil {
return fmt.Errorf("unmarshalTemplateElement vector UnmarshalXML: %s", err)
}
case xml.CharData:
// StartElement CharData X
// We need to know what is the token X
// As we call Token method again, we must save the chardata buffer in case we need it later
tokSav := xml.CopyToken(tok)
loop:
for {
// need to look at a third token to distinguish between pair and vector
tokNext, err := d.Token()
if err != nil {
if err.Error() == io.EOF.Error() {
return nil
}
return err
}
switch tokNext.(type) {
case xml.StartElement:
// StartElement CharData StartElement
// There is some characters between two opening tags,
// we shift last element to the left:
// StartElement StartElement X
tok = xml.CopyToken(tokNext)
case xml.EndElement:
// StartElement CharData EndElement --> it's a pair
// Or, after shift:
// StartElement StartElement EndElement --> not handled below
// It's a pair
tokData, ok := tokSav.(xml.CharData)
if ok {
t.AddPair(tokPrev.Name.Local, string(tokData))
}
break loop
case xml.CharData:
// StartElement CharData CharData --> should not occur
// Or, after shift:
// StartElement StartElement CharData --> it's a vector
// Need to copy, to avoid next Token call to rewrite the chardata buffer
tokData, _ := tokNext.(xml.CharData)
cdata := tokData.Copy()
startVec, ok := tok.(xml.StartElement)
if !ok {
return fmt.Errorf("unmarshalTemplateElement: start element expected")
}
vec := t.AddVector(tokPrev.Name.Local)
// consume EndElement of the first pair
_, err = d.Token()
if err != nil {
return err
}
vec.AddPair(startVec.Name.Local, string(cdata))
// unmarshal the rest of the vector
err = vec.UnmarshalXML(d, tokPrev)
if err != nil {
return fmt.Errorf("unmarshalTemplateElement vector UnmarshalXML: %s", err)
}
break loop
}
}
}
return nil
}
// UnmarshalXML parse dynamically a vector. Either a single vector, or inside of a TEMPLATE.
func (t *Vector) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// In case we unmarshal a simple vector, then we need to initialize it
if t.Pairs == nil {
t.XMLName.Local = start.Name.Local
t.Pairs = make([]Pair, 0, 2)
}
var pair xmlPair
loop:
for {
// Retrieve the next token
token, err := d.Token()
if err != nil {
if err.Error() == io.EOF.Error() {
return nil
}
return err
}
// Add a pair to the vector on a StartElement
switch token.(type) {
case xml.StartElement:
startEl, _ := token.(xml.StartElement)
err = d.DecodeElement(&pair, &startEl)
if err != nil {
return err
}
t.AddPair(pair.XMLName.Local, pair.Content)
case xml.CharData:
case xml.EndElement:
break loop
}
}
return nil
}

View File

@ -1,117 +0,0 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 dynamic
import (
"encoding/xml"
"fmt"
)
// Common part
// UnmatchedTag contains the tag informations
type UnmatchedTag struct {
XMLName xml.Name
Content string `xml:",chardata"`
//FullContent string `xml:",innerxml"` // for debug purpose, allow to see what's inside some tags
}
// Store unmatched tags in a map
// Inspired from: https://stackoverflow.com/questions/30928770/marshall-map-to-xml-in-go/33110881
// NOTE: to be used in flat xml part with distinct tag names
// If it's not flat: the hash will contains key with empty values
// If there is several tags with the same name : only the last value will be stored
// UnmatchedTagsMap store tags not handled by Unmarshal in a map, it should be labelled with `xml",any"`
type UnmatchedTagsMap map[string]string
func (u *UnmatchedTagsMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
if *u == nil {
*u = UnmatchedTagsMap{}
}
e := UnmatchedTag{}
err := d.DecodeElement(&e, &start)
if err != nil {
return err
}
// Fail the parsing of the whole xml
//if _, ok := (*u)[e.XMLName.Local]; ok {
// return fmt.Errorf("UnmatchedTagsMap: UnmarshalXML: Tag %s: multiple entries with the same name", e.XMLName.Local)
//}
(*u)[e.XMLName.Local] = e.Content
return nil
}
func (u *UnmatchedTagsMap) GetContentByName(name string) string {
return ((map[string]string)(*u))[name]
}
// Store unmatched tags in a slice
// NOTE: to be used in flat xml part
// UnmatchedTagsSlice store tags not handled by Unmarshal in a slice, it should be labelled with `xml",any"`
type UnmatchedTagsSlice struct {
Tags []UnmatchedTag
}
func (u *UnmatchedTagsSlice) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var e UnmatchedTag
err := d.DecodeElement(&e, &start)
if err != nil {
return err
}
u.Tags = append(u.Tags, e)
return nil
}
// Retrieve slice of tags with given name
func (u *UnmatchedTagsSlice) GetContentSliceByName(name string) []string {
content := make([]string, 0, 1)
for _, t := range u.Tags {
if t.XMLName.Local != name {
continue
}
content = append(content, t.Content)
}
return content
}
// Retrieve a tag with given name, fail if not present or present more than once
func (u *UnmatchedTagsSlice) GetContentByName(name string) (string, error) {
var content string
match := false
for _, t := range u.Tags {
if t.XMLName.Local != name {
continue
}
if match == true {
return "", fmt.Errorf("GetContentByName: multiple entries with the name %s", name)
}
content = t.Content
match = true
}
if match == false {
return "", fmt.Errorf("GetContentByName: tag %s not found", name)
}
return content, nil
}

View File

@ -114,8 +114,8 @@ func (gc *GroupController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds group content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new group contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (gc *GroupController) Update(tpl string, uType parameters.UpdateType) error { func (gc *GroupController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -115,7 +115,7 @@ func (hc *HookController) Delete() error {
return err return err
} }
// Update replaces the hook contents. // Update replaces the hook content.
// * tpl: The new hook contents. Syntax can be the usual attribute=value or XML. // * tpl: The new hook contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.

View File

@ -21,20 +21,21 @@ import (
"time" "time"
hk "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook" hk "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook/keys"
) )
var call = "one.zone.info" var call = "one.zone.info"
var HkTpl = `
NAME = hook-goca
TYPE = api
COMMAND = "/usr/bin/ls -l"
CALL = "` + call + `"
`
// Helper to create a Hook Network // Helper to create a Hook Network
func createHook(t *testing.T) (*hk.Hook, int) { func createHook(t *testing.T) (*hk.Hook, int) {
id, err := testCtrl.Hooks().Create(HkTpl)
tpl := hk.NewTemplate()
tpl.Add(keys.Name, "hook-goca")
tpl.Add(keys.Type, "api")
tpl.Add(keys.Command, "/usr/bin/ls -l")
tpl.AddPair("CALL", call)
id, err := testCtrl.Hooks().Create(tpl.String())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -87,7 +88,7 @@ func TestHook(t *testing.T) {
hook, err = hookC.Info(false) hook, err = hookC.Info(false)
if (len(hook.Log.ExecutionRecords) <= currentExecs) { if len(hook.Log.ExecutionRecords) <= currentExecs {
t.Errorf("Hook have not been triggered") t.Errorf("Hook have not been triggered")
} }
@ -100,11 +101,11 @@ func TestHook(t *testing.T) {
hook, err = hookC.Info(false) hook, err = hookC.Info(false)
if (len(hook.Log.ExecutionRecords) <= currentExecs) { if len(hook.Log.ExecutionRecords) <= currentExecs {
t.Errorf("Hook execution have not been retried") t.Errorf("Hook execution have not been retried")
} }
if (hook.Log.ExecutionRecords[len(hook.Log.ExecutionRecords) -1].Retry != "yes") { if hook.Log.ExecutionRecords[len(hook.Log.ExecutionRecords)-1].Retry != "yes" {
t.Errorf("Hook execution have not been retried") t.Errorf("Hook execution have not been retried")
} }

View File

@ -123,8 +123,8 @@ func (hc *HostController) Status(status int) error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds host content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new host contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (hc *HostController) Update(tpl string, uType parameters.UpdateType) error { func (hc *HostController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -142,8 +142,8 @@ func (ic *ImageController) Clone(cloneName string, dsid int) (int, error) {
return response.BodyInt(), nil return response.BodyInt(), nil
} }
// Update replaces the cluster cluster contents. // Update adds image content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new image contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (ic *ImageController) Update(tpl string, uType parameters.UpdateType) error { func (ic *ImageController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -21,6 +21,7 @@ import (
"testing" "testing"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image/keys"
) )
var imageTpl = ` var imageTpl = `
@ -51,6 +52,12 @@ func ImageExpectState(imageC *ImageController, state string) func() bool {
// Helper to create a Image // Helper to create a Image
func createImage(t *testing.T) (*image.Image, int) { func createImage(t *testing.T) (*image.Image, int) {
tpl := image.NewTemplate()
tpl.Add(keys.Name, "test-image")
tpl.Add(keys.Size, "1")
tpl.SetType(image.Datablock)
// Datastore ID 1 means default for image // Datastore ID 1 means default for image
id, err := testCtrl.Images().Create(imageTpl, 1) id, err := testCtrl.Images().Create(imageTpl, 1)
if err != nil { if err != nil {

View File

@ -136,8 +136,8 @@ func (mc *MarketPlaceController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds marketplace content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new marketplace contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (mc *MarketPlaceController) Update(tpl string, uType parameters.UpdateType) error { func (mc *MarketPlaceController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -20,6 +20,7 @@ import (
"testing" "testing"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplace" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplace"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplace/keys"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
@ -28,13 +29,14 @@ func TestMarketplace(t *testing.T) {
var market *marketplace.MarketPlace var market *marketplace.MarketPlace
var mkt_template string = "NAME = \"" + mkt_name + "\"\n" + tpl := marketplace.NewTemplate()
"MARKET_MAD = \"http\"\n" + tpl.Add(keys.Name, mkt_name)
"BASE_URL = \"http://url/\"\n" + tpl.Add(keys.MarketMAD, "http")
"PUBLIC_DIR = \"/var/loca/market-http\"" tpl.Add(keys.BaseUrl, "http://url/")
tpl.Add(keys.PublicDir, "/var/loca/market-http")
//Create Marketpkace //Create Marketpkace
market_id, err := testCtrl.MarketPlaces().Create(mkt_template) market_id, err := testCtrl.MarketPlaces().Create(tpl.String())
if err != nil { if err != nil {
t.Fatalf("Test failed:\n" + err.Error()) t.Fatalf("Test failed:\n" + err.Error())
} }
@ -70,7 +72,7 @@ func TestMarketplace(t *testing.T) {
} }
actual_mm := market.MarketMad actual_mm := market.MarketMad
actual_1, err := market.Template.Dynamic.GetContentByName("ATT1") actual_1, err := market.Template.GetStr("ATT1")
if err != nil { if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error())
} else { } else {

View File

@ -144,8 +144,8 @@ func (mc *MarketPlaceAppController) Enable(enable bool) error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds marketplace app content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new marketplace contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (mc *MarketPlaceAppController) Update(tpl string, uType parameters.UpdateType) error { func (mc *MarketPlaceAppController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -21,26 +21,34 @@ import (
"testing" "testing"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplaceapp" imgkeys "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image/keys"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplace"
mktkeys "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplace/keys"
mktapp "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplaceapp"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplaceapp/keys"
) )
func TestMarketplaceApp(t *testing.T) { func TestMarketplaceApp(t *testing.T) {
var mkt_app_name string = "new_mkt_app" var mkt_app_name string = "new_mkt_app"
var mkt_app *marketplaceapp.MarketPlaceApp var mkt_app *mktapp.MarketPlaceApp
var mkt_app_tmpl string
var mkt_img_id int var mkt_img_id int
var market_id int var market_id int
var err error var err error
mkt_app_tmpl = "NAME= \"" + mkt_app_name + "\"\n" + mkt_app_tmpl := mktapp.NewTemplate()
"TYPE=image\n" mkt_app_tmpl.Add(keys.Name, mkt_app_name)
mkt_app_tmpl.Add(keys.Size, "1")
mkt_app_tmpl.SetType(mktapp.Image)
//Create an image //Create an image
img_tmpl := "NAME = \"test_img_go" + "\"\n" +
"TYPE = DATABLOCK\n" +
"SIZE = 1\n"
mkt_img_id, err = testCtrl.Images().Create(img_tmpl, 1) img_tmpl := image.NewTemplate()
img_tmpl.Add(imgkeys.Name, "test_img_go")
img_tmpl.Add(imgkeys.Size, "1")
img_tmpl.SetType(image.Datablock)
mkt_img_id, err = testCtrl.Images().Create(img_tmpl.String(), 1)
if err != nil { if err != nil {
t.Fatalf("Test failed:\n" + err.Error()) t.Fatalf("Test failed:\n" + err.Error())
} }
@ -58,24 +66,25 @@ func TestMarketplaceApp(t *testing.T) {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
} }
mkt_app_tmpl += "ORIGIN_ID=" + strconv.Itoa(int(mkt_img_id)) + "\n" mkt_app_tmpl.Add(keys.OriginID, strconv.Itoa(int(mkt_img_id)))
//Create a marketplace //Create a marketplace
mkt_tmpl := "NAME = \"mkt-app-test\"\n" +
"MARKET_MAD = \"http\"\n" +
"BASE_URL = \"http://url/\"\n" +
"PUBLIC_DIR = \"/var/loca/market-http\"\n"
market_id, err = testCtrl.MarketPlaces().Create(mkt_tmpl) mkt_tmpl := marketplace.NewTemplate()
mkt_tmpl.Add(mktkeys.Name, "mkt-app-test")
mkt_tmpl.Add(mktkeys.MarketMAD, "http")
mkt_tmpl.Add(mktkeys.BaseUrl, "http://url/")
mkt_tmpl.Add(mktkeys.PublicDir, "/var/loca/market-http")
market_id, err = testCtrl.MarketPlaces().Create(mkt_tmpl.String())
if err != nil { if err != nil {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
} }
mkt_app_tmpl += "MARKETPLACE_ID=\"" + strconv.Itoa(int(market_id)) + "\"\n" mkt_app_tmpl.Add(keys.MarketPlaceID, strconv.Itoa(int(market_id)))
//Create MarketplaceApp //Create MarketplaceApp
app_id, err := testCtrl.MarketPlaceApps().Create(mkt_app_tmpl, int(market_id)) app_id, err := testCtrl.MarketPlaceApps().Create(mkt_app_tmpl.String(), int(market_id))
if err != nil { if err != nil {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())

View File

@ -16,19 +16,23 @@
package acl package acl
import "encoding/xml"
// Pool represents an OpenNebula ACL pool // Pool represents an OpenNebula ACL pool
type Pool struct { type Pool struct {
ACLs []ACL `xml:"ACL"` XMLName xml.Name `xml:"ACL_POOL"`
ACLs []ACL `xml:"ACL"`
} }
// ACL represents an OpenNebula ACL // ACL represents an OpenNebula ACL
type ACL struct { type ACL struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"ACL"`
User string `xml:"USER"` ID int `xml:"ID,omitempty"`
Resource string `xml:"RESOURCE"` User string `xml:"USER,omitempty"`
Rights string `xml:"RIGHTS"` Resource string `xml:"RESOURCE,omitempty"`
Zone string `xml:"ZONE"` Rights string `xml:"RIGHTS,omitempty"`
String string `xml:"STRING"` Zone string `xml:"ZONE,omitempty"`
String string `xml:"STRING,omitempty"`
} }
type Users uint type Users uint

View File

@ -16,26 +16,25 @@
package cluster package cluster
import dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" import (
"encoding/xml"
shared "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
)
// Pool represents an OpenNebula Cluster pool // Pool represents an OpenNebula Cluster pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"CLUSTER_POOL"`
Clusters []Cluster `xml:"CLUSTER"` Clusters []Cluster `xml:"CLUSTER"`
} }
// Cluster represents an OpenNebula Cluster // Cluster represents an OpenNebula Cluster
type Cluster struct { type Cluster struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"CLUSTER"`
Name string `xml:"NAME"` ID int `xml:"ID,omitempty"`
HostsID []int `xml:"HOSTS>ID"` Name string `xml:"NAME"`
DatastoresID []int `xml:"DATASTORES>ID"` Hosts shared.EntitiesID `xml:"HOSTS,omitempty"`
VnetsID []int `xml:"VNETS>ID"` Datastores shared.EntitiesID `xml:"DATASTORES,omitempty"`
Template Template `xml:"TEMPLATE"` Vnets shared.EntitiesID `xml:"VNETS,omitempty"`
} Template Template `xml:"TEMPLATE,omitempty"`
type Template struct {
// Example of reservation: https://github.com/OpenNebula/addon-storpool/blob/ba9dd3462b369440cf618c4396c266f02e50f36f/misc/reserved.sh
ReservedMem string `xml:"RESERVED_MEM"`
ReservedCPU string `xml:"RESERVED_CPU"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }

View File

@ -0,0 +1,26 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type for cluster template keys.
type Template string
const (
Name Template = "NAME"
ReservedMem Template = "RESERVED_MEM"
ReservedCPU Template = "RESERVED_CPU"
)

View File

@ -0,0 +1,42 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 cluster
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/cluster/keys"
)
// Template is a cluster template
type Template struct {
dyn.Template
}
// Get returns the string value for an cluster template keys
func (n *Template) Get(key keys.Template) (string, error) {
return n.GetStr(string(key))
}
// GetI returns the integer value for a cluster template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds an cluster template key, value pair
func (n *Template) Add(key keys.Template, value string) {
n.AddPair(string(key), value)
}

View File

@ -1,42 +1,40 @@
package datastore package datastore
import ( import (
"encoding/xml"
"fmt" "fmt"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Datastore pool // Pool represents an OpenNebula Datastore pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"DATASTORE_POOL"`
Datastores []Datastore `xml:"DATASTORE"` Datastores []Datastore `xml:"DATASTORE"`
} }
// Datastore represents an OpenNebula Datastore // Datastore represents an OpenNebula Datastore
type Datastore struct { type Datastore struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"DATASTORE"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
DSMad string `xml:"DS_MAD"` DSMad string `xml:"DS_MAD,omitempty"`
TMMad string `xml:"TM_MAD"` TMMad string `xml:"TM_MAD,omitempty"`
BasePath string `xml:"BASE_PATH"` BasePath string `xml:"BASE_PATH,omitempty"`
Type string `xml:"TYPE"` Type string `xml:"TYPE,omitempty"`
DiskType string `xml:"DISK_TYPE"` DiskType string `xml:"DISK_TYPE,omitempty"`
StateRaw int `xml:"STATE"` StateRaw int `xml:"STATE,omitempty"`
ClustersID []int `xml:"CLUSTERS>ID"` Clusters shared.EntitiesID `xml:"CLUSTERS,omitempty"`
TotalMB int `xml:"TOTAL_MB"` TotalMB int `xml:"TOTAL_MB,omitempty"`
FreeMB int `xml:"FREE_MB"` FreeMB int `xml:"FREE_MB,omitempty"`
UsedMB int `xml:"USED_MB"` UsedMB int `xml:"USED_MB,omitempty"`
ImagesID []int `xml:"IMAGES>ID"` Images shared.EntitiesID `xml:"IMAGES,omitempty"`
Template Template `xml:"TEMPLATE"` Template Template `xml:"TEMPLATE,omitempty"`
}
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }
// State is the state of an OpenNebula datastore // State is the state of an OpenNebula datastore

View File

@ -0,0 +1,37 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type for datastore template keys.
type Template string
const (
Name Template = "NAME"
Type Template = "TYPE"
DSMAD Template = "DS_MAD"
TMMAD Template = "TM_MAD"
RestrictedDirs Template = "RESTRICTED_DIRS"
SafeDirs Template = "SAFE_DIRS"
NoDecompress Template = "NO_DECOMPRESS"
LimitTransferBW Template = "LIMIT_TRANSFER_BW"
DatastoreCapacityCheck Template = "DATASTORE_CAPACITY_CHECK"
LimitMB Template = "LIMIT_MB"
BridgeList Template = "BRIDGE_LIST"
StagingDir Template = "STAGING_DIR"
Driver Template = "DRIVER"
CompatibleSysDs Template = "COMPATIBLE_SYS_DS"
)

View File

@ -0,0 +1,66 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 datastore
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/datastore/keys"
)
type Types string
const (
System Types = "SYSTEM"
Image Types = "IMAGE"
File Types = "FILE"
)
// Template is a datastore template
type Template struct {
dyn.Template
}
// NewTemplate returns a new datastore Template object
func NewTemplate() *Template {
return &Template{}
}
// Get returns the string value for an datastore keys
func (n *Template) Get(key keys.Template) (string, error) {
return n.GetStr(string(key))
}
// GetI returns the integer value for a datastore template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds an datastore key, value pair
func (n *Template) Add(key keys.Template, value string) {
n.AddPair(string(key), value)
}
// SetType set a Datastore type
func (t *Template) SetType(typ Types) {
pair, err := t.GetPair(string(keys.Type))
if err != nil {
t.AddPair(string(keys.Type), string(typ))
} else {
pair.Value = string(typ)
}
}

View File

@ -17,29 +17,29 @@
package document package document
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Document pool // Pool represents an OpenNebula Document pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"DOCUMENT_POOL"`
Documents []Document `xml:"DOCUMENT"` Documents []Document `xml:"DOCUMENT"`
} }
// Document represents an OpenNebula Document // Document represents an OpenNebula Document
type Document struct { type Document struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"DOCUMENT"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
Type string `xml:"TYPE"` Type string `xml:"TYPE"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
LockInfos *shared.Lock `xml:"LOCK"` LockInfos *shared.Lock `xml:"LOCK,omitempty"`
Template Template `xml:"TEMPLATE"` Template dyn.Template `xml:"TEMPLATE"`
}
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }

View File

@ -17,30 +17,36 @@
package group package group
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula GroupPool // Pool represents an OpenNebula GroupPool
type Pool struct { type Pool struct {
Groups []Group `xml:"GROUP"` XMLName xml.Name `xml:"GROUP_POOL"`
Quotas []shared.Quotas `xml:"QUOTAS"` Groups []GroupShort `xml:"GROUP"`
DefaultUserQuotas shared.QuotasList `xml:"DEFAULT_USER_QUOTAS"` Quotas []shared.Quotas `xml:"QUOTAS"`
DefaultGroupQuotas shared.QuotasList `xml:"DEFAULT_GROUP_QUOTAS"`
}
// GroupShort keeps summary information on a group
type GroupShort struct {
XMLName xml.Name `xml:"GROUP"`
ID int `xml:"ID,omitempty"`
Name string `xml:"NAME"`
Template dyn.Template `xml:"TEMPLATE"`
Users shared.EntitiesID `xml:"USERS,omitempty"`
Admins shared.EntitiesID `xml:"ADMINS,omitempty"`
} }
// Group represents an OpenNebula Group // Group represents an OpenNebula Group
type Group struct { type Group struct {
ID int `xml:"ID"` GroupShort
Name string `xml:"NAME"`
UsersID []int `xml:"USERS>ID"`
AdminsID []int `xml:"ADMINS>ID"`
Template Template `xml:"TEMPLATE"`
// Variable part between one.grouppool.info and one.group.info // Variable part between one.groupool.info and one.group.info
shared.QuotasList shared.QuotasList
DefaultUserQuotas shared.QuotasList `xml:"DEFAULT_USER_QUOTAS"` DefaultGroupQuotas shared.QuotasList `xml:"DEFAULT_GROUP_QUOTAS"`
}
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }

View File

@ -16,35 +16,26 @@
package hook package hook
import ( import "encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
)
// Pool represents an OpenNebula Host pool // Pool represents an OpenNebula Hook pool
type Pool struct { type Pool struct {
Hooks []Hook `xml:"HOOK"` XMLName xml.Name `xml:"HOOK_POOL"`
Hooks []Hook `xml:"HOOK"`
} }
// Host represents an OpenNebula Host // Hook represents an OpenNebula Hook
type Hook struct { type Hook struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"HOOK"`
Name string `xml:"NAME"` ID int `xml:"ID"`
Type string `xml:"TYPE"` Name string `xml:"NAME"`
Template Template `xml:"TEMPLATE"` Type string `xml:"TYPE"`
Log HookLog `xml:"HOOKLOG"` Template Template `xml:"TEMPLATE"`
} Log HookLog `xml:"HOOKLOG"`
type Template struct {
// Example of reservation: https://github.com/OpenNebula/addon-storpool/blob/ba9dd3462b369440cf618c4396c266f02e50f36f/misc/reserved.sh
Arguments string `xml:"ARGUMENTS"`
ArgumentsSTDIN string `xml:"ARGUMENTS_STDIN"`
Command string `xml:"COMMAND"`
Remote string `xml:"REMOTE"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }
type HookLog struct { type HookLog struct {
ExecutionRecords []ExecutionRecord `xml:"HOOK_EXECUTION_RECORD"` ExecutionRecords []ExecutionRecord `xml:"HOOK_EXECUTION_RECORD"`
} }
type ExecutionRecord struct { type ExecutionRecord struct {

View File

@ -0,0 +1,29 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Keys is a type used to enumerate hook template keys
type Template string
const (
Name Template = "NAME"
Type Template = "TYPE"
Arguments Template = "ARGUMENTS"
ArgumentsSTDIN Template = "ARGUMENTS_STDIN"
Command Template = "COMMAND"
Remote Template = "REMOTE"
)

View File

@ -0,0 +1,56 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 hook
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook/keys"
)
type Types string
const (
System Types = "SYSTEM"
Image Types = "IMAGE"
File Types = "FILE"
)
// Template is a hook template
// Example of reservation: https://github.com/OpenNebula/addon-storpool/blob/ba9dd3462b369440cf618c4396c266f02e50f36f/misc/reserved.sh
type Template struct {
dyn.Template
}
// NewTemplate returns a hook Template structure
func NewTemplate() *Template {
return &Template{}
}
// Get returns the string value for an hook template keys
func (n *Template) Get(key keys.Template) (string, error) {
return n.GetStr(string(key))
}
// GetI returns the integer value for a hook template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds an hook template key, value pair
func (n *Template) Add(key keys.Template, value string) {
n.AddPair(string(key), value)
}

View File

@ -17,136 +17,60 @@
package host package host
import ( import (
"fmt" "encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Host pool // Pool represents an OpenNebula Host pool
type Pool struct { type Pool struct {
Hosts []Host `xml:"HOST"` XMLName xml.Name `xml:"HOST_POOL"`
Hosts []Host `xml:"HOST"`
} }
// Host represents an OpenNebula Host // Host represents an OpenNebula Host
type Host struct { type Host struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"HOST"`
Name string `xml:"NAME"` ID int `xml:"ID,omitempty"`
StateRaw int `xml:"STATE"` Name string `xml:"NAME"`
IMMAD string `xml:"IM_MAD"` StateRaw int `xml:"STATE,omitempty"`
VMMAD string `xml:"VM_MAD"` IMMAD string `xml:"IM_MAD,omitempty"`
LastMonTime int `xml:"LAST_MON_TIME"` VMMAD string `xml:"VM_MAD,omitempty"`
ClusterID int `xml:"CLUSTER_ID"` LastMonTime int `xml:"LAST_MON_TIME,omitempty"`
Cluster string `xml:"CLUSTER"` ClusterID int `xml:"CLUSTER_ID,omitempty"`
Share Share `xml:"HOST_SHARE"` Cluster string `xml:"CLUSTER,omitempty"`
VMsID []int `xml:"VMS>ID"` Share Share `xml:"HOST_SHARE,omitempty"`
Template Template `xml:"TEMPLATE"` VMs shared.EntitiesID `xml:"VMS,omitempty"`
Template Template `xml:"TEMPLATE,omitempty"`
} }
type Share struct { type Share struct {
DiskUsage int `xml:"DISK_USAGE"` DiskUsage int `xml:"DISK_USAGE,omitempty"`
MemUsage int `xml:"MEM_USAGE"` MemUsage int `xml:"MEM_USAGE,omitempty"`
CPUUsage int `xml:"CPU_USAGE"` CPUUsage int `xml:"CPU_USAGE,omitempty"`
TotalMem int `xml:"TOTAL_MEM"` TotalMem int `xml:"TOTAL_MEM,omitempty"`
TotalCPU int `xml:"TOTAL_CPU"` TotalCPU int `xml:"TOTAL_CPU,omitempty"`
MaxDisk int `xml:"MAX_DISK"` MaxDisk int `xml:"MAX_DISK,omitempty"`
MaxMem int `xml:"MAX_MEM"` MaxMem int `xml:"MAX_MEM,omitempty"`
MaxCPU int `xml:"MAX_CPU"` MaxCPU int `xml:"MAX_CPU,omitempty"`
FreeDisk int `xml:"FREE_DISK"` FreeDisk int `xml:"FREE_DISK,omitempty"`
FreeMem int `xml:"FREE_MEM"` FreeMem int `xml:"FREE_MEM,omitempty"`
FreeCPU int `xml:"FREE_CPU"` FreeCPU int `xml:"FREE_CPU,omitempty"`
UsedDisk int `xml:"USED_DISK"` UsedDisk int `xml:"USED_DISK,omitempty"`
UsedMem int `xml:"USED_MEM"` UsedMem int `xml:"USED_MEM,omitempty"`
UsedCPU int `xml:"USED_CPU"` UsedCPU int `xml:"USED_CPU,omitempty"`
RunningVMs int `xml:"RUNNING_VMS"` RunningVMs int `xml:"RUNNING_VMS,omitempty"`
Stores []DS `xml:"DATASTORES>DS"` Datastores []Datastores `xml:"DATASTORES>DS,omitempty"`
PCIDevices interface{} `xml:"PCI_DEVICES>PCI"` PCIDevices interface{} `xml:"PCI_DEVICES>PCI,omitempty"`
} }
type DS struct { type Datastores struct {
ID int `xml:"ID"` ID int `xml:"ID,omitempty"`
UsedMB int `xml:"USED_MB"` UsedMB int `xml:"USED_MB,omitempty"`
FreeMB int `xml:"FREE_MB"` FreeMB int `xml:"FREE_MB,omitempty"`
TotalMB int `xml:"TOTAL_MB"` TotalMB int `xml:"TOTAL_MB,omitempty"`
}
type Template struct {
// Example of reservation: https://github.com/OpenNebula/addon-storpool/blob/ba9dd3462b369440cf618c4396c266f02e50f36f/misc/reserved.sh
ReservedMem int `xml:"RESERVED_MEM"`
ReservedCPU int `xml:"RESERVED_CPU"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
// HostState is the state of an OpenNebula Host
type State int
const (
// Init host is in the initial state when enabled
Init = iota
// MonitoringMonitored host is being monitored (from monitored state)
MonitoringMonitored
// Monitored host has been successfully monitored
Monitored
// Error host has encountered an error ocurred while monitoring
Error
// Disabled host is disabled
Disabled
// MonitoringError host is being monitored (from error state)
MonitoringError
// MonitoringInit host is being monitored (from init state)
MonitoringInit
// MonitoringDisabled host is being monitored (from disabled state)
MonitoringDisabled
// Offline host is totally offline
Offline
)
func (s State) isValid() bool {
if s >= Init && s <= Offline {
return true
}
return false
}
func (s State) String() string {
return [...]string{
"INIT",
"MONITORING_MONITORED",
"MONITORED",
"ERROR",
"DISABLED",
"MONITORING_ERROR",
"MONITORING_INIT",
"MONITORING_DISABLED",
"OFFLINE",
}[s]
}
// State looks up the state of the image and returns the ImageState
func (host *Host) State() (State, error) {
state := State(host.StateRaw)
if !state.isValid() {
return -1, fmt.Errorf("Host State: this state value is not currently handled: %d\n", host.StateRaw)
}
return state, nil
}
// StateString returns the state in string format
func (host *Host) StateString() (string, error) {
state := State(host.StateRaw)
if !state.isValid() {
return "", fmt.Errorf("Host StateString: this state value is not currently handled: %d\n", host.StateRaw)
}
return state.String(), nil
} }

View File

@ -0,0 +1,28 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type used to enumerate host template keys
type Template string
const (
Name Template = "NAME"
IMMAD Template = "IM_MAD"
VMMAD Template = "VM_MAD"
ReservedMem Template = "RESERVED_MEM"
ReservedCPU Template = "RESERVED_CPU"
)

View File

@ -0,0 +1,92 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 host
import (
"fmt"
)
// HostState is the state of an OpenNebula Host
type State int
const (
// Init host is in the initial state when enabled
Init = iota
// MonitoringMonitored host is being monitored (from monitored state)
MonitoringMonitored
// Monitored host has been successfully monitored
Monitored
// Error host has encountered an error ocurred while monitoring
Error
// Disabled host is disabled
Disabled
// MonitoringError host is being monitored (from error state)
MonitoringError
// MonitoringInit host is being monitored (from init state)
MonitoringInit
// MonitoringDisabled host is being monitored (from disabled state)
MonitoringDisabled
// Offline host is totally offline
Offline
)
func (s State) isValid() bool {
if s >= Init && s <= Offline {
return true
}
return false
}
func (s State) String() string {
return [...]string{
"INIT",
"MONITORING_MONITORED",
"MONITORED",
"ERROR",
"DISABLED",
"MONITORING_ERROR",
"MONITORING_INIT",
"MONITORING_DISABLED",
"OFFLINE",
}[s]
}
// State looks up the state of the image and returns the ImageState
func (host *Host) State() (State, error) {
state := State(host.StateRaw)
if !state.isValid() {
return -1, fmt.Errorf("Host State: this state value is not currently handled: %d\n", host.StateRaw)
}
return state, nil
}
// StateString returns the state in string format
func (host *Host) StateString() (string, error) {
state := State(host.StateRaw)
if !state.isValid() {
return "", fmt.Errorf("Host StateString: this state value is not currently handled: %d\n", host.StateRaw)
}
return state.String(), nil
}

View File

@ -0,0 +1,47 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 host
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/host/keys"
)
// Template is a host template
type Template struct {
dyn.Template
}
// NewTemplate returns a new host Template object
func NewTemplate() *Template {
return &Template{}
}
// Get returns the string value for a host template
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for an host template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a host template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}

View File

@ -17,59 +17,49 @@
package image package image
import ( import (
"encoding/xml"
"fmt" "fmt"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Image pool // Pool represents an OpenNebula Image pool
type Pool struct { type Pool struct {
Images []Image `xml:"IMAGE"` XMLName xml.Name `xml:"IMAGE_POOL"`
Images []Image `xml:"IMAGE"`
} }
// Image represents an OpenNebula Image // Image represents an OpenNebula Image
type Image struct { type Image struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"IMAGE"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
Name string `xml:"NAME"` GName string `xml:"GNAME,omitempty"`
LockInfos *shared.Lock `xml:"LOCK"` Name string `xml:"NAME"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` LockInfos *shared.Lock `xml:"LOCK,omitempty"`
Type string `xml:"TYPE"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
DiskType int `xml:"DISK_TYPE"` Type *int `xml:"TYPE,omitempty"`
PersistentValue int `xml:"PERSISTENT"` DiskType *int `xml:"DISK_TYPE,omitempty"`
RegTime int `xml:"REGTIME"` Persistent *int `xml:"PERSISTENT,omitempty"`
Source string `xml:"SOURCE"` RegTime int `xml:"REGTIME,omitempty"`
Path string `xml:"PATH"` Source string `xml:"SOURCE,omitempty"`
FsType string `xml:"FSTYPE"` Path string `xml:"PATH,omitempty"`
Size int `xml:"SIZE"` FsType string `xml:"FSTYPE,omitempty"`
StateRaw int `xml:"STATE"` Size int `xml:"SIZE,omitempty"`
RunningVMs int `xml:"RUNNING_VMS"` StateRaw int `xml:"STATE,omitempty"`
CloningOps int `xml:"CLONING_OPS"` RunningVMs int `xml:"RUNNING_VMS,omitempty"`
CloningID int `xml:"CLONING_ID"` CloningOps int `xml:"CLONING_OPS,omitempty"`
TargetSnapshot int `xml:"TARGET_SNAPSHOT"` CloningID int `xml:"CLONING_ID,omitempty"`
DatastoreID int `xml:"DATASTORE_ID"` TargetSnapshot int `xml:"TARGET_SNAPSHOT,omitempty"`
Datastore string `xml:"DATASTORE"` DatastoreID *int `xml:"DATASTORE_ID,omitempty"`
VMsID []int `xml:"VMS>ID"` Datastore string `xml:"DATASTORE,omitempty"`
ClonesID []int `xml:"CLONES>ID"` VMs shared.EntitiesID `xml:"VMS,omitempty"`
AppClonesID []int `xml:"APP_CLONES>ID"` Clones shared.EntitiesID `xml:"CLONES,omitempty"`
Snapshots Snapshot `xml:"SNAPSHOTS"` AppClones shared.EntitiesID `xml:"APP_CLONES,omitempty"`
Template Template `xml:"TEMPLATE"` Snapshots shared.DiskSnapshot `xml:"SNAPSHOTS,omitempty"`
} Template Template `xml:"TEMPLATE"`
// Snapshot entity related
type Snapshot struct {
AllowOrphans string `xml:"ALLOW_ORPHANS"`
CurrentBase int `xml:"CURRENT_BASE"`
NextSnapshot int `xml:"NEXT_SNAPSHOT"`
Snapshots []shared.Snapshot `xml:"SNAPSHOT"`
}
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }
// State is the state of the Image // State is the state of the Image

View File

@ -0,0 +1,37 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Types is a type used to enumerate image template keys
type Template string
const (
Name Template = "NAME"
Persistent Template = "PERSISTENT"
PersistentType Template = "PERSISTENT_TYPE"
Size Template = "SIZE"
DevPrefix Template = "DEV_PREFIX"
Target Template = "TARGET"
Driver Template = "DRIVER"
Path Template = "PATH"
Source Template = "SOURCE"
DiskType Template = "DISK_TYPE"
ReadOnly Template = "READONLY"
Md5 Template = "MD5"
Sha1 Template = "SHA1"
Type Template = "TYPE"
)

View File

@ -0,0 +1,74 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 image
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image/keys"
)
// Types is a type used to enumerate image types
type Types string
const (
// Virtual Machine disks
Datablock Types = "DATABLOCK"
CDRom Types = "CDROM"
OS Types = "OS"
// File types, can be registered only in File Datastores
Kernel Types = "KERNEL"
RamDisk Types = "RAMDISK"
Context Types = "CONTEXT"
)
// Template is the dynamic part of the image entity
type Template struct {
dyn.Template
}
// NewTemplate returns an image template
func NewTemplate() *Template {
return &Template{
dyn.Template{},
}
}
// Get return the string value of a template image key
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for an image template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds an image template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}
// SetType set an Image type
func (t *Template) SetType(typ Types) {
pair, err := t.GetPair(string(keys.Type))
if err != nil {
t.AddPair(string(keys.Type), string(typ))
} else {
pair.Value = string(typ)
}
}

View File

@ -0,0 +1,24 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type used to enumerate marketplace keys
type Template string
const (
Name Template = "NAME"
)

View File

@ -0,0 +1,25 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
const (
// Http kind keys
MarketMAD Template = "MARKET_MAD"
PublicDir Template = "PUBLIC_DIR"
BaseUrl Template = "BASE_URL"
BridgeList Template = "BRIDGE_LIST"
)

View File

@ -17,34 +17,32 @@
package marketplace package marketplace
import ( import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "encoding/xml"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula MarketPlace pool // Pool represents an OpenNebula MarketPlace pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"MARKETPLACE_POOL"`
MarketPlaces []MarketPlace `xml:"MARKETPLACE"` MarketPlaces []MarketPlace `xml:"MARKETPLACE"`
} }
// MarketPlace represents an OpenNebula MarketPlace // MarketPlace represents an OpenNebula MarketPlace
type MarketPlace struct { type MarketPlace struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"MARKETPLACE"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
MarketMad string `xml:"MARKET_MAD"` MarketMad string `xml:"MARKET_MAD,omitempty"`
ZoneID string `xml:"ZONE_ID"` ZoneID string `xml:"ZONE_ID,omitempty"`
TotalMB int `xml:"TOTAL_MB"` TotalMB int `xml:"TOTAL_MB,omitempty"`
FreeMB int `xml:"FREE_MB"` FreeMB int `xml:"FREE_MB,omitempty"`
UsedMB int `xml:"USED_MB"` UsedMB int `xml:"USED_MB,omitempty"`
MarketPlaceAppsIDs []int `xml:"MARKETPLACEAPPS>ID"` MarketPlaceAppsIDs shared.EntitiesID `xml:"MARKETPLACEAPPS,omitempty"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
Template Template `xml:"TEMPLATE"` Template Template `xml:"TEMPLATE"`
} }
// MarketPlaceTemplate represent the template part of the MarketPlace
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}

View File

@ -0,0 +1,49 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 marketplace
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplace/keys"
)
// Template is the dynamic part of the marketplace entity
type Template struct {
dyn.Template
}
// NewTemplate returns a marketplace template
func NewTemplate() *Template {
return &Template{
dyn.Template{},
}
}
// Get return the string value of a template marketplace key
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for a marketplace template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a marketplace Template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}

View File

@ -0,0 +1,34 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type used to enumerate marketplace keys of Http kind
type Template string
const (
Name Template = "NAME"
OriginID Template = "ORIGIN_ID"
Type Template = "TYPE"
Size Template = "SIZE"
MarketPlaceID Template = "MARKETPLACE_ID"
MarketPlace Template = "MARKETPLACES"
Description Template = "DESCRIPTION"
Publisher Template = "PUBLISHER"
Version Template = "VERSION"
VMTemplate64 Template = "VMTEMPLATE64"
AppTemplate64 Template = "APPTEMPLATE64"
)

View File

@ -17,42 +17,42 @@
package marketplaceapp package marketplaceapp
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula MarketPlaceApp pool // Pool represents an OpenNebula MarketPlaceApp pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"MARKETPLACEAPP_POOL"`
MarketPlaceApps []MarketPlaceApp `xml:"MARKETPLACEAPP"` MarketPlaceApps []MarketPlaceApp `xml:"MARKETPLACEAPP"`
} }
// MarketPlaceApp represents an OpenNebula MarketPlaceApp // MarketPlaceApp represents an OpenNebula MarketPlaceApp
type MarketPlaceApp struct { type MarketPlaceApp struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"MARKETPLACEAPP"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
LockInfos *shared.Lock `xml:"LOCK"` GName string `xml:"GNAME,omitempty"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` LockInfos *shared.Lock `xml:"LOCK,omitempty"`
RegTime int `xml:"REGTIME"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
RegTime int `xml:"REGTIME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
ZoneID string `xml:"ZONE_ID"` ZoneID string `xml:"ZONE_ID,omitempty"`
OriginID string `xml:"ORIGIN_ID"` OriginID int `xml:"ORIGIN_ID"`
Source string `xml:"SOURCE"` Source string `xml:"SOURCE,omitempty"`
MD5 string `xml:"MD5"` MD5 string `xml:"MD5,omitempty"`
Size int `xml:"SIZE"` Size int `xml:"SIZE,omitempty"`
Description string `xml:"DESCRIPTION"` Description string `xml:"DESCRIPTION,omitempty"`
Version string `xml:"VERSION"` Version string `xml:"VERSION,omitempty"`
Format string `xml:"FORMAT"` Format string `xml:"FORMAT,omitempty"`
AppTemplate64 string `xml:"APPTEMPLATE64"` AppTemplate64 string `xml:"APPTEMPLATE64,omitempty"`
MarketPlaceID int `xml:"MARKETPLACEID"` MarketPlaceID *int `xml:"MARKETPLACE_ID,omitempty"`
MarketPlace string `xml:"MARKETPLACE"` MarketPlace string `xml:"MARKETPLACE,omitempty"`
State int `xml:"STATE"` State int `xml:"STATE,omitempty"`
Type int `xml:"TYPE"` Type int `xml:"TYPE,omitempty"`
Template Template `xml:"TEMPLATE"` Template dyn.Template `xml:"TEMPLATE"`
}
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:,any`
} }

View File

@ -0,0 +1,69 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 marketplaceapp
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/marketplaceapp/keys"
)
// Types is a type used to enumerate marketplace app types
type Types string
const (
// Virtual Machine disks
Datablock Types = "DATABLOCK"
Image Types = "IMAGE"
)
// Template is the dynamic part of the marketplace app entity
type Template struct {
dyn.Template
}
// NewTemplate returns a marketplace app template
func NewTemplate() *Template {
return &Template{
dyn.Template{},
}
}
// Get return the string value of a template marketplace app key
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for a marketplace app template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a marketplace app template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}
// SetType set a Datastore type
func (t *Template) SetType(typ Types) {
pair, err := t.GetPair(string(keys.Type))
if err != nil {
t.AddPair(string(keys.Type), string(typ))
} else {
pair.Value = string(typ)
}
}

View File

@ -0,0 +1,31 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Rule is a type used to enumerate security group rules keys
type Rule string
const (
RuleVec Rule = "RULE"
Protocol Rule = "PROTOCOL"
RuleType Rule = "RULE_TYPE"
IP Rule = "IP"
Size Rule = "SIZE"
Range Rule = "RANGE"
IcmpType Rule = "ICMP_TYPE"
NetworkID Rule = "NETWORK_ID"
)

View File

@ -0,0 +1,25 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type used to enumerate securitygroup keys
type Template string
const (
Name Template = "NAME"
Description Template = "DESCRIPTION"
)

View File

@ -0,0 +1,46 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 securitygroup
import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup/keys"
)
// Rule is a security group rule vector
type Rule struct {
dyn.Vector
}
// NewRule returns a security group rule vector
func NewRule() *Rule {
return &Rule{
dyn.Vector{XMLName: xml.Name{Local: string(keys.RuleVec)}},
}
}
// Get return the string value of a security group rule template key
func (t *Rule) Get(key keys.Rule) (string, error) {
return t.GetStr(string(key))
}
// Add adds a security group rule template key, value pair
func (t *Rule) Add(key keys.Rule, value string) {
t.AddPair(string(key), value)
}

View File

@ -17,39 +17,30 @@
package securitygroup package securitygroup
import ( import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "encoding/xml"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula SecurityGroup pool // Pool represents an OpenNebula SecurityGroup pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"SECURITY_GROUP_POOL"`
SecurityGroups []SecurityGroup `xml:"SECURITY_GROUP"` SecurityGroups []SecurityGroup `xml:"SECURITY_GROUP"`
} }
// SecurityGroup represents an OpenNebula SecurityGroup // SecurityGroup represents an OpenNebula SecurityGroup
type SecurityGroup struct { type SecurityGroup struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"SECURITY_GROUP"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
UpdatedVMs []int `xml:"UPDATED_VMS>ID"` UpdatedVMs shared.EntitiesID `xml:"UPDATED_VMS,omitempty"`
OutdatedVMs []int `xml:"OUTDATED_VMS>ID"` OutdatedVMs shared.EntitiesID `xml:"OUTDATED_VMS,omitempty"`
UpdatingVMs []int `xml:"UPDATING_VMS>ID"` UpdatingVMs shared.EntitiesID `xml:"UPDATING_VMS,omitempty"`
ErrorVMs []int `xml:"ERROR_VMS>ID"` ErrorVMs shared.EntitiesID `xml:"ERROR_VMS,omitempty"`
Template Template `xml:"TEMPLATE"` Template Template `xml:"TEMPLATE"`
} }
// Template represent the template part of the OpenNebula SecurityGroup
type Template struct {
Description string `xml:"DESCRIPTION"`
Rules []SecurityGroupRule `xml:"RULE"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type SecurityGroupRule struct {
Protocol string `xml:"PROTOCOL"`
RuleType string `xml:"RULE_TYPE"`
}

View File

@ -0,0 +1,51 @@
package securitygroup
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup/keys"
)
// Template represent the template part of the OpenNebula SecurityGroup
type Template struct {
dyn.Template
}
// NewTemplate returns a security group template
func NewTemplate() *Template {
return &Template{}
}
// AddAR allow to add a security group rule to the template
func (t *Template) AddRule() *Rule {
rule := NewRule()
t.Elements = append(t.Elements, rule)
return rule
}
// GetRules allow to retrieve security group rules from template
func (t *Template) GetRules() []Rule {
vecs := t.GetVectors(string(keys.RuleVec))
rules := make([]Rule, len(vecs))
for i, v := range vecs {
rules[i] = Rule{*v}
}
return rules
}
// Get return the string value of a template security group key
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for a security group template key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a security group Template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}

View File

@ -0,0 +1,59 @@
package shared
import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
)
// Disk is a structure allowing to parse disk templates
type Disk struct {
dyn.Vector
}
// DiskKeys is here to help the user to keep track of XML tags defined in Disk
type DiskKeys string
// Some keys are specific to VM some others to VRouter
const (
DiskVec string = "DISK"
DevPrefix DiskKeys = "DEV_PREFIX"
DiskID DiskKeys = "DISK_ID"
Datastore DiskKeys = "DATASTORE"
DatastoreID DiskKeys = "DATASTORE_ID"
DiskType DiskKeys = "DISK_TYPE"
Driver DiskKeys = "DRIVER"
Image DiskKeys = "IMAGE"
ImageID DiskKeys = "IMAGE_ID"
ImageUname DiskKeys = "IMAGE_UNAME"
OriginalSize DiskKeys = "ORIGINAL_SIZE"
Size DiskKeys = "SIZE"
TargetDisk DiskKeys = "TARGET"
)
// NewDisk returns a structure disk entity to build
func NewDisk() *Disk {
return &Disk{
dyn.Vector{XMLName: xml.Name{Local: DiskVec}},
}
}
// ID returns the disk ID as an integer
func (d *Disk) ID() (int, error) {
return d.GetInt(string(DiskID))
}
// Get return the string value for a disk key
func (d *Disk) Get(key DiskKeys) (string, error) {
return d.GetStr(string(key))
}
// GetI returns the integer value for a disk key
func (d *Disk) GetI(key DiskKeys) (int, error) {
return d.GetInt(string(key))
}
// Add adds a disk key, value pair
func (d *Disk) Add(key DiskKeys, value string) {
d.AddPair(string(key), value)
}

View File

@ -0,0 +1,5 @@
package shared
type EntitiesID struct {
ID []int `xml"ID,omitempty"`
}

View File

@ -0,0 +1,76 @@
package shared
import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
)
// NIC is a structure allowing to parse NIC templates. Common to VM and VRouter.
type NIC struct {
dyn.Vector
}
// NICKeys is here to help the user to keep track of XML tags defined in NIC
type NICKeys string
// Some keys are specific to VM some others to VRouter
// For VM values: https://docs.opennebula.org/5.8/operation/references/template.html#network-section
const (
NICVec string = "NIC"
NICID NICKeys = "NIC_ID"
Bridge NICKeys = "BRIDGE"
Filter NICKeys = "FILTER"
IP NICKeys = "IP"
MAC NICKeys = "MAC"
Network NICKeys = "NETWORK"
NetworkMask NICKeys = "NETWORK_MASK"
NetworkID NICKeys = "NETWORK_ID"
NetworkUID NICKeys = "NETWORK_UID"
NetworkUName NICKeys = "NETWORK_UNAME"
NetworkAddress NICKeys = "NETWORK_ADDRESS"
SecurityGroups NICKeys = "SECURITY_GROUPS"
Target NICKeys = "TARGET"
VlanID NICKeys = "VLAN_ID"
Script NICKeys = "SCRIPT"
Model NICKeys = "MODEL"
InboundAvgBw NICKeys = "INBOUND_AVG_BW"
InboundPeakBw NICKeys = "INBOUND_PEAK_BW"
InboundPeakK NICKeys = "INBOUND_PEAK_KB"
OutboundAvgBw NICKeys = "OUTBOUND_AVG_BW"
OutboundPeakBw NICKeys = "OUTBOUND_PEAK_BW"
OutboundPeakKb NICKeys = "OUTBOUND_PEAK_KB"
NetworkMode NICKeys = "NETWORK_MODE"
SchedRequirements NICKeys = "SCHED_REQUIREMENTS"
SchedRank NICKeys = "SCHED_RANK"
Name NICKeys = "NAME"
Parent NICKeys = "PARENT"
External NICKeys = "EXTERNAL"
)
// NewNIC returns a structure disk entity to build
func NewNIC() *NIC {
return &NIC{
dyn.Vector{XMLName: xml.Name{Local: NICVec}},
}
}
// ID returns the NIC ID as an integer
func (n *NIC) ID() (int, error) {
return n.GetInt(string(NICID))
}
// Get returns the string value for a NIC key
func (n *NIC) Get(key NICKeys) (string, error) {
return n.GetStr(string(key))
}
// GetI returns the integer value for a NIC key
func (n *NIC) GetI(key NICKeys) (int, error) {
return n.GetInt(string(key))
}
// Add adds a NIC key, value pair
func (n *NIC) Add(key NICKeys, value string) {
n.AddPair(string(key), value)
}

View File

@ -16,51 +16,57 @@
package shared package shared
// Quotas keeps quota value per User or Group
type Quotas struct { type Quotas struct {
ID int `xml:"ID"` ID int `xml:"ID"`
QuotasList QuotasList
} }
// QuotasList keeps quota per entity type
type QuotasList struct { type QuotasList struct {
DatastoreQuotas []DatastoreQuota `xml:"DATASTORE_QUOTA>DATASTORE"` Datastore []DatastoreQuota `xml:"DATASTORE_QUOTA>DATASTORE"`
NetworkQuotas []NetworkQuota `xml:"NETWORK_QUOTA>NETWORK"` Network []NetworkQuota `xml:"NETWORK_QUOTA>NETWORK"`
VMQuotas []VMQuota `xml:"VM_QUOTA>VM"` VM *VMQuota `xml:"VM_QUOTA>VM"`
ImageQuotas []ImageQuota `xml:"IMAGE_QUOTA>IMAGE"` Image []ImageQuota `xml:"IMAGE_QUOTA>IMAGE"`
} }
// DatastoreQuota keeps quota for a datastore
type DatastoreQuota struct { type DatastoreQuota struct {
ID int `xml:"ID"` ID int `xml:"ID"`
Images string `xml:"IMAGES"` Images int `xml:"IMAGES"`
ImagesUsed string `xml:"IMAGES_USED"` ImagesUsed int `xml:"IMAGES_USED"`
Size string `xml:"SIZE"` Size int `xml:"SIZE"`
SizeUsed string `xml:"SIZE_USED"` SizeUsed int `xml:"SIZE_USED"`
} }
// NetworkQuota keeps quota for a network
type NetworkQuota struct { type NetworkQuota struct {
ID int `xml:"ID"` ID int `xml:"ID"`
Leases string `xml:"LEASES"` Leases int `xml:"LEASES"`
LeasesUsed string `xml:"LEASES_USED"` LeasesUsed int `xml:"LEASES_USED"`
} }
// VMQuota keeps quota for all VMs in the group
type VMQuota struct { type VMQuota struct {
CPU string `xml:"CPU"` CPU float32 `xml:"CPU"`
CPUUsed string `xml:"CPU_USED"` CPUUsed float32 `xml:"CPU_USED,omitempty"`
Memory string `xml:"MEMORY"` Memory int `xml:"MEMORY"`
MemoryUsed string `xml:"MEMORY_USED"` MemoryUsed int `xml:"MEMORY_USED,omitempty"`
RunningCPU string `xml:"RUNNING_CPU"` RunningCPU float32 `xml:"RUNNING_CPU"`
RunningCPUUsed string `xml:"RUNNING_CPU_USED"` RunningCPUUsed float32 `xml:"RUNNING_CPU_USED,omitempty"`
RunningMemory string `xml:"RUNNING_MEMORY"` RunningMemory int `xml:"RUNNING_MEMORY"`
RunningMemoryUsed string `xml:"RUNNING_MEMORY_USED"` RunningMemoryUsed int `xml:"RUNNING_MEMORY_USED"`
RunningVMs string `xml:"RUNNING_VMS"` RunningVMs int `xml:"RUNNING_VMS"`
RunningVMsUsed string `xml:"RUNNING_VMS_USED"` RunningVMsUsed int `xml:"RUNNING_VMS_USED,omitempty"`
SystemDiskSize string `xml:"SYSTEM_DISK_SIZE"` SystemDiskSize int64 `xml:"SYSTEM_DISK_SIZE"`
SystemDiskSizeUsed string `xml:"SYSTEM_DISK_SIZE_USED"` SystemDiskSizeUsed int64 `xml:"SYSTEM_DISK_SIZE_USED,omitempty"`
VMs string `xml:"VMS"` VMs int `xml:"VMS"`
VMsUsed string `xml:"VMS_USED"` VMsUsed int `xml:"VMS_USED"`
} }
// ImageQuota keeps quota for an image
type ImageQuota struct { type ImageQuota struct {
ID int `xml:"ID"` ID int `xml:"ID"`
RVMs string `xml:"RVMS"` RVMs int `xml:"RVMS"`
RVMsUsed string `xml:"RVMS_USED"` RVMsUsed int `xml:"RVMS_USED"`
} }

View File

@ -28,3 +28,11 @@ type Snapshot struct {
Parent int `xml:"PARENT"` Parent int `xml:"PARENT"`
Size int `xml:"SIZE"` Size int `xml:"SIZE"`
} }
// DiskSnapshot represent a disk snapshot
type DiskSnapshot struct {
AllowOrphans string `xml:"ALLOW_ORPHANS"`
CurrentBase int `xml:"CURRENT_BASE"`
NextSnapshot int `xml:"NEXT_SNAPSHOT"`
Snapshots []Snapshot `xml:"SNAPSHOT"`
}

View File

@ -17,68 +17,29 @@
package template package template
import ( import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "encoding/xml"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
vm "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm"
) )
// Pool represents an OpenNebula Template pool // Pool represents an OpenNebula Template pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"VMTEMPLATE_POOL"`
Templates []Template `xml:"VMTEMPLATE"` Templates []Template `xml:"VMTEMPLATE"`
} }
// Template represents an OpenNebula Template // Template represents an OpenNebula Template
type Template struct { type Template struct {
ID int `xml:"ID"` ID int `xml:"ID,omitempty"`
UID int `xml:"UID"` UID int `xml:"UID,omitempty"`
GID int `xml:"GID"` GID int `xml:"GID,omitempty"`
UName string `xml:"UNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME"` GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
LockInfos *shared.Lock `xml:"LOCK"` LockInfos *shared.Lock `xml:"LOCK,omitempty"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
RegTime int `xml:"REGTIME"` RegTime int `xml:"REGTIME,omitempty"`
Template TemplateTpl `xml:"TEMPLATE"` Template vm.Template `xml:"TEMPLATE"`
}
// Template represent the template part of the OpenNebula Template
type TemplateTpl struct {
CPU float64 `xml:"CPU"`
Memory int `xml:"MEMORY"`
Context *Context `xml:"CONTEXT"`
Disk []Disk `xml:"DISK"`
NIC []NIC `xml:"NIC"`
Graphics *Graphics `xml:"GRAPHICS"`
NICDefault *NicDefault `xml:"NIC_DEFAULT"`
OS *OS `xml:"OS"`
UserInputs UserInputs `xml:"USER_INPUTS"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type Context struct {
Dynamic dyn.UnmatchedTagsMap `xml:",any"`
}
type Disk struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type NIC struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type Graphics struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type UserInputs struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type NicDefault struct {
Model string `xml:"MODEL"`
}
type OS struct {
Arch string `xml:"ARCH"`
Boot string `xml:"BOOT"`
} }

View File

@ -17,39 +17,44 @@
package user package user
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula User pool // Pool represents an OpenNebula User pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"USER_POOL"`
Users []User `xml:"USER"` Users []User `xml:"USER"`
Quotas []shared.Quotas `xml:"QUOTAS"` Quotas []shared.Quotas `xml:"QUOTAS"`
DefaultUserQuotas shared.QuotasList `xml:"DEFAULT_USER_QUOTAS"` DefaultUserQuotas shared.QuotasList `xml:"DEFAULT_USER_QUOTAS"`
} }
// UserShort keeps summary information on a user
type UserShort struct {
XMLName xml.Name `xml:"USER"`
ID int `xml:"ID,omitempty"`
GID int `xml:"GID,omitempty"`
Groups shared.EntitiesID `xml:"GROUPS,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME,omitempty"`
Password string `xml:"PASSWORD,omitempty"`
AuthDriver string `xml:"AUTH_DRIVER,omitempty"`
Enabled int `xml:"ENABLED,omitempty"`
LoginTokens []LoginToken `xml:"LOGIN_TOKEN,omitempty"`
Template dyn.Template `xml:"TEMPLATE"`
}
// User represents an OpenNebula user // User represents an OpenNebula user
type User struct { type User struct {
ID int `xml:"ID"` UserShort
GID int `xml:"GID"`
GroupsID []int `xml:"GROUPS>ID"`
GName string `xml:"GNAME"`
Name string `xml:"NAME"`
Password string `xml:"PASSWORD"`
AuthDriver string `xml:"AUTH_DRIVER"`
Enabled int `xml:"ENABLED"`
LoginTokens []LoginToken `xml:"LOGIN_TOKEN"`
Template Template `xml:"TEMPLATE"`
// Variable part between one.userpool.info and one.user.info // Variable part between one.userpool.info and one.user.info
shared.QuotasList shared.QuotasList
DefaultUserQuotas shared.QuotasList `xml:"DEFAULT_USER_QUOTAS"` DefaultUserQuotas shared.QuotasList `xml:"DEFAULT_USER_QUOTAS"`
} }
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type LoginToken struct { type LoginToken struct {
Token string `xml:"TOKEN"` Token string `xml:"TOKEN"`
ExpirationTime int `xml:"EXPIRATION_TIME"` ExpirationTime int `xml:"EXPIRATION_TIME"`

View File

@ -17,28 +17,33 @@
package vdc package vdc
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Vdc pool // Pool represents an OpenNebula Vdc pool
type Pool struct { type Pool struct {
VDCs []VDC `xml:"VDC"` XMLName xml.Name `xml:"VDC_POOL"`
VDCs []VDC `xml:"VDC"`
} }
// VDC represents an OpenNebula Vdc // VDC represents an OpenNebula Vdc
type VDC struct { type VDC struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"VDC"`
Name string `xml:"NAME"` ID int `xml:"ID,omitempty"`
GroupsID []int `xml:"GROUPS>ID"` Name string `xml:"NAME"`
Clusters []Cluster `xml:"CLUSTERS>CLUSTER"` Groups shared.EntitiesID `xml:"GROUPS,omitempty"`
Hosts []Host `xml:"HOSTS>HOST"` Clusters []Cluster `xml:"CLUSTERS>CLUSTER,omitempty"`
Datastores []Datastore `xml:"DATASTORES>DATASTORE"` Hosts []Host `xml:"HOSTS>HOST,omitempty"`
VNets []VNet `xml:"VNETS>VNET"` Datastores []Datastore `xml:"DATASTORES>DATASTORE,omitempty"`
Template Template `xml:"TEMPLATE"` VNets []VNet `xml:"VNETS>VNET,omitempty"`
Template Template `xml:"TEMPLATE"`
} }
type Template struct { type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"` dyn.Template
} }
type Cluster struct { type Cluster struct {

View File

@ -0,0 +1,58 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 virtualnetwork
import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork/keys"
)
// Address Range template part
// AddressRange is a structure allowing to parse AddressRange templates. Common to VM and VRouter.
type AddressRange struct {
dyn.Vector
}
// NewAddressRange returns a structure disk entity to build
func NewAddressRange() *AddressRange {
return &AddressRange{
dyn.Vector{XMLName: xml.Name{Local: keys.ARVec}},
}
}
// ID returns the address range ID as an integer
func (n *AddressRange) ID() (int, error) {
return n.GetInt(string(keys.ARID))
}
// Get returns the string value for an address range keys
func (n *AddressRange) Get(key keys.AddressRange) (string, error) {
return n.GetStr(string(key))
}
// GetI returns the integer value for an address range key
func (n *AddressRange) GetI(key keys.AddressRange) (int, error) {
return n.GetInt(string(key))
}
// Add adds an address range key, value pair.
func (n *AddressRange) Add(key keys.AddressRange, value string) {
n.AddPair(string(key), value)
}

View File

@ -0,0 +1,34 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Address Range template part
// AddressRange is here to help the user to keep track of XML tags defined in AddressRange
type AddressRange string
const (
ARVec string = "AR"
ARID AddressRange = "AR_ID"
IP AddressRange = "IP"
Size AddressRange = "SIZE"
Type AddressRange = "TYPE"
Mac AddressRange = "MAC"
GlobalPrefix AddressRange = "GLOBAL_PREFIX"
UlaPrefix AddressRange = "ULA_PREFIX"
PrefixLength AddressRange = "PREFIX_LENGTH"
)

View File

@ -0,0 +1,61 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Template is a type for virtual network template keys.
type Template string
// Physical network template keys
const (
Name Template = "NAME"
VNMad Template = "VN_MAD"
Bridge Template = "BRIDGE"
VlanID Template = "VLAN_ID"
AutomaticVlanID Template = "AUTOMATIC_VLAN_ID"
PhyDev Template = "PHYDEV"
)
// Quality of service template keys
const (
InboundAvgBw Template = "INBOUND_AVG_BW"
InboundPeakBw Template = "INBOUND_PEAK_BW"
InboundPeakKb Template = "INBOUND_PEAK_KB"
OutboundAvgBw Template = "OUTBOUND_AVG_BW"
OutboundPeakBw Template = "OUTBOUND_PEAK_BW"
OutboundPeakKb Template = "OUTBOUND_PEAK_KB"
)
// Contextualization template keys
const (
NetworkMask Template = "NETWORK_MASK"
NetworkAddress Template = "NETWORK_ADDRESS"
Gateway Template = "GATEWAY"
Gateway6 Template = "GATEWAY6"
DNS Template = "DNS"
GuestMTU Template = "GUEST_MTU"
ContextForceIPV4 Template = "CONTEXT_FORCE_IPV4"
SearchDomain Template = "SEARCH_DOMAIN"
SecGroups Template = "SECURITY_GROUPS"
)
// Interface creation options template keys
const (
Conf Template = "CONF"
BridgeConf Template = "BRIDGE"
OvsBridgeConf Template = "OVS_BRIDGE_CONF"
IPLinkConf Template = "IP_LINK_CONF"
)

View File

@ -0,0 +1,66 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 virtualnetwork
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork/keys"
)
// Template is a virtual network template
type Template struct {
dyn.Template
}
// NewTemplate returns a new virtual network Template object
func NewTemplate() *Template {
return &Template{}
}
// Get returns the string value for a virtual network template
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for an virtual network key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a virtual network template key, value pair.
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}
// AddAR allow to add a AR to the template
func (t *Template) AddAddressRange() *AddressRange {
ar := NewAddressRange()
t.Elements = append(t.Elements, ar)
return ar
}
// GetAR allow to retrieve ARs from template
func (t *Template) GetARs() []AddressRange {
vecs := t.GetVectors(string(keys.ARVec))
ars := make([]AddressRange, len(vecs))
for i, v := range vecs {
ars[i] = AddressRange{*v}
}
return ars
}

View File

@ -17,80 +17,79 @@
package virtualnetwork package virtualnetwork
import ( import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "encoding/xml"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula VirtualNetwork pool // Pool represents an OpenNebula VirtualNetwork pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"VNET_POOL"`
VirtualNetworks []VirtualNetwork `xml:"VNET"` VirtualNetworks []VirtualNetwork `xml:"VNET"`
} }
// VirtualNetwork represents an OpenNebula VirtualNetwork // VirtualNetwork represents an OpenNebula VirtualNetwork
type VirtualNetwork struct { type VirtualNetwork struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"VNET"`
ID int `xml:"ID,omitempty"`
UID int `xml:"UID"` UID int `xml:"UID"`
GID int `xml:"GID"` GID int `xml:"GID"`
UName string `xml:"UNAME"` UName string `xml:"UNAME"`
GName string `xml:"GNAME"` GName string `xml:"GNAME"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS"`
ClustersID []int `xml:"CLUSTERS>ID"` Clusters shared.EntitiesID `xml:"CLUSTERS,omitempty"`
Bridge string `xml:"BRIDGE"` Bridge string `xml:"BRIDGE,omitempty"`
BridgeType string `xml:"BRIDGE_TYPE"` // minOccurs=0 BridgeType string `xml:"BRIDGE_TYPE,omitempty"` // minOccurs=0
ParentNetworkID string `xml:"PARENT_NETWORK_ID"` ParentNetworkID string `xml:"PARENT_NETWORK_ID,omitempty"`
VNMad string `xml:"VN_MAD"` VNMad string `xml:"VN_MAD"`
PhyDev string `xml:"PHYDEV"` PhyDev string `xml:"PHYDEV,omitempty"`
VlanID string `xml:"VLAN_ID"` // minOccurs=0 VlanID string `xml:"VLAN_ID,omitempty"` // minOccurs=0
OuterVlanID string `xml:"OUTER_VLAN_ID"` // minOccurs=0 OuterVlanID string `xml:"OUTER_VLAN_ID,omitempty"` // minOccurs=0
VlanIDAutomatic string `xml:"VLAN_ID_AUTOMATIC"` VlanIDAutomatic string `xml:"VLAN_ID_AUTOMATIC,omitempty,omitempty"`
OuterVlanIDAutomatic string `xml:"OUTER_VLAN_ID_AUTOMATIC"` OuterVlanIDAutomatic string `xml:"OUTER_VLAN_ID_AUTOMATIC,omitempty"`
UsedLeases int `xml:"USED_LEASES"` UsedLeases int `xml:"USED_LEASES,omitempty"`
VRoutersID []int `xml:"VROUTERS>ID"` VRouters shared.EntitiesID `xml:"VROUTERS,omitempty"`
Template Template `xml:"TEMPLATE"` Template Template `xml:"TEMPLATE"`
// Variable parts between one.vnpool.info and one.vn.info // Variable parts between one.vnpool.info and one.vn.info
ARs []AR `xml:"AR_POOL>AR"` ARs []AR `xml:"AR_POOL>AR,omitempty"`
Lock *shared.Lock `xml:"LOCK"` Lock *shared.Lock `xml:"LOCK,omitempty"`
}
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }
type AR struct { type AR struct {
ID string `xml:"AR_ID"` ID string `xml:"AR_ID,omitempty"`
GlobalPrefix string `xml:"GLOBAL_PREFIX"` // minOccurs=0 GlobalPrefix string `xml:"GLOBAL_PREFIX,omitempty"` // minOccurs=0
IP string `xml:"IP"` // minOccurs=0 IP string `xml:"IP"` // minOccurs=0
MAC string `xml:"MAC"` MAC string `xml:"MAC,omitempty"`
ParentNetworkARID string `xml:"PARENT_NETWORK_AR_ID"` // minOccurs=0 ParentNetworkARID string `xml:"PARENT_NETWORK_AR_ID,omitempty"` // minOccurs=0
Size int `xml:"SIZE"` Size int `xml:"SIZE"`
Type string `xml:"TYPE"` Type string `xml:"TYPE"`
ULAPrefix string `xml:"ULA_PREFIX"` // minOccurs=0 ULAPrefix string `xml:"ULA_PREFIX,omitempty"` // minOccurs=0
VNMAD string `xml:"VN_MAD"` // minOccurs=0 VNMAD string `xml:"VN_MAD,omitempty"` // minOccurs=0
MACEnd string `xml:"MAC_END"` MACEnd string `xml:"MAC_END,omitempty"`
IPEnd string `xml:"IP_END"` IPEnd string `xml:"IP_END,omitempty"`
IP6ULA string `xml:"IP6_ULA"` IP6ULA string `xml:"IP6_ULA,omitempty"`
IP6ULAEnd string `xml:"IP6_ULA_END"` IP6ULAEnd string `xml:"IP6_ULA_END,omitempty"`
IP6Global string `xml:"IP6_GLOBAL"` IP6Global string `xml:"IP6_GLOBAL,omitempty"`
IP6GlobalEnd string `xml:"IP6_GLOBAL_END"` IP6GlobalEnd string `xml:"IP6_GLOBAL_END,omitempty"`
IP6 string `xml:"IP6"` IP6 string `xml:"IP6,omitempty"`
IP6End string `xml:"IP6_END"` IP6End string `xml:"IP6_END,omitempty"`
UsedLeases string `xml:"USED_LEASES"` UsedLeases string `xml:"USED_LEASES,omitempty"`
Leases []Lease `xml:"LEASES>LEASE"` Leases []Lease `xml:"LEASES>LEASE,omitempty"`
// Not filled with Info // Not filled with Info
Allocated string `xml:ALLOCATED` Allocated string `xml:"ALLOCATED"`
} }
type Lease struct { type Lease struct {
IP string `xml:"IP"` IP string `xml:"IP,omitempty"`
IP6 string `xml:"IP6"` IP6 string `xml:"IP6,omitempty"`
IP6Global string `xml:"IP6GLOBAL"` IP6Global string `xml:"IP6GLOBAL,omitempty"`
IP6Link string `xml:"IP6LINK"` IP6Link string `xml:"IP6LINK,omitempty"`
IP6ULA string `xml:"IP6ULA"` IP6ULA string `xml:"IP6ULA,omitempty"`
MAC string `xml:"MAC"` MAC string `xml:"MAC,omitempty"`
VM int `xml:"VM"` VM int `xml:"VM,omitempty"`
VNet int `xml:"VNET"` VNet int `xml:"VNET,omitempty"`
VRouter int `xml:"VROUTER"` VRouter int `xml:"VROUTER,omitempty"`
} }

View File

@ -0,0 +1,27 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
type Template string
const (
Name Template = "NAME"
Description Template = "DESCRIPTION"
VRouter Template = "VROUTER"
KeepAlivedPassword Template = "VROUTER_KEEPALIVED_PASSWORD"
KeepAlivedID Template = "VROUTER_KEEPALIVED_ID"
)

View File

@ -0,0 +1,72 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 virtualrouter
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualrouter/keys"
)
// Template is a virtual router template
type Template struct {
dyn.Template
}
// NewTemplate returns a new virtual router Template object
func NewTemplate() *Template {
tpl := &Template{}
tpl.Add(keys.VRouter, "YES")
return tpl
}
// Get returns the string value for a virtual router template
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for an virtual router key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a virtual router template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}
// AddNIC allow to add a NIC to the template
func (t *Template) AddNIC() *shared.NIC {
nic := shared.NewNIC()
t.Elements = append(t.Elements, nic)
return nic
}
// GetNICs allow to get NICs from Template
func (t *Template) GetNICs() []shared.NIC {
vecs := t.GetVectors(string(shared.NICVec))
nics := make([]shared.NIC, len(vecs))
for i, v := range vecs {
nics[i] = shared.NIC{*v}
}
return nics
}

View File

@ -17,39 +17,31 @@
package virtualrouter package virtualrouter
import ( import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" "encoding/xml"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula VirtualRouter pool // Pool represents an OpenNebula VirtualRouter pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"VROUTER_POOL"`
VirtualRouters []VirtualRouter `xml:"VROUTER"` VirtualRouters []VirtualRouter `xml:"VROUTER"`
} }
// VirtualRouter represents an OpenNebula VirtualRouter // VirtualRouter represents an OpenNebula VirtualRouter
type VirtualRouter struct { type VirtualRouter struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"VROUTER"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
LockInfos *shared.Lock `xml:"LOCK"` LockInfos *shared.Lock `xml:"LOCK,omitempty"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
Type int `xml:"TYPE"` Type *int `xml:"TYPE,omitempty"`
DiskType int `xml:"DISK_TYPE"` DiskType *int `xml:"DISK_TYPE,omitempty"`
Persistent int `xml:"PERSISTENT"` Persistent int `xml:"PERSISTENT,omitempty"`
VMsID []int `xml:"VMS>ID"` VMs shared.EntitiesID `xml:"VMS,omitempty"`
Template Template `xml:"TEMPLATE"` Template Template `xml:"TEMPLATE"`
} }
// Template represent the template part of the OpenNebula VirtualRouter
type Template struct {
NIC []NIC `xml:"NIC"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type NIC struct {
NICID int `xml:"NIC_ID"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}

View File

@ -0,0 +1,167 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// Available template parts and keys are listed here: https://docs.opennebula.org/5.8/operation/references/template.html
// Some specific part are not defined: vCenter, Public Cloud, Hypervisor, User Inputs
// Template is a type used to enumerate VM generic keys
type Template string
const (
Name Template = "NAME"
VRouter Template = "VROUTER"
Description Template = "DESCRIPTION"
)
// Capacity define keys for showback values
type Capacity string
const (
CPU Capacity = "CPU"
Memory Capacity = "MEMORY"
VCPU Capacity = "VCPU"
)
// Showback define keys for showback values
type Showback string
const (
MemCost Showback = "MEMORY_COST"
CPUCost Showback = "CPU_COST"
DiskCost Showback = "DISK_COST"
)
// OS define keys for OS and boot values of the VM
type OS string
const (
OSVec string = "OS"
Arch OS = "ARCH"
Machine OS = "MACHINE"
Kernel OS = "KERNEL"
KernelDS OS = "KERNEL_DS"
Initrd OS = "INITRD"
InitrdDS OS = "INITRD_DS"
Root OS = "ROOT"
KernelCmd OS = "KERNEL_CMD"
Bootloader OS = "BOOTLOADER"
Boot OS = "BOOT"
)
// CPUModel define keys for the VM CPU model
type CPUModel string
const (
CPUModelVec string = "CPU_MODEL"
Model CPUModel = "MODEL"
)
// Feature define keys for the VM features
type Feature string
const (
FeaturesVec string = "FEATURES"
PAE Feature = "PAE"
ACPI Feature = "ACPI"
APIC Feature = "APIC"
LocalTime Feature = "LOCAL_TIME"
GuestAgent Feature = "GUEST_AGENT"
VirtIOScsiQueues Feature = "VIRTIO_SCSI_QUEUES"
)
// IOGraphics define keys for the VM IO graphics
type IOGraphics string
// IOGraphics define keys for the VM IO input
type IOInput string
const (
//IOinput
IOInputVec string = "INPUT"
InputType IOInput = "TYPE" // Values: mouse or tablet
Bus IOInput = "BUS" // Values: usb or ps2
// IOGraphics
IOGraphicsVec string = "GRAPHICS"
GraphicType IOGraphics = "TYPE" // Values: vnc, sdl, spice
Listen IOGraphics = "LISTEN"
Port IOGraphics = "PORT"
Passwd IOGraphics = "PASSWD"
Keymap IOGraphics = "KEYMAP"
RandomPassword IOGraphics = "RANDOM_PASSWD"
)
// Context is here to help the user to keep track of XML tags defined in VM context
type Context string
// ContextB64 is the same that Context with base64 encoded values
type ContextB64 string
const (
ContextVec string = "CONTEXT"
DNS Context = "DNS"
DNSHostName Context = "DNS_HOSTNAME"
EC2PubKey Context = "EC2_PUBLIC_KEY"
Files Context = "FILES"
FilesDS Context = "FILES_DS"
GatewayIface Context = "GATEWAY_IFACE"
NetworkCtx Context = "NETWORK"
InitScripts Context = "INIT_SCRIPTS"
SSHPubKey Context = "SSH_PUBLIC_KEY"
TargetCtx Context = "TARGET"
Token Context = "TOKEN"
Username Context = "USERNAME"
Variable Context = "VARIABLE"
SecureTTY Context = "SECURETTY"
SetHostname Context = "SET_HOSTNAME"
// Base64 values
PasswordB64 ContextB64 = "PASSWORD_BASE64"
StartScriptB64 ContextB64 = "START_SCRIPT_BASE64"
CryptedPassB64 ContextB64 = "CRYPTED_PASSWORD_BASE64"
)
// Placement define keys for VM placement
type Placement string
const (
SchedRequirements Placement = "SCHED_REQUIREMENTS"
SchedRank Placement = "SCHED_RANK"
SchedDSRequirements Placement = "SCHED_DS_REQUIREMENTS"
SchedDSRank Placement = "SCHED_DS_RANK"
UserPriority Placement = "USER_PRIORITY"
)
// SchedAction define keys for scheduled action
type SchedAction string
const (
SchedActionVec string = "SCHED_ACTION"
Time SchedAction = "TIME"
Repeat SchedAction = "REPEAT"
Days SchedAction = "DAYS"
Action SchedAction = "ACTION"
EndType SchedAction = "END_TYPE"
EndValue SchedAction = "END_VALUE"
)

View File

@ -0,0 +1,25 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 keys
// UserTemplate define keys for user template values
type UserTemplate string
const (
Error UserTemplate = "ERROR"
SchedMessage UserTemplate = "SCHED_MESSAGE"
)

View File

@ -0,0 +1,304 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 vm
import (
"encoding/base64"
"encoding/xml"
"fmt"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm/keys"
)
// Available template parts and keys are listed here: https://docs.opennebula.org/5.8/operation/references/template.html
// Some specific part are not defined: vCenter, Public Cloud, Hypervisor, User Inputs
// Template is a structure allowing to parse VM templates.
// It's defined in a semi-static way to guide the user among the bunch of values
type Template struct {
dyn.Template
}
// NewTemplate returns a vm Template structure
func NewTemplate() *Template {
return &Template{}
}
// Get returns the string value for a vm template
func (t *Template) Get(key keys.Template) (string, error) {
return t.GetStr(string(key))
}
// GetI returns the integer value for an vm key
func (n *Template) GetI(key keys.Template) (int, error) {
return n.GetInt(string(key))
}
// Add adds a vm template key, value pair
func (t *Template) Add(key keys.Template, value string) {
t.AddPair(string(key), value)
}
// Template parts
// Capacity template part
// CPU set the CPU amount to the template
func (t *Template) CPU(cpu float64) *Template {
pair, err := t.GetPair(string(keys.CPU))
if err != nil {
t.AddPair(string(keys.CPU), cpu)
} else {
pair.Value = fmt.Sprint(cpu)
}
return t
}
// Memory set the memory amount to the template
func (t *Template) Memory(memory int) *Template {
pair, err := t.GetPair(string(keys.Memory))
if err != nil {
t.AddPair(string(keys.Memory), memory)
} else {
pair.Value = fmt.Sprint(memory)
}
return t
}
// VCPU set the VCPU count to the template
func (t *Template) VCPU(vcpu int) *Template {
pair, err := t.GetPair(string(keys.VCPU))
if err != nil {
t.AddPair(string(keys.VCPU), vcpu)
} else {
pair.Value = fmt.Sprint(vcpu)
}
return t
}
// GetCPU return the CPU amount from a VM Template
func (t *Template) GetCPU() (float64, error) {
CPU, err := t.GetFloat(string(keys.CPU))
if err != nil {
return -1, err
}
return CPU, nil
}
// GetMemory return the memory amount from a VM Template
func (t *Template) GetMemory() (int, error) {
Memory, err := t.GetInt(string(keys.Memory))
if err != nil {
return -1, err
}
return Memory, nil
}
// GetVCPU return the VCPU count from a VM Template
func (t *Template) GetVCPU() (int, error) {
VCPU, err := t.GetInt(string(keys.VCPU))
if err != nil {
return -1, err
}
return VCPU, nil
}
// GetDisk allow to get disks from Template
func (t *Template) GetDisks() []shared.Disk {
vecs := t.GetVectors(string(shared.DiskVec))
disks := make([]shared.Disk, len(vecs))
for i, v := range vecs {
disks[i] = shared.Disk{*v}
}
return disks
}
// GetNICs allow to get NICs from Template
func (t *Template) GetNICs() []shared.NIC {
vecs := t.GetVectors(string(shared.NICVec))
nics := make([]shared.NIC, len(vecs))
for i, v := range vecs {
nics[i] = shared.NIC{*v}
}
return nics
}
// AddDisk allow to add a disk to the template
func (t *Template) AddDisk() *shared.Disk {
disk := shared.NewDisk()
t.Elements = append(t.Elements, disk)
return disk
}
// AddNIC allow to add a NIC to the template
func (t *Template) AddNIC() *shared.NIC {
nic := shared.NewNIC()
t.Elements = append(t.Elements, nic)
return nic
}
// Show back template part
func (t *Template) Showback(key keys.Showback, value string) *Template {
t.Template.Del(string(key))
t.Template.AddPair(string(key), value)
return t
}
func (t *Template) GetShowback(key keys.Showback) (string, error) {
return t.Template.GetStr(string(key))
}
// OS template part
func (t *Template) AddOS(key keys.OS, value string) error {
return t.Template.AddPairToVec(keys.OSVec, string(key), value)
}
func (t *Template) GetOS(key keys.OS) (string, error) {
return t.Template.GetStrFromVec(string(keys.OSVec), string(key))
}
// CPU model part
// CPUModel set the model of the CPU
func (t *Template) CPUModel(value string) *Template {
t.Template.Del(string(keys.CPUModelVec))
t.Template.AddPairToVec(keys.CPUModelVec, string(keys.Model), value)
return t
}
// GetCPUModel get the model of the CPU
func (t *Template) GetCPUModel(key keys.CPUModel) (string, error) {
cpuModVec, err := t.Template.GetVector(string(keys.CPUModelVec))
if err != nil {
return "", fmt.Errorf("Template.GetCPUModel: vector %s: %s", keys.CPUModelVec, err)
}
return cpuModVec.GetStr(string(key))
}
// Features template part
func (t *Template) AddFeature(key keys.Feature, value string) error {
return t.Template.AddPairToVec(keys.FeaturesVec, string(key), value)
}
func (t *Template) GetFeature(key keys.Feature) (string, error) {
return t.Template.GetStrFromVec(string(keys.FeaturesVec), string(key))
}
// I/O devices template part
func (t *Template) AddIOGraphic(key keys.IOGraphics, value string) error {
return t.Template.AddPairToVec(keys.IOGraphicsVec, string(key), value)
}
func (t *Template) GetIOGraphic(key keys.IOInput) (string, error) {
return t.Template.GetStrFromVec(string(keys.IOGraphicsVec), string(key))
}
func (t *Template) AddIOInput(key keys.IOGraphics, value string) error {
return t.Template.AddPairToVec(keys.IOGraphicsVec, string(key), value)
}
func (t *Template) GetIOInput(key keys.IOInput) (string, error) {
return t.Template.GetStrFromVec(string(keys.IOGraphicsVec), string(key))
}
// Context template part
// GetCtx retrieve a context key
func (t *Template) GetCtx(key keys.Context) (string, error) {
return t.GetStrFromVec(string(keys.ContextVec), string(key))
}
// Add adds a context key, value pair
func (t *Template) AddCtx(key keys.Context, value string) error {
return t.AddPairToVec(keys.ContextVec, string(key), value)
}
// Add adds a context key, value pair. It will convert value to base64
func (t *Template) AddB64Ctx(key keys.ContextB64, value string) error {
valueB64 := base64.StdEncoding.EncodeToString([]byte(value))
return t.AddPairToVec(keys.ContextVec, string(key), valueB64)
}
// Placement Template part
// Placement set once a placement attribute
func (t *Template) Placement(key keys.Placement, value string) *Template {
t.Template.Del(string(key))
t.Template.AddPair(string(key), value)
return t
}
func (t *Template) GetPlacement(key keys.Placement) (string, error) {
return t.Template.GetStr(string(key))
}
// Scheduled actions template part
// SchedAction is a scheduled action on VM
type SchedAction struct {
dyn.Vector
}
// AddSchedAction returns a structure disk entity to build
func (t *Template) AddSchedAction() *SchedAction {
action := &SchedAction{
dyn.Vector{XMLName: xml.Name{Local: keys.SchedActionVec}},
}
t.Template.Elements = append(t.Template.Elements, action)
return action
}
// Add adds a SchedAction key, value pair
func (t *SchedAction) Add(key keys.SchedAction, value string) {
t.AddPair(string(key), value)
}
// Get retrieve a SchedAction key
func (t *SchedAction) Get(key keys.SchedAction) (string, error) {
return t.GetStr(string(key))
}

View File

@ -0,0 +1,39 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 vm
import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm/keys"
)
type UserTemplateKeys string
const (
Error UserTemplateKeys = "ERROR"
SchedMessage UserTemplateKeys = "SCHED_MESSAGE"
)
// UserTemplate contains common and custom attributes
type UserTemplate struct {
dyn.Template
}
// Get allows to get a pair by key
func (d *UserTemplate) Get(key keys.UserTemplate) (string, error) {
return d.GetStr(string(key))
}

View File

@ -17,161 +17,73 @@
package vm package vm
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Virtual Machine pool // Pool represents an OpenNebula Virtual Machine pool
type Pool struct { type Pool struct {
VMs []VM `xml:"VM"` XMLName xml.Name `xml:"VM_POOL"`
VMs []VM `xml:"VM"`
} }
// VM represents an OpenNebula Virtual Machine // VM represents an OpenNebula Virtual Machine
type VM struct { type VM struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"VM"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
Name string `xml:"NAME"` GName string `xml:"GNAME,omitempty"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Name string `xml:"NAME,omitempty"`
LastPoll int `xml:"LAST_POLL"` Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
StateRaw int `xml:"STATE"` LastPoll int `xml:"LAST_POLL,omitempty"`
LCMStateRaw int `xml:"LCM_STATE"` StateRaw int `xml:"STATE,omitempty"`
PrevStateRaw int `xml:"PREV_STATE"` LCMStateRaw int `xml:"LCM_STATE,omitempty"`
PrevLCMStateRaw int `xml:"PREV_LCM_STATE"` PrevStateRaw int `xml:"PREV_STATE,omitempty"`
ReschedValue int `xml:"RESCHED"` PrevLCMStateRaw int `xml:"PREV_LCM_STATE,omitempty"`
STime int `xml:"STIME"` ReschedValue int `xml:"RESCHED,omitempty"`
ETime int `xml:"ETIME"` STime int `xml:"STIME,omitempty"`
DeployID string `xml:"DEPLOY_ID"` ETime int `xml:"ETIME,omitempty"`
MonitoringInfos Monitoring `xml:"MONITORING"` DeployID string `xml:"DEPLOY_ID,omitempty"`
Template Template `xml:"TEMPLATE"` MonitoringInfos Monitoring `xml:"MONITORING,omitempty"`
UserTemplate *UserTemplate `xml:"USER_TEMPLATE"` Template Template `xml:"TEMPLATE,omitempty"`
HistoryRecords []HistoryRecord `xml:"HISTORY_RECORDS>HISTORY"` UserTemplate UserTemplate `xml:"USER_TEMPLATE,omitempty"`
HistoryRecords []HistoryRecord `xml:"HISTORY_RECORDS>HISTORY,omitempty"`
Snapshots shared.DiskSnapshot `xml:"SNAPSHOTS,omitempty"`
// Not filled with NewUserPool call // Not filled with NewUserPool call
LockInfos *shared.Lock `xml:"LOCK"` LockInfos *shared.Lock `xml:"LOCK"`
} }
// Monitoring is a dynamic VM part containing metrics
type Monitoring struct { type Monitoring struct {
DiskSize []MonitoringDiskSize `xml:"DISK_SIZE"` dyn.Template
SnapshotSize []MonitoringSnapshotSize `xml:"SNAPSHOT_SIZE"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type MonitoringDiskSize struct {
ID int `xml:"ID"`
Size int `xml:"SIZE"`
} }
// History records // History records
type HistoryRecord struct { type HistoryRecord struct {
OID int `xml:"OID"` OID int `xml:"OID"`
SEQ int `xml:"SEQ"` SEQ int `xml:"SEQ"`
Hostname string `xml:"HOSTNAME"` Hostname string `xml:"HOSTNAME"`
HID int `xml:"HID"` HID int `xml:"HID"`
CID int `xml:"CID"` CID int `xml:"CID"`
DSID int `xml:"DS_ID"` STime int `xml:"STIME"`
Action int `xml:"ACTION"` ETime int `xml:"ETIME"`
UID int `xml:"UID"` VMMad string `xml:"VM_MAD"`
GID int `xml:"GID"` TMMad string `xml:"TM_MAD"`
RequestID string `xml:"REQUEST_ID"` DSID int `xml:"DS_ID"`
PSTime int `xml:"PSTIME"` PSTime int `xml:"PSTIME"`
PETime int `xml:"PETIME"` PETime int `xml:"PETIME"`
RSTime int `xml:"RSTIME"` RSTime int `xml:"RSTIME"`
RETime int `xml:"RETIME"` RETime int `xml:"RETIME"`
ESTime int `xml:"ESTIME"` ESTime int `xml:"ESTIME"`
EETime int `xml:"EETIME"` EETime int `xml:"EETIME"`
STime int `xml:"STIME"` Action int `xml:"ACTION"`
ETime int `xml:"ETIME"` UID int `xml:"UID"`
VMMad string `xml:"VM_MAD"` GID int `xml:"GID"`
TMMad string `xml:"TM_MAD"` RequestID string `xml:"REQUEST_ID"`
Snapshots []HistoryRecordSnapshot `xml:"SNAPSHOTS"`
}
type HistoryRecordSnapshot struct {
image.Snapshot
DiskID int `xml:"DISK_ID"`
}
type MonitoringSnapshotSize struct {
DiskID int `xml:"DISK_ID"`
Size int `xml:"SIZE"`
}
// VMUserTemplate contain custom attributes
type UserTemplate struct {
Error string `xml:"ERROR"`
SchedMessage string `xml:"SCHED_MESSAGE"`
Dynamic dyn.UnmatchedTagsMap `xml:",any"`
}
type Template struct {
CPU float64 `xml:"CPU"`
Memory int `xml:"MEMORY"`
NICs []Nic `xml:"NIC"`
NICAliases []NicAlias `xml:"NIC_ALIAS"`
Context *Context `xml:"CONTEXT"`
Disks []Disk `xml:"DISK"`
Graphics *Graphics `xml:"GRAPHICS"`
OS *OS `xml:"OS"`
Snapshots []Snapshot `xml:"SNAPSHOT"`
SecurityGroupRules []SecurityGroupRule `xml:"SECURITY_GROUP_RULE"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type Context struct {
Dynamic dyn.UnmatchedTagsMap `xml:",any"`
}
type Nic struct {
ID int `xml:"NIC_ID"`
Network string `xml:"NETWORK"`
IP string `xml:"IP"`
MAC string `xml:"MAC"`
PhyDev string `xml:"PHYDEV"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type NicAlias struct {
ID int `xml:"NIC_ID"` // minOccurs=1
Parent string `xml:"PARENT"` // minOccurs=1
ParentID string `xml:"PARENT_ID"` // minOccurs=1
}
type Graphics struct {
Listen string `xml:"LISTEN"`
Port string `xml:"PORT"`
Type string `xml:"TYPE"`
}
type Disk struct {
ID int `xml:"DISK_ID"`
Datastore string `xml:"DATASTORE"`
DiskType string `xml:"DISK_TYPE"`
Image string `xml:"IMAGE"`
Driver string `xml:"DRIVER"`
OriginalSize int `xml:"ORIGINAL_SIZE"`
Size int `xml:"SIZE"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
}
type OS struct {
Arch string `xml:"ARCH"`
Boot string `xml:"BOOT"`
}
type SecurityGroupRule struct {
securitygroup.SecurityGroupRule
SecurityGroup string `xml:"SECURITY_GROUP_NAME"`
}
type Snapshot struct {
HypervisorID string `xml:"HYPERVISOR_ID"`
Name string `xml:"NAME"`
ID int `xml:"SNAPSHOT_ID"`
Time string `xml:"TIME"`
} }

View File

@ -1,3 +1,19 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 vm package vm
import "fmt" import "fmt"

View File

@ -17,17 +17,21 @@
package vmgroup package vmgroup
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula VM group pool // Pool represents an OpenNebula VM group pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"VM_GROUP_POOL"`
VMGroups []VMGroup `xml:"VM_GROUP"` VMGroups []VMGroup `xml:"VM_GROUP"`
} }
// VMGroup represents an OpenNebula VM group // VMGroup represents an OpenNebula VM group
type VMGroup struct { type VMGroup struct {
XMLName xml.Name `xml:"VM_GROUP"`
ID int `xml:"ID"` ID int `xml:"ID"`
UID int `xml:"UID"` UID int `xml:"UID"`
GID int `xml:"GID"` GID int `xml:"GID"`
@ -36,18 +40,15 @@ type VMGroup struct {
Name string `xml:"NAME"` Name string `xml:"NAME"`
Permissions *shared.Permissions `xml:"PERMISSIONS"` Permissions *shared.Permissions `xml:"PERMISSIONS"`
LockInfos *shared.Lock `xml:"LOCK"` LockInfos *shared.Lock `xml:"LOCK"`
Roles []vmGroupRole `xml:"ROLES>ROLE"` Roles []Role `xml:"ROLES>ROLE"`
Template Template `xml:"TEMPLATE"` Template dyn.Template `xml:"TEMPLATE"`
} }
type vmGroupRole struct { type Role struct {
ID int `xml:"ID"` ID int `xml:"ID"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
HostAffined string `xml:"HOST_AFFINED"` // minOccurs=0 HostAffined string `xml:"HOST_AFFINED,omitempty"` // minOccurs=0
HostAntiAffined string `xml:"HOST_ANTI_AFFINED"` // minOccurs=0 HostAntiAffined string `xml:"HOST_ANTI_AFFINED,omitempty"` // minOccurs=0
Policy string `xml:"POLICY"` // minOccurs=0 Policy string `xml:"POLICY,omitempty"` // minOccurs=0
} VMs string `xml:"VMS,omitempty"`
type Template struct {
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }

View File

@ -19,30 +19,29 @@ package vntemplate
// Since version 5.8 of OpenNebula // Since version 5.8 of OpenNebula
import ( import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
// Pool represents an OpenNebula Virtual Network Template pool // Pool represents an OpenNebula Virtual Network Template pool
type Pool struct { type Pool struct {
XMLName xml.Name `xml:"VNTEMPLATE_POOL"`
VNTemplates []VNTemplate `xml:"VNTEMPLATE"` VNTemplates []VNTemplate `xml:"VNTEMPLATE"`
} }
// VNTemplate represents an OpenNebula Virtual Network Template // VNTemplate represents an OpenNebula Virtual Network Template
type VNTemplate struct { type VNTemplate struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"VNTEMPLATE"`
UID int `xml:"UID"` ID int `xml:"ID,omitempty"`
GID int `xml:"GID"` UID int `xml:"UID,omitempty"`
UName string `xml:"UNAME"` GID int `xml:"GID,omitempty"`
GName string `xml:"GNAME"` UName string `xml:"UNAME,omitempty"`
GName string `xml:"GNAME,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
LockInfos *shared.Lock `xml:"LOCK"` LockInfos *shared.Lock `xml:"LOCK"`
Permissions shared.Permissions `xml:"PERMISSIONS"` Permissions shared.Permissions `xml:"PERMISSIONS"`
RegTime string `xml:"REGTIME"` RegTime string `xml:"REGTIME"`
Template Template `xml:"TEMPLATE"` Template dyn.Template `xml:"TEMPLATE"`
}
type Template struct {
VNMad string `xml:"VN_MAD"`
Dynamic dyn.UnmatchedTagsSlice `xml:",any"`
} }

View File

@ -17,20 +17,23 @@
package zone package zone
import ( import (
"encoding/xml"
"fmt" "fmt"
) )
// Pool represents an OpenNebula Zone pool // Pool represents an OpenNebula Zone pool
type Pool struct { type Pool struct {
Zones []Zone `xml:"ZONE"` XMLName xml.Name `xml:"ZONE_POOL"`
Zones []Zone `xml:"ZONE"`
} }
// Zone represents an OpenNebula Zone // Zone represents an OpenNebula Zone
type Zone struct { type Zone struct {
ID int `xml:"ID"` XMLName xml.Name `xml:"ZONE"`
ID int `xml:"ID,omitempty"`
Name string `xml:"NAME"` Name string `xml:"NAME"`
Template Template `xml:"TEMPLATE"` Template Template `xml:"TEMPLATE"`
ServerPool []Server `xml:"SERVER_POOL>SERVER"` ServerPool []Server `xml:"SERVER_POOL>SERVER,omitempty"`
} }
type Server struct { type Server struct {

View File

@ -146,8 +146,8 @@ func (sc *SecurityGroupController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds security group content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new security group contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (sc *SecurityGroupController) Update(tpl string, uType parameters.UpdateType) error { func (sc *SecurityGroupController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -20,19 +20,23 @@ import (
"testing" "testing"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup"
secgroup "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/securitygroup/keys"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
) )
func TestSGAllocate(t *testing.T) { func TestSGAllocate(t *testing.T) {
var sg_name string = "new_test_sg" var sg_name string = "new_test_sg"
var sg *securitygroup.SecurityGroup var sg *securitygroup.SecurityGroup
var sg_template string = "NAME = \"" + sg_name + "\"\n" +
"DESCRIPTION = \"test security group\"\n" + sg_template := secgroup.NewTemplate()
"ATT1 = \"VAL1\"\n" + sg_template.Add(keys.Name, sg_name)
"ATT2 = \"VAL2\"" sg_template.Add(keys.Description, "test security group")
sg_template.AddPair("ATT1", "VAL1")
sg_template.AddPair("ATT2", "VAL2")
//Create SG //Create SG
sg_id, err := testCtrl.SecurityGroups().Create(sg_template) sg_id, err := testCtrl.SecurityGroups().Create(sg_template.String())
if err != nil { if err != nil {
t.Fatalf("Test failed:\n" + err.Error()) t.Fatalf("Test failed:\n" + err.Error())
@ -64,7 +68,7 @@ func TestSGAllocate(t *testing.T) {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
} }
actual_1, err := sg.Template.Dynamic.GetContentByName("ATT1") actual_1, err := sg.Template.GetStr("ATT1")
if err != nil { if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error())
} else { } else {
@ -73,7 +77,7 @@ func TestSGAllocate(t *testing.T) {
} }
} }
actual_3, err := sg.Template.Dynamic.GetContentByName("ATT3") actual_3, err := sg.Template.GetStr("ATT3")
if err != nil { if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT3", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT3", err.Error())
} else { } else {

View File

@ -125,8 +125,8 @@ func (tc *TemplatesController) Create(template string) (int, error) {
return response.BodyInt(), nil return response.BodyInt(), nil
} }
// Update replaces the cluster cluster contents. // Update adds template content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new template contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (tc *TemplateController) Update(tpl string, uType parameters.UpdateType) error { func (tc *TemplateController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -21,6 +21,9 @@ import (
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic" dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/template" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/template"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm/keys"
) )
// Helper to create a template // Helper to create a template
@ -28,11 +31,9 @@ func createTemplate(t *testing.T) (*template.Template, int) {
templateName := GenName("template") templateName := GenName("template")
// Create template // Create template
tpl := dyn.NewTemplateBuilder() tpl := vm.NewTemplate()
tpl.Add(keys.Name, templateName)
tpl.AddValue("name", templateName) tpl.CPU(1).Memory(64)
tpl.AddValue("cpu", 1)
tpl.AddValue("memory", "64")
id, err := testCtrl.Templates().Create(tpl.String()) id, err := testCtrl.Templates().Create(tpl.String())
if err != nil { if err != nil {
@ -87,11 +88,9 @@ func TestTemplateInstantiate(t *testing.T) {
templateName := GenName("template") templateName := GenName("template")
// Create template // Create template
tpl := dyn.NewTemplateBuilder() tpl := vm.NewTemplate()
tpl.Add(keys.Name, templateName)
tpl.AddValue("name", templateName) tpl.CPU(1).Memory(64)
tpl.AddValue("cpu", 1)
tpl.AddValue("memory", "64")
id, err := testCtrl.Templates().Create(tpl.String()) id, err := testCtrl.Templates().Create(tpl.String())
if err != nil { if err != nil {
@ -124,8 +123,8 @@ func TestTemplateUpdate(t *testing.T) {
template, _ := createTemplate(t) template, _ := createTemplate(t)
templateCtrl := testCtrl.Template(template.ID) templateCtrl := testCtrl.Template(template.ID)
tpl := dyn.NewTemplateBuilder() tpl := dyn.NewTemplate()
tpl.AddValue("A", "B") tpl.AddPair("A", "B")
// Update // Update
templateCtrl.Update(tpl.String(), 1) templateCtrl.Update(tpl.String(), 1)
@ -135,7 +134,7 @@ func TestTemplateUpdate(t *testing.T) {
t.Error(err) t.Error(err)
} }
val, err := template.Template.Dynamic.GetContentByName("A") val, err := template.Template.GetStr("A")
if err != nil { if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "A", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "A", err.Error())
} else { } else {

View File

@ -30,6 +30,12 @@ type UsersController entitiesController
// UserController is a controller for User entities // UserController is a controller for User entities
type UserController entityController type UserController entityController
// UserByNameController is a controller for an user by it's name
type UserByNameController struct {
c *Controller
Name string
}
// Users returns a Users controller. // Users returns a Users controller.
func (c *Controller) Users() *UsersController { func (c *Controller) Users() *UsersController {
return &UsersController{c} return &UsersController{c}
@ -40,6 +46,11 @@ func (c *Controller) User(id int) *UserController {
return &UserController{c, id} return &UserController{c, id}
} }
// UserByName returns a UserByName controller.
func (c *Controller) UserByName(name string) *UserByNameController {
return &UserByNameController{c, name}
}
// ByName returns a User by Name // ByName returns a User by Name
func (c *UsersController) ByName(name string) (int, error) { func (c *UsersController) ByName(name string) (int, error) {
var id int var id int
@ -130,18 +141,28 @@ func (uc *UserController) Passwd(password string) error {
// * token: The token, if empty oned will generate one // * token: The token, if empty oned will generate one
// * timeSeconds: Valid period in seconds; 0 reset the token and -1 for a non-expiring token. // * timeSeconds: Valid period in seconds; 0 reset the token and -1 for a non-expiring token.
// * effectiveGID: Effective GID to use with this token. To use the current GID and user groups set it to -1 // * effectiveGID: Effective GID to use with this token. To use the current GID and user groups set it to -1
// NOTE: This method make two XML-RPC calls, to make only one call, use UserByName(name).Login(...) method
func (uc *UserController) Login(token string, timeSeconds int, effectiveGID int) error { func (uc *UserController) Login(token string, timeSeconds int, effectiveGID int) error {
user, err := uc.Info(false) user, err := uc.Info(false)
if err != nil { if err != nil {
return err return err
} }
_, err = uc.c.Client.Call("one.user.login", user.Name, token, timeSeconds, effectiveGID) _, err = uc.c.Client.Call("one.user.login", user.Name, token, timeSeconds, effectiveGID)
return err return err
} }
// Update replaces the cluster cluster contents. // Login generates or sets a login token.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * token: The token, if empty oned will generate one
// * timeSeconds: Valid period in seconds; 0 reset the token and -1 for a non-expiring token.
// * effectiveGID: Effective GID to use with this token. To use the current GID and user groups set it to -1
func (uc *UserByNameController) Login(token string, timeSeconds int, effectiveGID int) error {
_, err := uc.c.Client.Call("one.user.login", uc.Name, token, timeSeconds, effectiveGID)
return err
}
// Update adds user content.
// * tpl: The new user contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (uc *UserController) Update(tpl string, uType parameters.UpdateType) error { func (uc *UserController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -119,8 +119,8 @@ func (vc *VDCController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds vdc content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new vdc contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (vc *VDCController) Update(tpl string, uType parameters.UpdateType) error { func (vc *VDCController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -184,8 +184,8 @@ func (vc *VirtualNetworkController) Release(tpl string) error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds virtual network content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new virtual network contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (vc *VirtualNetworkController) Update(tpl string, uType parameters.UpdateType) error { func (vc *VirtualNetworkController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -21,20 +21,21 @@ import (
"testing" "testing"
vn "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork" vn "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork/keys"
) )
var vnTpl = `
NAME = "vntest"
BRIDGE = "vnetbr"
PHYDEV = "eth0"
SECURITY_GROUPS = 0
VLAN_ID = 8000042
VN_MAD = "vxlan"
`
// Helper to create a Virtual Network // Helper to create a Virtual Network
func createVirtualNetwork(t *testing.T) (*vn.VirtualNetwork, int) { func createVirtualNetwork(t *testing.T) (*vn.VirtualNetwork, int) {
id, err := testCtrl.VirtualNetworks().Create(vnTpl, -1)
vnTpl := vn.NewTemplate()
vnTpl.Add(keys.Name, "vntest")
vnTpl.Add(keys.Bridge, "vnetbr")
vnTpl.Add(keys.PhyDev, "eth0")
vnTpl.Add(keys.SecGroups, "0")
vnTpl.Add(keys.VlanID, "8000042")
vnTpl.Add(keys.VNMad, "vxlan")
id, err := testCtrl.VirtualNetworks().Create(vnTpl.String(), -1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -126,8 +126,8 @@ func (vc *VirtualRoutersController) Create(tpl string) (int, error) {
return response.BodyInt(), nil return response.BodyInt(), nil
} }
// Update replaces the cluster cluster contents. // Update adds virtual router content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new virtual router contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (vc *VirtualRouterController) Update(tpl string, uType parameters.UpdateType) error { func (vc *VirtualRouterController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -20,19 +20,25 @@ import (
"testing" "testing"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared" "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
vr "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualrouter" vn "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork"
vnkeys "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualnetwork/keys"
vrouter "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualrouter"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/virtualrouter/keys"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm"
vmkeys "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm/keys"
) )
func TestVirtualRouter(t *testing.T) { func TestVirtualRouter(t *testing.T) {
var vr_name string = "new_vr" var vr_name string = "new_vr"
var vr *vr.VirtualRouter var vr *vrouter.VirtualRouter
var vr_template string = "NAME = \"" + vr_name + "\"\n" +
"VROUTER = YES\n" + vr_template := vrouter.NewTemplate()
"ATT1 = \"VAL1\"\n" + vr_template.Add(keys.Name, vr_name)
"ATT2 = \"VAL2\"" vr_template.AddPair("ATT1", "VAL1")
vr_template.AddPair("ATT2", "VAL2")
//Create VirtualRouter //Create VirtualRouter
vr_id, err := testCtrl.VirtualRouters().Create(vr_template) vr_id, err := testCtrl.VirtualRouters().Create(vr_template.String())
if err != nil { if err != nil {
t.Fatalf("Test failed:\n" + err.Error()) t.Fatalf("Test failed:\n" + err.Error())
@ -64,7 +70,7 @@ func TestVirtualRouter(t *testing.T) {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
} }
actual_1, err := vr.Template.Dynamic.GetContentByName("ATT1") actual_1, err := vr.Template.GetStr("ATT1")
if err != nil { if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error())
} else { } else {
@ -73,7 +79,7 @@ func TestVirtualRouter(t *testing.T) {
} }
} }
actual_3, err := vr.Template.Dynamic.GetContentByName("ATT3") actual_3, err := vr.Template.GetStr("ATT3")
if err != nil { if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT3", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT3", err.Error())
} else { } else {
@ -146,12 +152,12 @@ func TestVirtualRouter(t *testing.T) {
t.Errorf("Test failed, expected: '%s', got: '%s'", rename, actual) t.Errorf("Test failed, expected: '%s', got: '%s'", rename, actual)
} }
tmpl = "NAME = vrtemplate\n" + vrTmpl := vm.NewTemplate()
"CPU = 0.1\n" + vrTmpl.Add(vmkeys.Name, "vrtemplate")
"VROUTER = YES\n" + vrTmpl.Add(vmkeys.VRouter, "YES")
"MEMORY = 64\n" vrTmpl.CPU(0.1).Memory(64)
tmpl_id, err := testCtrl.Templates().Create(tmpl) tmpl_id, err := testCtrl.Templates().Create(vrTmpl.String())
if err != nil { if err != nil {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
} }
@ -173,16 +179,18 @@ func TestVirtualRouter(t *testing.T) {
template.Delete() template.Delete()
vn_tmpl := "NAME = \"go-net\"\n" + vn_tmpl := vn.NewTemplate()
"BRIDGE = vbr0\n" + vn_tmpl.Add(vnkeys.Name, "go-net")
"VN_MAD = dummy\n" vn_tmpl.Add(vnkeys.Bridge, "vbr0")
vn_tmpl.Add(vnkeys.VNMad, "dummy")
vnet_id, _ := testCtrl.VirtualNetworks().Create(vn_tmpl, 0) vnet_id, _ := testCtrl.VirtualNetworks().Create(vn_tmpl.String(), 0)
nic_tmpl := "NIC = [ NETWORK=\"go-net\" ]" nic_tmpl := shared.NewNIC()
nic_tmpl.Add(shared.Network, "go-net")
//Attach nic to VirtualRouter //Attach nic to VirtualRouter
err = vrC.AttachNic(nic_tmpl) err = vrC.AttachNic(nic_tmpl.String())
if err != nil { if err != nil {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
@ -193,10 +201,11 @@ func TestVirtualRouter(t *testing.T) {
t.Errorf("Test failed:\n" + err.Error()) t.Errorf("Test failed:\n" + err.Error())
} }
if len(vr.Template.NIC) == 0 { nics := vr.Template.GetVectors(string(shared.NICVec))
if len(nics) == 0 {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "NIC", err.Error()) t.Errorf("Test failed, can't retrieve '%s', error: %s", "NIC", err.Error())
} else { } else {
actualNetName, _ := vr.Template.NIC[0].Dynamic.GetContentByName("NETWORK") actualNetName, _ := nics[0].GetStr("NETWORK")
if actualNetName != "go-net" { if actualNetName != "go-net" {
t.Errorf("Test failed, expected: '%s', got: '%s'", "go-net", actualNetName) t.Errorf("Test failed, expected: '%s', got: '%s'", "go-net", actualNetName)

View File

@ -226,8 +226,8 @@ func (vc *VMController) Action(action string) error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds vm content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new vm contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (vc *VMController) Update(tpl string, uType parameters.UpdateType) error { func (vc *VMController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -19,9 +19,11 @@ package goca
import ( import (
"testing" "testing"
ds "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/datastore"
dskeys "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/datastore/keys"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/vm/keys"
. "gopkg.in/check.v1" . "gopkg.in/check.v1"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
) )
// Hook up gocheck into the "go test" runner. // Hook up gocheck into the "go test" runner.
@ -37,11 +39,10 @@ var _ = Suite(&VMSuite{})
func (s *VMSuite) SetUpSuite(c *C) { func (s *VMSuite) SetUpSuite(c *C) {
// Create template // Create template
tpl := dyn.NewTemplateBuilder() vmName := GenName("VMSuite-template")
tpl := vm.NewTemplate()
tpl.AddValue("NAME", GenName("VMSuite-template")) tpl.Add(keys.Name, vmName)
tpl.AddValue("CPU", 1) tpl.CPU(1).Memory(64)
tpl.AddValue("MEMORY", "64")
templateID, err := testCtrl.Templates().Create(tpl.String()) templateID, err := testCtrl.Templates().Create(tpl.String())
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -50,11 +51,13 @@ func (s *VMSuite) SetUpSuite(c *C) {
s.hostID, _ = testCtrl.Hosts().Create("dummy-test", "dummy", "dummy", 0) s.hostID, _ = testCtrl.Hosts().Create("dummy-test", "dummy", "dummy", 0)
tmpl := "TM_MAD=dummy\nDS_MAD=dummy" tmpl := ds.NewTemplate()
tmpl.Add(dskeys.TMMAD, "dummy")
tmpl.Add(dskeys.DSMAD, "dummy")
testCtrl.Datastore(1).Update(tmpl, 1) testCtrl.Datastore(1).Update(tmpl.String(), 1)
testCtrl.Datastore(0).Update(tmpl, 1) testCtrl.Datastore(0).Update(tmpl.String(), 1)
} }
@ -133,7 +136,7 @@ func (s *VMSuite) TestVMUpdate(c *C) {
vm, err := vmC.Info(false) vm, err := vmC.Info(false)
c.Assert(err, IsNil) c.Assert(err, IsNil)
val := vm.UserTemplate.Dynamic.GetContentByName("A") val, _ := vm.UserTemplate.GetStr("A")
c.Assert(val, Equals, "B") c.Assert(val, Equals, "B")
} }
@ -237,7 +240,9 @@ func (s *VMSuite) TestVMResize(c *C) {
vm, err := vmC.Info(false) vm, err := vmC.Info(false)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(vm.Template.CPU, Equals, 2.5) cpu, _ := vm.Template.GetCPU()
mem, _ := vm.Template.GetMemory()
c.Assert(vm.Template.Memory, Equals, 512) c.Assert(cpu, Equals, 2.5)
c.Assert(mem, Equals, 512)
} }

View File

@ -142,7 +142,7 @@ func (vc *VMGroupController) Delete() error {
return err return err
} }
// Update replaces the vmGroup template contents. // Update replaces the vmGroup template content.
// * tpl: The new vmGroup template contents. Syntax can be the usual attribute=value or XML. // * tpl: The new vmGroup template contents. Syntax can be the usual attribute=value or XML.
// * appendTemplate: Update type: 0: Replace the whole template. 1: Merge new template with the existing one. // * appendTemplate: Update type: 0: Replace the whole template. 1: Merge new template with the existing one.
func (vc *VMGroupController) Update(tpl string, uType int) error { func (vc *VMGroupController) Update(tpl string, uType int) error {

View File

@ -128,8 +128,8 @@ func (vc *VNTemplateController) Create(vntemplate string) (int, error) {
return response.BodyInt(), nil return response.BodyInt(), nil
} }
// Update replaces the cluster cluster contents. // Update adds vntemplate content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new vntemplate contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (vc *VNTemplateController) Update(tpl string, uType parameters.UpdateType) error { func (vc *VNTemplateController) Update(tpl string, uType parameters.UpdateType) error {

View File

@ -117,8 +117,8 @@ func (zc *ZoneController) Delete() error {
return err return err
} }
// Update replaces the cluster cluster contents. // Update adds zone content.
// * tpl: The new cluster contents. Syntax can be the usual attribute=value or XML. // * tpl: The new zone contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template. // * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one. // Merge: Merge new template with the existing one.
func (zc *ZoneController) Update(tpl string, uType parameters.UpdateType) error { func (zc *ZoneController) Update(tpl string, uType parameters.UpdateType) error {