1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-04-01 06:50:25 +03:00

F #6311: GOCA - marketplace state

- Add state to Markeplace
- Add state Markeplace Appliance
- Add enable method for Marketplace
- Add tests and use gocheck

co-authored-by: Pavel Czerny <pczerny@opennebula.io>

Signed-off-by: Pierre Lafievre <pierre.lafievre@iguanesolutions.com>
This commit is contained in:
Pierre Lafievre 2023-09-12 18:02:53 +02:00 committed by Ruben S. Montero
parent 4c1ab6efee
commit 4673721a21
No known key found for this signature in database
GPG Key ID: A0CEA6FA880A1D87
7 changed files with 448 additions and 211 deletions

View File

@ -123,10 +123,17 @@ func (mc *MarketPlaceController) Delete() error {
return err
}
// Enable enables or disables a marketplace.
// * enable: True for enabling, False for disabling
func (mc *MarketPlaceController) Enable(enable bool) error {
_, err := mc.c.Client.Call("one.market.enable", mc.ID, enable)
return err
}
// Update adds marketplace content.
// * tpl: The new marketplace contents. Syntax can be the usual attribute=value or XML.
// * uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one.
// - tpl: The new marketplace contents. Syntax can be the usual attribute=value or XML.
// - uType: Update type: Replace: Replace the whole template.
// Merge: Merge new template with the existing one.
func (mc *MarketPlaceController) Update(tpl string, uType parameters.UpdateType) error {
_, err := mc.c.Client.Call("one.market.update", mc.ID, tpl, uType)
return err

View File

@ -17,142 +17,142 @@
package goca
import (
"testing"
"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/parameters"
. "gopkg.in/check.v1"
)
func TestMarketplace(t *testing.T) {
var mkt_name string = "marketplace_test_go"
type MarketPlaceSuite struct {
marketName string
marketID int
}
var market *marketplace.MarketPlace
var _ = Suite(&MarketPlaceSuite{})
func (s *MarketPlaceSuite) SetUpTest(c *C) {
// Create Marketpkace
s.marketName = "marketplace_test_go"
tpl := marketplace.NewTemplate()
tpl.Add(keys.Name, mkt_name)
tpl.Add(keys.Name, s.marketName)
tpl.Add(keys.MarketMAD, "http")
tpl.Add(keys.BaseUrl, "http://url/")
tpl.Add(keys.PublicDir, "/var/loca/market-http")
tpl.Add(keys.PublicDir, "/var/local/market-http")
//Create Marketpkace
market_id, err := testCtrl.MarketPlaces().Create(tpl.String())
if err != nil {
t.Fatalf("Test failed:\n" + err.Error())
}
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
marketCtrl := testCtrl.MarketPlace(market_id)
market, err = marketCtrl.Info(false)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
actual := market.Name
if actual != mkt_name {
t.Errorf("Test failed, expected: '%s', got: '%s'", mkt_name, actual)
}
tmpl := "ATT1 = \"VAL1\""
//Update Marketpkace
err = marketCtrl.Update(tmpl, 1)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
market, err = marketCtrl.Info(false)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
actual_mm := market.MarketMad
actual_1, err := market.Template.GetStr("ATT1")
if err != nil {
t.Errorf("Test failed, can't retrieve '%s', error: %s", "ATT1", err.Error())
} else {
if actual_1 != "VAL1" {
t.Errorf("Test failed, expected: '%s', got: '%s'", "VAL1", actual_1)
}
}
if actual_mm != "http" {
t.Errorf("Test failed, expected: '%s', got: '%s'", "http", actual_mm)
}
//Change permissions for Marketpkace
err = marketCtrl.Chmod(shared.Permissions{1, 1, 1, 1, 1, 1, 1, 1, 1})
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
market, err = marketCtrl.Info(false)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
expected_perm := shared.Permissions{1, 1, 1, 1, 1, 1, 1, 1, 1}
actual_perm := *market.Permissions
if actual_perm != expected_perm {
t.Errorf("Test failed, expected: '%s', got: '%s'", expected_perm.String(), actual_perm.String())
}
//Change owner of Marketpkace
err = marketCtrl.Chown(1, 1)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
market, err = marketCtrl.Info(false)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
expected_usr := 1
expected_grp := 1
actual_usr := market.UID
actual_grp := market.GID
if actual_usr != expected_usr {
t.Errorf("Test failed, expected: '%d', got: '%d'", expected_usr, actual_usr)
}
if actual_grp != expected_grp {
t.Errorf("Test failed, expected: '%d', got: '%d'", expected_grp, actual_grp)
}
rename := mkt_name + "-renamed"
//Rename Marketpkace
err = marketCtrl.Rename(rename)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
market, err = marketCtrl.Info(false)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
actual = market.Name
if actual != rename {
t.Errorf("Test failed, expected: '%s', got: '%s'", rename, actual)
}
//Delete Marketpkace
err = marketCtrl.Delete()
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
id, err := testCtrl.MarketPlaces().Create(tpl.String())
c.Assert(err, IsNil)
s.marketID = id
}
func (s *MarketPlaceSuite) TearDownTest(c *C) {
// Delete Marketpkace
marketC := testCtrl.MarketPlace(s.marketID)
err := marketC.Delete()
c.Assert(err, IsNil)
}
func (s *MarketPlaceSuite) TestGetByNameAndID(c *C) {
// Get MarketPlace by ID
market, err := testCtrl.MarketPlace(s.marketID).Info(false)
c.Assert(err, IsNil)
c.Assert(market.ID, Equals, s.marketID)
c.Assert(market.Name, Equals, s.marketName)
c.Assert(market.MarketMad, Equals, "http")
state, err := market.State()
c.Assert(err, IsNil)
c.Assert(state, Equals, marketplace.Enabled);
// Test value from MarketPlace template
baseUrl, err := market.Template.Get(keys.BaseUrl)
c.Assert(err, IsNil)
c.Assert(baseUrl, Equals, "http://url/")
// Get Backup Job by Name
id, err := testCtrl.MarketPlaces().ByName(s.marketName)
c.Assert(err, IsNil)
c.Assert(id, Equals, s.marketID)
}
func (s *MarketPlaceSuite) TestUpdate(c *C) {
marketC := testCtrl.MarketPlace(s.marketID)
err := marketC.Update(`ATT1 = "VAL1"`, parameters.Merge)
c.Assert(err, IsNil)
market, err := testCtrl.MarketPlace(s.marketID).Info(false)
c.Assert(err, IsNil)
att, err := market.Template.Get("ATT1")
c.Assert(err, IsNil)
c.Assert(att, Equals, "VAL1")
c.Assert(market.MarketMad, Equals, "http")
}
func (s *MarketPlaceSuite) TestRename(c *C) {
marketC := testCtrl.MarketPlace(s.marketID)
marketC.Rename("new_name")
market, err := testCtrl.MarketPlace(s.marketID).Info(false)
c.Assert(err, IsNil)
c.Assert(market.Name, Equals, "new_name");
}
func (s *MarketPlaceSuite) TestChown(c *C) {
// Test only if the call exists, no real change
marketC := testCtrl.MarketPlace(s.marketID)
err := marketC.Chown(1, 1)
c.Assert(err, IsNil)
market, err := testCtrl.MarketPlace(s.marketID).Info(false)
c.Assert(err, IsNil)
c.Assert(market.UID, Equals, 1);
c.Assert(market.GID, Equals, 1);
}
func (s *MarketPlaceSuite) TestChmod(c *C) {
new_permissions := shared.Permissions{1, 1, 1, 1, 1, 1, 1, 1, 1}
marketC := testCtrl.MarketPlace(s.marketID)
err := marketC.Chmod(new_permissions)
c.Assert(err, IsNil)
market, err := marketC.Info(false)
c.Assert(err, IsNil)
c.Assert(*market.Permissions, Equals, new_permissions);
}
func (s *MarketPlaceSuite) TestEnable(c *C) {
// Disable
marketC := testCtrl.MarketPlace(s.marketID)
err := marketC.Enable(false)
c.Assert(err, IsNil)
market, err := marketC.Info(false)
c.Assert(err, IsNil)
state, err := market.State()
c.Assert(err, IsNil)
c.Assert(state, Equals, marketplace.Disabled);
// Enable
err = marketC.Enable(true)
c.Assert(err, IsNil)
market, err = marketC.Info(false)
c.Assert(err, IsNil)
state, err = market.State()
c.Assert(err, IsNil)
c.Assert(state, Equals, marketplace.Enabled);
}

View File

@ -17,41 +17,48 @@
package goca
import (
"strconv"
"testing"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/image"
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"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
"github.com/OpenNebula/one/src/oca/go/src/goca/parameters"
. "gopkg.in/check.v1"
)
func TestMarketplaceApp(t *testing.T) {
var mkt_app_name string = "new_mkt_app"
var mkt_app *mktapp.MarketPlaceApp
var mkt_img_id int
var market_id int
var err error
type MarketPlaceAppSuite struct {
marketID int
imgID int
appID int
appName string
}
mkt_app_tmpl := mktapp.NewTemplate()
mkt_app_tmpl.Add(keys.Name, mkt_app_name)
mkt_app_tmpl.Add(keys.Size, "1")
mkt_app_tmpl.SetType(mktapp.Image)
var _ = Suite(&MarketPlaceAppSuite{})
//Create an image
func (s *MarketPlaceAppSuite) SetUpSuite(c *C) {
// Create a marketplace
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/local/market-http")
id, err := testCtrl.MarketPlaces().Create(mkt_tmpl.String())
c.Assert(err, IsNil)
s.marketID = id
// Create an image
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 {
t.Fatalf("Test failed:\n" + err.Error())
}
s.imgID, err = testCtrl.Images().Create(img_tmpl.String(), 1)
c.Assert(err, IsNil)
WaitResource(func() bool {
id, _ := testCtrl.Images().ByName("test_img_go")
@ -61,64 +68,159 @@ func TestMarketplaceApp(t *testing.T) {
return state == image.Ready
})
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
mkt_app_tmpl.Add(keys.OriginID, strconv.Itoa(int(mkt_img_id)))
//Create a marketplace
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 {
t.Errorf("Test failed:\n" + err.Error())
}
mkt_app_tmpl.Add(keys.MarketPlaceID, strconv.Itoa(int(market_id)))
//Create MarketplaceApp
app_id, err := testCtrl.MarketPlaceApps().Create(mkt_app_tmpl.String(), int(market_id))
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
mkt_app, err = testCtrl.MarketPlaceApp(app_id).Info(false)
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
actual := mkt_app.Name
if actual != mkt_app_name {
t.Errorf("Test failed, expected: '%s', got: '%s'", mkt_app_name, actual)
}
//Delete MarketplaceApp
err = testCtrl.MarketPlaceApp(app_id).Delete()
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
//delete image
err = testCtrl.Image(mkt_img_id).Delete()
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
//delete marketplace
err = testCtrl.MarketPlace(market_id).Delete()
if err != nil {
t.Errorf("Test failed:\n" + err.Error())
}
}
func (s *MarketPlaceAppSuite) TearDownSuite(c *C) {
// Delete image
err := testCtrl.Image(s.imgID).Delete()
c.Assert(err, IsNil)
// Delete marketplace
err = testCtrl.MarketPlace(s.marketID).Delete()
c.Assert(err, IsNil)
}
func (s *MarketPlaceAppSuite) SetUpTest(c *C) {
// Create Marketplace App
s.appName = "new_mkt_app"
mkt_app_tmpl := mktapp.NewTemplate()
mkt_app_tmpl.Add(keys.Name, s.appName)
mkt_app_tmpl.Add(keys.Size, "1")
mkt_app_tmpl.SetType(mktapp.Image)
mkt_app_tmpl.Add(keys.OriginID, s.imgID)
mkt_app_tmpl.Add(keys.MarketPlaceID, s.marketID)
app_id, err := testCtrl.MarketPlaceApps().Create(mkt_app_tmpl.String(), s.marketID)
c.Assert(err, IsNil)
s.appID = app_id
}
func (s *MarketPlaceAppSuite) TearDownTest(c *C) {
// Delete Marketplace App
appC := testCtrl.MarketPlaceApp(s.appID)
appC.Delete()
// Wait App deleted
WaitResource(func() bool {
_, err := appC.Info(false)
return err != nil
})
}
func (s *MarketPlaceAppSuite) TestGetByNameAndID(c *C) {
// Get MarketPlace App by ID
app, err := testCtrl.MarketPlaceApp(s.appID).Info(false)
c.Assert(err, IsNil)
c.Assert(app.ID, Equals, s.appID)
c.Assert(app.Name, Equals, s.appName)
state, err := app.State()
c.Assert(err, IsNil)
c.Assert(state, Equals, mktapp.Locked);
// Get MarketPlace App by Name
id, err := testCtrl.MarketPlaceApps().ByName(s.appName)
c.Assert(err, IsNil)
c.Assert(id, Equals, s.appID)
}
func (s *MarketPlaceAppSuite) TestUpdate(c *C) {
appC := testCtrl.MarketPlaceApp(s.appID)
err := appC.Update(`DESCRIPTION = "Testing"`, parameters.Merge)
c.Assert(err, IsNil)
app, err := testCtrl.MarketPlaceApp(s.appID).Info(false)
c.Assert(err, IsNil)
descr, err := app.Template.Get(keys.Description)
c.Assert(err, IsNil)
c.Assert(descr, Equals, "Testing")
}
func (s *MarketPlaceAppSuite) TestRename(c *C) {
appC := testCtrl.MarketPlaceApp(s.appID)
appC.Rename("new_name")
app, err := testCtrl.MarketPlaceApp(s.appID).Info(false)
c.Assert(err, IsNil)
c.Assert(app.Name, Equals, "new_name");
}
func (s *MarketPlaceAppSuite) TestChown(c *C) {
// Test only if the call exists, no real change
appC := testCtrl.MarketPlaceApp(s.appID)
err := appC.Chown(1, 1)
c.Assert(err, IsNil)
}
func (s *MarketPlaceAppSuite) TestChmod(c *C) {
new_permissions := shared.Permissions{1, 1, 1, 1, 1, 1, 1, 1, 1}
appC := testCtrl.MarketPlaceApp(s.appID)
err := appC.Chmod(new_permissions)
c.Assert(err, IsNil)
app, err := appC.Info(false)
c.Assert(err, IsNil)
c.Assert(*app.Permissions, Equals, new_permissions);
}
func (s *MarketPlaceAppSuite) TestLock(c *C) {
// Lock
appC := testCtrl.MarketPlaceApp(s.appID)
err := appC.Lock(shared.LockUse)
c.Assert(err, IsNil)
app, err := appC.Info(false)
c.Assert(err, IsNil)
c.Assert(app.LockInfos.Locked, Equals, 1);
// Unlock
err = appC.Unlock()
c.Assert(err, IsNil)
app, err = appC.Info(false)
c.Assert(err, IsNil)
c.Assert(app.LockInfos, IsNil)
}
func (s *MarketPlaceAppSuite) TestEnable(c *C) {
id, err := testCtrl.MarketPlaceApps().ByName("Custom via netboot.xyz")
c.Assert(err, IsNil)
// Disable
appC := testCtrl.MarketPlaceApp(id)
err = appC.Enable(false)
c.Assert(err, IsNil)
app, err := appC.Info(false)
c.Assert(err, IsNil)
state, err := app.State()
c.Assert(err, IsNil)
c.Assert(state, Equals, mktapp.Disabled);
// Enable
err = appC.Enable(true)
c.Assert(err, IsNil)
app, err = appC.Info(false)
c.Assert(err, IsNil)
state, err = app.State()
c.Assert(err, IsNil)
c.Assert(state, Equals, mktapp.Ready);
}

View File

@ -44,5 +44,6 @@ type MarketPlace struct {
UsedMB int `xml:"USED_MB,omitempty"`
MarketPlaceAppsIDs shared.EntitiesID `xml:"MARKETPLACEAPPS,omitempty"`
Permissions *shared.Permissions `xml:"PERMISSIONS,omitempty"`
StateRaw int `xml:"STATE,omitempty"`
Template Template `xml:"TEMPLATE"`
}

View File

@ -0,0 +1,61 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2023, 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 (
"fmt"
)
// State is the state of an OpenNebula marketplace
type State int
const (
Enabled State = iota
Disabled
)
func (s State) isValid() bool {
if s >= Enabled && s <= Disabled {
return true
}
return false
}
func (s State) String() string {
return [...]string{
"ENABLED",
"DISABLED",
}[s]
}
// State looks up the state of the marketplace
func (app *MarketPlace) State() (State, error) {
state := State(app.StateRaw)
if !state.isValid() {
return -1, fmt.Errorf("Marketplace State: this state value is not currently handled: %d\n", app.StateRaw)
}
return state, nil
}
// StateString returns the state in string format
func (app *MarketPlace) StateString() (string, error) {
state := State(app.StateRaw)
if !state.isValid() {
return "", fmt.Errorf("Marketplace StateString: this state value is not currently handled: %d\n", app.StateRaw)
}
return state.String(), nil
}

View File

@ -19,7 +19,6 @@ package marketplaceapp
import (
"encoding/xml"
dyn "github.com/OpenNebula/one/src/oca/go/src/goca/dynamic"
"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/shared"
)
@ -52,7 +51,7 @@ type MarketPlaceApp struct {
AppTemplate64 string `xml:"APPTEMPLATE64,omitempty"`
MarketPlaceID *int `xml:"MARKETPLACE_ID,omitempty"`
MarketPlace string `xml:"MARKETPLACE,omitempty"`
State int `xml:"STATE,omitempty"`
StateRaw int `xml:"STATE,omitempty"`
Type int `xml:"TYPE,omitempty"`
Template dyn.Template `xml:"TEMPLATE"`
Template Template `xml:"TEMPLATE"`
}

View File

@ -0,0 +1,67 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2023, 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 (
"fmt"
)
// State is the state of an OpenNebula marketplace
type State int
const (
Init State = iota
Ready
Locked
Error
Disabled
)
func (s State) isValid() bool {
if s >= Init && s <= Disabled {
return true
}
return false
}
func (s State) String() string {
return [...]string{
"INIT",
"READY",
"LOCKED",
"ERROR",
"DISABLED",
}[s]
}
// State looks up the state of the marketplace appliance
func (app *MarketPlaceApp) State() (State, error) {
state := State(app.StateRaw)
if !state.isValid() {
return -1, fmt.Errorf("Marketplace appliance State: this state value is not currently handled: %d\n", app.StateRaw)
}
return state, nil
}
// StateString returns the state in string format
func (app *MarketPlaceApp) StateString() (string, error) {
state := State(app.StateRaw)
if !state.isValid() {
return "", fmt.Errorf("Marketplace appliance StateString: this state value is not currently handled: %d\n", app.StateRaw)
}
return state.String(), nil
}