From 6fc548c08bbf3dc1d232da25dfdc8fa376738041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Philippe=20Four=C3=A8s?= <38558303+jp-pro@users.noreply.github.com> Date: Wed, 5 Dec 2018 17:16:38 +0100 Subject: [PATCH] F #2656: add missing XML RPC Go Bindings --- src/oca/go/src/goca/goca.go | 10 ++ src/oca/go/src/goca/marketplace.go | 131 ++++++++++++++++++ src/oca/go/src/goca/marketplaceapp.go | 173 ++++++++++++++++++++++++ src/oca/go/src/goca/securitygroup.go | 148 +++++++++++++++++++++ src/oca/go/src/goca/virtualrouter.go | 183 ++++++++++++++++++++++++++ 5 files changed, 645 insertions(+) create mode 100644 src/oca/go/src/goca/marketplace.go create mode 100644 src/oca/go/src/goca/marketplaceapp.go create mode 100644 src/oca/go/src/goca/securitygroup.go create mode 100644 src/oca/go/src/goca/virtualrouter.go diff --git a/src/oca/go/src/goca/goca.go b/src/oca/go/src/goca/goca.go index b820fa0c76..279d672916 100644 --- a/src/oca/go/src/goca/goca.go +++ b/src/oca/go/src/goca/goca.go @@ -118,6 +118,16 @@ func SystemVersion() (string, error) { return response.Body(), nil } +// SystemConfig returns the current OpenNebula config +func SystemConfig() (string, error) { + response, err := client.Call("one.system.config") + if err != nil { + return "", err + } + + return response.Body(), nil +} + // Call is an XML-RPC wrapper. It returns a pointer to response and an error. func (c *oneClient) Call(method string, args ...interface{}) (*response, error) { var ( diff --git a/src/oca/go/src/goca/marketplace.go b/src/oca/go/src/goca/marketplace.go new file mode 100644 index 0000000000..48d7a2b63d --- /dev/null +++ b/src/oca/go/src/goca/marketplace.go @@ -0,0 +1,131 @@ +package goca + +import "errors" + +// MarketPlace represents an OpenNebula MarketPlace +type MarketPlace struct { + XMLResource + ID uint + Name string +} + +// MarketPlacePool represents an OpenNebula MarketPlacePool +type MarketPlacePool struct { + XMLResource +} + +// NewMarketPlacePool returns a marketplace pool. A connection to OpenNebula is +// performed. +func NewMarketPlacePool(args ...int) (*MarketPlacePool, error) { + var who, start, end int + + switch len(args) { + case 0: + who = PoolWhoMine + start = -1 + end = -1 + case 1: + who = args[0] + start = -1 + end = -1 + case 3: + who = args[0] + start = args[1] + end = args[2] + default: + return nil, errors.New("Wrong number of arguments") + } + + response, err := client.Call("one.marketpool.info", who, start, end) + if err != nil { + return nil, err + } + + marketpool := &MarketPlacePool{XMLResource{body: response.Body()}} + + return marketpool, err +} + +// NewMarketPlace finds a marketplace object by ID. No connection to OpenNebula. +func NewMarketPlace(id uint) *MarketPlace { + return &MarketPlace{ID: id} +} + +// NewMarketPlaceFromName finds a marketplace object by name. It connects to +// OpenNebula to retrieve the pool, but doesn't perform the Info() call to +// retrieve the attributes of the marketplace. +func NewMarketPlaceFromName(name string) (*MarketPlace, error) { + marketPool, err := NewMarketPlacePool() + if err != nil { + return nil, err + } + + id, err := marketPool.GetIDFromName(name, "/MARKETPLACE_POOL/MARKETPLACE") + if err != nil { + return nil, err + } + + return NewMarketPlace(id), nil +} + +// CreateMarketPlace allocates a new marketplace. It returns the new marketplace ID. +// * tpl: template of the marketplace +func CreateMarketPlace(tpl string) (uint, error) { + response, err := client.Call("one.market.allocate", tpl) + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Delete deletes the given marketplace from the pool. +func (market *MarketPlace) Delete() error { + _, err := client.Call("one.market.delete", market.ID) + return err +} + +// Update replaces the marketplace template contents. +// * tpl: The new 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. +func (market *MarketPlace) Update(tpl string, appendTemplate int) error { + _, err := client.Call("one.market.update", market.ID, tpl, appendTemplate) + return err +} + +// Chmod changes the permission bits of a marketplace +// * uu: USER USE bit. If set to -1, it will not change. +// * um: USER MANAGE bit. If set to -1, it will not change. +// * ua: USER ADMIN bit. If set to -1, it will not change. +// * gu: GROUP USE bit. If set to -1, it will not change. +// * gm: GROUP MANAGE bit. If set to -1, it will not change. +// * ga: GROUP ADMIN bit. If set to -1, it will not change. +// * ou: OTHER USE bit. If set to -1, it will not change. +// * om: OTHER MANAGE bit. If set to -1, it will not change. +// * oa: OTHER ADMIN bit. If set to -1, it will not change. +func (market *MarketPlace) Chmod(uu, um, ua, gu, gm, ga, ou, om, oa int) error { + _, err := client.Call("one.market.chmod", market.ID, uu, um, ua, gu, gm, ga, ou, om, oa) + return err +} + +// Chown changes the ownership of a marketplace. +// * userID: The User ID of the new owner. If set to -1, it will not change. +// * groupID: The Group ID of the new group. If set to -1, it will not change. +func (market *MarketPlace) Chown(userID, groupID uint) error { + _, err := client.Call("one.market.chown", market.ID, int(userID), int(groupID)) + return err +} + +// Rename renames a marketplace. +// * newName: The new name. +func (market *MarketPlace) Rename(newName string) error { + _, err := client.Call("one.market.rename", market.ID, newName) + return err +} + +// Info retrieves information for the marketplace. +func (market *MarketPlace) Info() error { + response, err := client.Call("one.market.info", market.ID) + market.body = response.Body() + return err +} diff --git a/src/oca/go/src/goca/marketplaceapp.go b/src/oca/go/src/goca/marketplaceapp.go new file mode 100644 index 0000000000..7423ec8914 --- /dev/null +++ b/src/oca/go/src/goca/marketplaceapp.go @@ -0,0 +1,173 @@ +package goca + +import "errors" + +// MarketPlaceApp represents an OpenNebula MarketPlaceApp +type MarketPlaceApp struct { + XMLResource + ID uint + Name string +} + +// MarketPlaceAppPool represents an OpenNebula MarketPlaceAppPool +type MarketPlaceAppPool struct { + XMLResource +} + +// NewMarketPlaceAppPool returns a marketplace app pool. A connection to OpenNebula is +// performed. +func NewMarketPlaceAppPool(args ...int) (*MarketPlaceAppPool, error) { + var who, start, end int + + switch len(args) { + case 0: + who = PoolWhoMine + start = -1 + end = -1 + case 1: + who = args[0] + start = -1 + end = -1 + case 3: + who = args[0] + start = args[1] + end = args[2] + default: + return nil, errors.New("Wrong number of arguments") + } + + response, err := client.Call("one.marketapppool.info", who, start, end) + if err != nil { + return nil, err + } + + marketapppool := &MarketPlaceAppPool{XMLResource{body: response.Body()}} + + return marketapppool, err +} + +// NewMarketPlaceApp finds a marketplace app object by ID. No connection to OpenNebula. +func NewMarketPlaceApp(id uint) *MarketPlaceApp { + return &MarketPlaceApp{ID: id} +} + +// NewMarketPlaceAppFromName finds a marketplace app object by name. It connects to +// OpenNebula to retrieve the pool, but doesn't perform the Info() call to +// retrieve the attributes of the marketplace app. +func NewMarketPlaceAppFromName(name string) (*MarketPlaceApp, error) { + marketAppPool, err := NewMarketPlaceAppPool() + if err != nil { + return nil, err + } + + id, err := marketAppPool.GetIDFromName(name, "/MARKETPLACEAPP_POOL/MARKETPLACEAPP") + if err != nil { + return nil, err + } + + return NewMarketPlaceApp(id), nil +} + +// CreateMarketPlaceApp allocates a new marketplace app. It returns the new marketplace app ID. +// * tpl: template of the marketplace app +// * market: market place ID +func CreateMarketPlaceApp(tpl string, market int) (uint, error) { + response, err := client.Call("one.marketapp.allocate", tpl, market) + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Delete deletes the given marketplace app from the pool. +func (marketApp *MarketPlaceApp) Delete() error { + _, err := client.Call("one.marketapp.delete", marketApp.ID) + return err +} + +// Enable enables or disables a marketplace app. +// * enable: True for enabling, False for disabling +func (marketApp *MarketPlaceApp) Enable(enable bool) error { + _, err := client.Call("one.marketapp.enable", marketApp.ID, enable) + return err +} + +// Update replaces the marketplace app template contents. +// * tpl: The new 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. +func (marketApp *MarketPlaceApp) Update(tpl string, appendTemplate int) error { + _, err := client.Call("one.marketapp.update", marketApp.ID, tpl, appendTemplate) + return err +} + +// Chmod changes the permission bits of a marketplace app +// * uu: USER USE bit. If set to -1, it will not change. +// * um: USER MANAGE bit. If set to -1, it will not change. +// * ua: USER ADMIN bit. If set to -1, it will not change. +// * gu: GROUP USE bit. If set to -1, it will not change. +// * gm: GROUP MANAGE bit. If set to -1, it will not change. +// * ga: GROUP ADMIN bit. If set to -1, it will not change. +// * ou: OTHER USE bit. If set to -1, it will not change. +// * om: OTHER MANAGE bit. If set to -1, it will not change. +// * oa: OTHER ADMIN bit. If set to -1, it will not change. +func (marketApp *MarketPlaceApp) Chmod(uu, um, ua, gu, gm, ga, ou, om, oa int) error { + _, err := client.Call("one.marketapp.chmod", marketApp.ID, uu, um, ua, gu, gm, ga, ou, om, oa) + return err +} + +// Chown changes the ownership of a marketplace app. +// * userID: The User ID of the new owner. If set to -1, it will not change. +// * groupID: The Group ID of the new group. If set to -1, it will not change. +func (marketApp *MarketPlaceApp) Chown(userID, groupID uint) error { + _, err := client.Call("one.marketapp.chown", marketApp.ID, int(userID), int(groupID)) + return err +} + +// Rename renames a marketplace app. +// * newName: The new name. +func (marketApp *MarketPlaceApp) Rename(newName string) error { + _, err := client.Call("one.marketapp.rename", marketApp.ID, newName) + return err +} + +// Info retrieves information for the marketplace app. +func (marketApp *MarketPlaceApp) Info() error { + response, err := client.Call("one.marketapp.info", marketApp.ID) + marketApp.body = response.Body() + return err +} + +// Lock locks the marketplace app depending on blocking level. +func (marketApp *MarketPlaceApp) Lock(level uint) error { + _, err := client.Call("one.marketapp.lock", marketApp.ID, level) + return err +} + +// Unlock unlocks the marketplace app. +func (marketApp *MarketPlaceApp) Unlock() error { + _, err := client.Call("one.marketapp.unlock", marketApp.ID) + return err +} + +// Lock actions + +// LockUse locks USE actions for the marketplace app +func (marketApp *MarketPlaceApp) LockUse() error { + return marketApp.Lock(1) +} + +// LockManage locks MANAGE actions for the marketplace app +func (marketApp *MarketPlaceApp) LockManage() error { + return marketApp.Lock(2) +} + +// LockAdmin locks ADMIN actions for the marketplace app +func (marketApp *MarketPlaceApp) LockAdmin() error { + return marketApp.Lock(3) +} + +// LockAll locks all actions for the marketplace app +func (marketApp *MarketPlaceApp) LockAll() error { + return marketApp.Lock(4) +} diff --git a/src/oca/go/src/goca/securitygroup.go b/src/oca/go/src/goca/securitygroup.go new file mode 100644 index 0000000000..6dddd53a0d --- /dev/null +++ b/src/oca/go/src/goca/securitygroup.go @@ -0,0 +1,148 @@ +package goca + +import "errors" + +// SecurityGroup represents an OpenNebula SecurityGroup +type SecurityGroup struct { + XMLResource + ID uint + Name string +} + +// SecurityGroupPool represents an OpenNebula SecurityGroupPool +type SecurityGroupPool struct { + XMLResource +} + +// NewSecurityGroupPool returns a security group pool. A connection to OpenNebula is +// performed. +func NewSecurityGroupPool(args ...int) (*SecurityGroupPool, error) { + var who, start, end int + + switch len(args) { + case 0: + who = PoolWhoMine + start = -1 + end = -1 + case 1: + who = args[0] + start = -1 + end = -1 + case 3: + who = args[0] + start = args[1] + end = args[2] + default: + return nil, errors.New("Wrong number of arguments") + } + + response, err := client.Call("one.secgrouppool.info", who, start, end) + if err != nil { + return nil, err + } + + secgrouppool := &SecurityGroupPool{XMLResource{body: response.Body()}} + + return secgrouppool, err +} + +// NewSecurityGroup finds a security group object by ID. No connection to OpenNebula. +func NewSecurityGroup(id uint) *SecurityGroup { + return &SecurityGroup{ID: id} +} + +// NewSecurityGroupFromName finds a security group object by name. It connects to +// OpenNebula to retrieve the pool, but doesn't perform the Info() call to +// retrieve the attributes of the security group. +func NewSecurityGroupFromName(name string) (*SecurityGroup, error) { + secgroupPool, err := NewSecurityGroupPool() + if err != nil { + return nil, err + } + + id, err := secgroupPool.GetIDFromName(name, "/SECURITY_GROUP_POOL/SECURITY_GROUP") + if err != nil { + return nil, err + } + + return NewSecurityGroup(id), nil +} + +// CreateSecurityGroup allocates a new security group. It returns the new security group ID. +// * tpl: template of the security group +func CreateSecurityGroup(tpl string) (uint, error) { + response, err := client.Call("one.secgroup.allocate", tpl) + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Clone clones an existing security group. It returns the clone ID +func (sg *SecurityGroup) Clone(cloneName string) (uint, error) { + response, err := client.Call("one.secgroup.clone", sg.ID, cloneName) + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Delete deletes the given security group from the pool. +func (sg *SecurityGroup) Delete() error { + _, err := client.Call("one.secgroup.delete", sg.ID) + return err +} + +// Update replaces the security group template contents. +// * tpl: The new 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. +func (sg *SecurityGroup) Update(tpl string, appendTemplate int) error { + _, err := client.Call("one.secgroup.update", sg.ID, tpl, appendTemplate) + return err +} + +// Commit apply security group changes to associated VMs. +// * recovery: If set the commit operation will only operate on outdated and error VMs. If not set operate on all VMs +func (sg *SecurityGroup) Commit(recovery bool) error { + _, err := client.Call("one.secgroup.commit", sg.ID, recovery) + return err +} + +// Chmod changes the permission bits of a security group +// * uu: USER USE bit. If set to -1, it will not change. +// * um: USER MANAGE bit. If set to -1, it will not change. +// * ua: USER ADMIN bit. If set to -1, it will not change. +// * gu: GROUP USE bit. If set to -1, it will not change. +// * gm: GROUP MANAGE bit. If set to -1, it will not change. +// * ga: GROUP ADMIN bit. If set to -1, it will not change. +// * ou: OTHER USE bit. If set to -1, it will not change. +// * om: OTHER MANAGE bit. If set to -1, it will not change. +// * oa: OTHER ADMIN bit. If set to -1, it will not change. +func (sg *SecurityGroup) Chmod(uu, um, ua, gu, gm, ga, ou, om, oa int) error { + _, err := client.Call("one.secgroup.chmod", sg.ID, uu, um, ua, gu, gm, ga, ou, om, oa) + return err +} + +// Chown changes the ownership of a security group. +// * userID: The User ID of the new owner. If set to -1, it will not change. +// * groupID: The Group ID of the new group. If set to -1, it will not change. +func (sg *SecurityGroup) Chown(userID, groupID uint) error { + _, err := client.Call("one.secgroup.chown", sg.ID, int(userID), int(groupID)) + return err +} + +// Rename renames a security group. +// * newName: The new name. +func (sg *SecurityGroup) Rename(newName string) error { + _, err := client.Call("one.secgroup.rename", sg.ID, newName) + return err +} + +// Info retrieves information for the security group. +func (sg *SecurityGroup) Info() error { + response, err := client.Call("one.secgroup.info", sg.ID) + sg.body = response.Body() + return err +} diff --git a/src/oca/go/src/goca/virtualrouter.go b/src/oca/go/src/goca/virtualrouter.go new file mode 100644 index 0000000000..75cfa8e4b4 --- /dev/null +++ b/src/oca/go/src/goca/virtualrouter.go @@ -0,0 +1,183 @@ +package goca + +import ( + "errors" +) + +// VirtualRouter represents an OpenNebula VirtualRouter +type VirtualRouter struct { + XMLResource + ID uint + Name string +} + +// VirtualRouterPool represents an OpenNebula VirtualRouterPool +type VirtualRouterPool struct { + XMLResource +} + +// NewVirtualRouterPool returns a virtual router pool. A connection to OpenNebula is +// performed. +func NewVirtualRouterPool(args ...int) (*VirtualRouterPool, error) { + var who, start, end int + + switch len(args) { + case 0: + who = PoolWhoMine + start = -1 + end = -1 + case 3: + who = args[0] + start = args[1] + end = args[2] + default: + return nil, errors.New("Wrong number of arguments") + } + + response, err := client.Call("one.vrouterpool.info", who, start, end) + if err != nil { + return nil, err + } + + vrouterpool := &VirtualRouterPool{XMLResource{body: response.Body()}} + + return vrouterpool, err + +} + +// NewVirtualRouter finds a virtual router object by ID. No connection to OpenNebula. +func NewVirtualRouter(id uint) *VirtualRouter { + return &VirtualRouter{ID: id} +} + +// NewVirtualRouterFromName finds a virtual router object by name. It connects to +// OpenNebula to retrieve the pool, but doesn't perform the Info() call to +// retrieve the attributes of the virtual router. +func NewVirtualRouterFromName(name string) (*VirtualRouter, error) { + vrouterPool, err := NewVirtualRouterPool() + if err != nil { + return nil, err + } + + id, err := vrouterPool.GetIDFromName(name, "/VROUTER_POOL/VROUTER") + if err != nil { + return nil, err + } + + return NewVirtualRouter(id), nil +} + +// CreateVirtualRouter allocates a new virtual router. It returns the new Virtual Router ID +// * tpl: template of the marketplace +func CreateVirtualRouter(tpl string) (uint, error) { + response, err := client.Call("one.vrouter.allocate", tpl) + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Info connects to OpenNebula and fetches the information of the VirtualRouter +func (vr *VirtualRouter) Info() error { + response, err := client.Call("one.vrouter.info", vr.ID) + vr.body = response.Body() + return err +} + +// Update will modify the virtual router. If appendVirtualRouter is 0, it will +// replace the whole virtual router. If its 1, it will merge. +func (vr *VirtualRouter) Update(tpl string, appendVirtualRouter int) error { + _, err := client.Call("one.vrouter.update", vr.ID, tpl, appendVirtualRouter) + return err +} + +// Chown changes the owner/group of a virtual router. If uid or gid is -1 it will not +// change +func (vr *VirtualRouter) Chown(uid, gid int) error { + _, err := client.Call("one.vrouter.chown", vr.ID, uid, gid) + return err +} + +// Chmod changes the permissions of a virtual router. If any perm is -1 it will not +// change +func (vr *VirtualRouter) Chmod(uu, um, ua, gu, gm, ga, ou, om, oa int) error { + _, err := client.Call("one.vrouter.chmod", vr.ID, uu, um, ua, gu, gm, ga, ou, om, oa) + return err +} + +// Rename changes the name of virtual router +func (vr *VirtualRouter) Rename(newName string) error { + _, err := client.Call("one.vrouter.rename", vr.ID, newName) + return err +} + +// Delete will remove the virtual router from OpenNebula. +func (vr *VirtualRouter) Delete() error { + _, err := client.Call("one.vrouter.delete", vr.ID) + return err +} + +// Instantiate will instantiate the virtual router. It returns the ID of the new VM +// * number: Number of VMs to instantiate. +// * tplid: VM Template id to instantiate. +// * name: Name for the VM instances. If it is an empty string OpenNebula will set a default name. Wildcard %i can be used. +// * hold: False to create the VM on pending (default), True to create it on hold. +// * extra: A string containing an extra template to be merged with the one being instantiated. It can be empty. Syntax can be the usual attribute=value or XML. +func (vr *VirtualRouter) Instantiate(number, tplid int, name string, hold bool, extra string) (uint, error) { + response, err := client.Call("one.vrouter.instantiate", vr.ID, number, tplid, name, hold, extra) + + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// AttachNic attaches a new network interface to the virtual router and the virtual machines. +// * tpl: NIC template string +func (vr *VirtualRouter) AttachNic(tpl string) error { + _, err := client.Call("one.vrouter.attachnic", vr.ID, tpl) + return err +} + +// DetachNic detaches a network interface from the virtual router and the virtual machines +// * nicid: NIC ID to detach +func (vr *VirtualRouter) DetachNic(nicid uint) error { + _, err := client.Call("one.vrouter.detachnic", vr.ID, nicid) + return err +} + +// Lock locks the virtual router depending on blocking level. +func (vr *VirtualRouter) Lock(level uint) error { + _, err := client.Call("one.vrouter.lock", vr.ID, level) + return err +} + +// Unlock unlocks the virtual router. +func (vr *VirtualRouter) Unlock() error { + _, err := client.Call("one.vrouter.unlock", vr.ID) + return err +} + +// Lock actions + +// LockUse locks USE actions for the virtual router +func (vr *VirtualRouter) LockUse() error { + return vr.Lock(1) +} + +// LockManage locks MANAGE actions for the virtual router +func (vr *VirtualRouter) LockManage() error { + return vr.Lock(2) +} + +// LockAdmin locks ADMIN actions for the virtual router +func (vr *VirtualRouter) LockAdmin() error { + return vr.Lock(3) +} + +// LockAll locks all actions for the virtual router +func (vr *VirtualRouter) LockAll() error { + return vr.Lock(4) +}