1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

F #6439: PCI (de)attach go and java api (#2919)

* PCI (de)attach go and java api
* Remove unused VirtualMachinePCI.h
* Use vm_authorization method to check Request authorization
* Fix typos
* L #-: C++ linting + onevm

(cherry picked from commit b1530690597a51402edcc13adc2aa2ecc3dbf04c)
This commit is contained in:
Pavel Czerný 2024-02-06 11:15:33 +01:00 committed by Ruben S. Montero
parent aa44b89c71
commit 05ad746446
No known key found for this signature in database
GPG Key ID: A0CEA6FA880A1D87
7 changed files with 114 additions and 301 deletions

View File

@ -1,246 +0,0 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#ifndef VIRTUAL_MACHINE_PCI_H_
#define VIRTUAL_MACHINE_PCI_H_
#include "VirtualMachineAttribute.h"
#include "PoolObjectSQL.h"
class AuthRequest;
/**
* The VirtualMachine PCI attribute
*/
class VirtualMachinePCI : public VirtualMachineAttribute
{
public:
VirtualMachinePCI(VectorAttribute *va, int id):
VirtualMachineAttribute(va, id){};
virtual ~VirtualMachinePCI(){};
/* ---------------------------------------------------------------------- */
/* PCI get/set functions for boolean disk flags */
/* ATTACH */
/* ---------------------------------------------------------------------- */
void set_attach()
{
set_flag("ATTACH");
};
/* ---------------------------------------------------------------------- */
/* PCI attributes */
/* ---------------------------------------------------------------------- */
/**
* Return the disk id ("PCI_ID")
*/
int get_pci_id() const
{
return get_id();
}
/**
* Check if a nic is alias or not
*/
bool is_alias() const
{
return name() == "NIC_ALIAS";
}
/**
* Check if a nic is a PCI
*/
bool is_nic() const
{
std::string type;
if (vector_value("TYPE", type) != 0)
{
return false;
}
one_util::toupper(type);
return type == "NIC";
}
};
/**
* Set of VirtualMachine NIC
*/
class VirtualMachinePCIs : public VirtualMachineAttributeSet
{
public:
/* ---------------------------------------------------------------------- */
/* Constructor and Initialization functions */
/* ---------------------------------------------------------------------- */
/**
* Creates the VirtualMachinePCI set from a Template with PCI=[...]
* attributes
* @param tmpl template with PCI
* @param has_id to use the ID's in PCI=[PCI_ID=...] or autogenerate
*/
VirtualMachinePCIs(Template * tmpl):
VirtualMachineAttributeSet(false)
{
std::vector<VectorAttribute *> pcis;
tmpl->get(PCI_NAME, pcis);
for (auto it = pcis.begin(); it != pcis.end(); )
{
if ( (*it)->vector_value("TYPE") != "NIC" )
{
it = pcis.erase(it);
}
else
{
++it;
}
}
init(pcis, false);
};
/**
* Creates the VirtualMachineNic set from a vector of NIC VectorAttribute
* @param va vector of NIC VectorAttribute
* @param has_id to use the ID's in NIC=[NIC_ID=...] or autogenerate
* @param dispose true to delete the VectorAttributes when the set is
* destroyed
*/
VirtualMachinePCIs(std::vector<VectorAttribute *>& va, bool has_id, bool dispose):
VirtualMachineAttributeSet(dispose)
{
init(va, has_id);
};
/**
* Creates an empty nic set
*/
VirtualMachinePCIs(bool dispose):
VirtualMachineAttributeSet(dispose){};
virtual ~VirtualMachinePCIs(){};
/**
* Function used to initialize the attribute map based on a vector of NIC
*/
void init(std::vector<VectorAttribute *>& vas, bool has_id)
{
if ( has_id )
{
init_attribute_map(PCI_ID_NAME, vas);
}
else
{
init_attribute_map("", vas);
}
}
/* ---------------------------------------------------------------------- */
/* Iterators */
/* ---------------------------------------------------------------------- */
/**
* Generic iterator for the nic set.
*/
class PCIIterator : public AttributeIterator
{
public:
PCIIterator():AttributeIterator(){};
PCIIterator(const AttributeIterator& dit):AttributeIterator(dit){};
virtual ~PCIIterator(){};
VirtualMachinePCI * operator*() const
{
return static_cast<VirtualMachinePCI *>(map_it->second);
}
};
PCIIterator begin()
{
PCIIterator it(ExtendedAttributeSet::begin());
return it;
}
PCIIterator end()
{
PCIIterator it(ExtendedAttributeSet::end());
return it;
}
typedef class PCIIterator pci_iterator;
/* ---------------------------------------------------------------------- */
/* NIC interface */
/* ---------------------------------------------------------------------- */
/**
* Returns the PCI attribute for a network interface
* @param pci_id of the PCI
* @return pointer to the attribute ir null if not found
*/
VirtualMachinePCI * get_pci(int pci_id) const
{
return static_cast<VirtualMachinePCI *>(get_attribute(pci_id));
}
/* ---------------------------------------------------------------------- */
/* Attach PCI interface */
/* ---------------------------------------------------------------------- */
/**
* Clear attach status from the attach PCI (ATTACH=YES) and removes PCI
* from the set
*/
VirtualMachinePCI * delete_attach()
{
return static_cast<VirtualMachinePCI *>(remove_attribute("ATTACH"));
}
/**
* Clear attach status from the attach PCI (ATTACH=YES)
*/
VirtualMachinePCI * clear_attach()
{
return static_cast<VirtualMachinePCI *>(clear_flag("ATTACH"));
}
/**
* Get the attach PCI (ATTACH=YES)
*/
VirtualMachinePCI * get_attach()
{
return static_cast<VirtualMachinePCI *>(get_attribute("ATTACH"));
}
protected:
VirtualMachineAttribute * attribute_factory(VectorAttribute * va,
int id) const
{
return new VirtualMachinePCI(va, id);
};
private:
static const char * PCI_NAME; //"PCI"
static const char * PCI_ID_NAME; //"PCI_ID"
};
#endif /*VIRTUAL_MACHINE_PCI_H_*/

View File

@ -2952,8 +2952,6 @@ int DispatchManager::resize(int vid, float cpu, int vcpu, long memory,
break;
}
auto vmm = Nebula::instance().get_vmm();
if (!vmm->is_live_resize(vm->get_vmm_mad()))
{
rc = -1;
@ -3019,8 +3017,6 @@ int DispatchManager::resize(int vid, float cpu, int vcpu, long memory,
int DispatchManager::attach_pci(int vid, VectorAttribute * pci,
const RequestAttributes& ra, string& error_str)
{
ostringstream oss;
auto vm = vmpool->get(vid);
if ( vm == nullptr )
@ -3097,8 +3093,6 @@ int DispatchManager::attach_pci(int vid, VectorAttribute * pci,
int DispatchManager::detach_pci(int vid, int pci_id, const RequestAttributes& ra,
string& error_str)
{
ostringstream oss;
auto vm = vmpool->get(vid);
if ( vm == nullptr )

View File

@ -1001,6 +1001,28 @@ func (vc *VMController) DetachSGContext(ctx context.Context, nicID int, sgID int
return err
}
// AttachPCI attaches new PCI to Virtual Machine
func (vc *VMController) AttachPCI(pciTemplate string) error {
return vc.AttachPCIContext(context.Background(), pciTemplate)
}
// AttachSGContext attaches new Security Group to Virtual Machine NIC
func (vc *VMController) AttachPCIContext(ctx context.Context, pciTemplate string) error {
_, err := vc.c.Client.CallContext(ctx, "one.vm.attachpci", vc.ID, pciTemplate)
return err
}
// DetachPCI detaches a PCI from Virtual Machine
func (vc *VMController) DetachPCI(pciID int) error {
return vc.DetachPCIContext(context.Background(), pciID)
}
// DetachPCIContext detaches a PCI from Virtual Machine
func (vc *VMController) DetachPCIContext(ctx context.Context, pciID int) error {
_, err := vc.c.Client.CallContext(ctx, "one.vm.detachpci", vc.ID, pciID)
return err
}
// Backup Virtual Machine
func (vc *VMController) Backup(dsID int, reset bool) error {
return vc.BackupContext(context.Background(), dsID, reset)

View File

@ -21,6 +21,7 @@ package goca
import (
"testing"
"strconv"
"regexp"
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"
@ -318,6 +319,43 @@ func (s *VMSuite) TestVMNicSgAttachDetach(c *C) {
c.Assert(WaitResource(VMExpectState(c, s.vmID, "ACTIVE", "RUNNING")), Equals, true)
}
func (s *VMSuite) TestVMPciAttachDetach(c *C) {
// Deploy VM
vmC := testCtrl.VM(s.vmID)
err := vmC.Deploy(s.hostID, false, -1)
c.Assert(err, IsNil)
c.Assert(WaitResource(VMExpectState(c, s.vmID, "ACTIVE", "RUNNING")), Equals, true)
err = vmC.Poweroff()
c.Assert(err, IsNil)
c.Assert(WaitResource(VMExpectState(c, s.vmID, "POWEROFF", "")), Equals, true)
// Attach PCI
err = vmC.AttachPCI("PCI = [ DEVICE = 0863 ]")
c.Assert(err, IsNil)
// Check PCI exists
vm, err := vmC.Info(false)
c.Assert(err, IsNil)
pci, err := vm.Template.GetVector("PCI")
c.Assert(err, IsNil)
matched, _ := regexp.MatchString("DEVICE=\"0863\"", pci.String())
c.Assert(matched, Equals, true)
// Detach PCI
err = vmC.DetachPCI(0)
c.Assert(err, IsNil)
// Check PCI doesn't exist
vm, err = vmC.Info(false)
c.Assert(err, IsNil)
_, err = vm.Template.GetVector("PCI")
c.Assert(err, NotNil)
}
func (s *VMSuite) TestVMBackup(c *C) {
// Deploy VM
vmC := testCtrl.VM(s.vmID)

View File

@ -62,6 +62,8 @@ public class VirtualMachine extends PoolElement{
private static final String UNLOCK = METHOD_PREFIX + "unlock";
private static final String ATTACHSG = METHOD_PREFIX + "attachsg";
private static final String DETACHSG = METHOD_PREFIX + "detachsg";
private static final String ATTACHPCI = METHOD_PREFIX + "attachpci";
private static final String DETACHPCI = METHOD_PREFIX + "detachpci";
private static final String BACKUP = METHOD_PREFIX + "backup";
private static final String BACKUPCANCEL = METHOD_PREFIX + "backupcancel";
@ -779,6 +781,33 @@ public class VirtualMachine extends PoolElement{
return client.call(DETACHSG, id, nicid, sgid);
}
/**
* Attaches a PCI to a VM
*
* @param client XML-RPC Client.
* @param id The Virtual Machine id (vid) of the target instance.
* @param pciTemplate The PCI Template to attach
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse pciAttach(Client client, int id,
String pciTemplate)
{
return client.call(ATTACHPCI, id, pciTemplate);
}
/**
* Detaches a PCI from a VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
* @param pciid The PCI id to detach
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse pciDetach(Client client, int id, int pciid)
{
return client.call(DETACHPCI, id, pciid);
}
/**
* Backup Virtual Machine
*
@ -1376,6 +1405,28 @@ public class VirtualMachine extends PoolElement{
return sgDetach(client, id, nicid, sgid);
}
/**
* Attaches a PCI to a VM
*
* @param pciTemplate The PCI template to attach
* @return If an error occurs the error message contains the reason.
*/
public OneResponse pciAttach(String pciTemplate)
{
return pciAttach(client, id, pciTemplate);
}
/**
* Detaches a PCI from a VM
*
* @param pciid The PCI id to detach
* @return If an error occurs the error message contains the reason.
*/
public OneResponse pciDetach(int pciid)
{
return pciDetach(client, id, pciid);
}
/**
* Backup VM
*

View File

@ -884,7 +884,7 @@ module OpenNebula
# Detaches a PCI from a VM
#
# @param nic_id [Integer] Id of the PCI to be detached
# @param pci_id [Integer] Id of the PCI to be detached
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def pci_detach(pci_id)

View File

@ -4124,32 +4124,8 @@ void VirtualMachineAttachPCI::request_execute(
// -------------------------------------------------------------------------
// Authorize the operation, restricted attributes
// -------------------------------------------------------------------------
PoolObjectAuth vm_perms;
if (auto vm = Nebula::instance().get_vmpool()->get_ro(id))
if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false)
{
vm->get_permissions(vm_perms);
}
else
{
att.resp_id = id;
att.resp_obj = PoolObjectSQL::VM;
failure_response(NO_EXISTS, att);
return;
}
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(att.auth_op, vm_perms);
VirtualMachine::set_auth_request(att.uid, ar, &tmpl, true);
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
@ -4193,30 +4169,8 @@ void VirtualMachineDetachPCI::request_execute(
// -------------------------------------------------------------------------
// Authorize the operation, restricted attributes
// -------------------------------------------------------------------------
PoolObjectAuth vm_perms;
if (auto vm = Nebula::instance().get_vmpool()->get_ro(id))
if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false)
{
vm->get_permissions(vm_perms);
}
else
{
att.resp_id = id;
att.resp_obj = PoolObjectSQL::VM;
failure_response(NO_EXISTS, att);
return;
}
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(att.auth_op, vm_perms);
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}