VMware Cloud Community
Vsure
Enthusiast
Enthusiast

How to modify an existing Reservation using VCACCAFEReservationReservationService

Greetings,

I am trying to apply a Reservation Policy to an existing reservation (I'm successfully creating the Reservation Policy using the VCACCAFERervationReservationPolicyService).  It doesn't seem to matter what changes I try to make to the Reservation object (reservationPolicyId, name, etc) I always get the same error when updating.

I can make the same changes to the existing reservation through the vRA UI without any errors and everything works fine deploying to the reservation so I'm thinking the problem must lie in the way I'm trying to modified it in code:

var reservationService = cafeHost.createReservationClient().getReservationReservationService();
var reservation = reservationService.getReservation(reservationId);
reservation.setReservationPolicyId(reservationPolicyId);
reservationService.updateReservation(reservation); <<<< ERROR The compute resource with ID 3e28cf22-ef25-4db5-b773-f176ed7da74e referenced by reservation is not valid
 
Any help is greatly appreciated!
6 Replies
Vsure
Enthusiast
Enthusiast

So I've discovered that my code for updating the reservation with the reservation policy works, but only when I run it from a workflow.  when I move the code to an Action that is executed by a blueprint form external source that's when I get the error.  Is it possible the form is putting some kind of lock on the reservation so it can't be modified while it's rendering?
Reply
0 Kudos
qc4vmware
Virtuoso
Virtuoso

Could be permissions related depending on how you have things configured.

Reply
0 Kudos
Vsure
Enthusiast
Enthusiast

Permissions do appear to be the issue.  I noticed that when the workflow is called by the Extneral Source bindings or Subscription event the "User Owner" becomes something like cafe-dwLe_0pNLg@vsphere.local.  To work around this issue I moved the code to another workflow and call it using workflow.execute(workflowid, user, pwd).   This resolved the issue.  If there is a way of specifying a specific user for vRA to call into vRO with let me know.
qc4vmware
Virtuoso
Virtuoso

Hmmm... What version of vRA are you on?  I've never hit any sort of security issue like you are running into.  Can you provide an example of the action you are trying to run?

Reply
0 Kudos
qc4vmware
Virtuoso
Virtuoso

Did you ever get this figured out?

Reply
0 Kudos
Vsure
Enthusiast
Enthusiast

I resolved it by moving the code to an external workflow and executing it with credentials of a service account that is a vRO admin (not sure of actual permission needed but this worked).

The code is used to ensure a 1:1 reservation policy is created and linked to each reservation of the same name.

Here is the code that is being called:

var tenant = System.getContext().getParameter("__asd_tenantRef");

var cafeHost = vCACCAFEHostManager.getDefaultHostForTenant(tenant , true);

var reservationPolicyService = cafeHost.createReservationClient().getReservationReservationPolicyService();

var reservationService = cafeHost.createReservationClient().getReservationReservationService();

var reservations = getReservationsMissingPolicies(reservationService);

if (reservations.length > 0){

     System.log("Reservations are missing Reservation Policies - " + reservations.length + " Total");

     for each (var reservation in reservations){

          var reservationName = reservation.name;

          var reservationId = reservation.id;

         

          System.log("Fixing '" + reservationName + "'");

         

          var reservationPolicyId = getReservationPolicyIdByName(reservationPolicyService, reservationName);

         

          if (!reservationPolicyId){

               System.log ("No Reservations Policies exist with the name '" + reservationName + "'");

               reservationPolicyId = createReservationPolicy(reservationPolicyService, reservationName);

               System.log ("Created Reservation Policy with name '" + reservationName + "'");

          }

         

          if (reservationPolicyId){

               //Link the Reservation Policy to the Reservation

               var reservationToUpdate = reservationService.getReservation(reservationId);

               reservationToUpdate.setReservationPolicyId(reservationPolicyId);

               reservationService.updateReservation(reservationToUpdate);

               System.log ("Successfully updated Reservation '" + reservationName + "'");

          }

     }

}else{

     System.log("No Reservations are missing Reservation Policies");

}

////////////////////////

// Helper Functions   //

////////////////////////

function createReservationPolicy(reservationPolicyService, reservationName){

     try{

          var rp = new vCACCAFEReservationPolicy();

          rp.reservationPolicyTypeId = "Infrastructure.Reservation.Policy.ComputeResource";

          rp.name = reservationName;

          rp.description = "Created automatically by vRO Workflow 'Update-ReservationsWithMissingPolicies'.";

          var rpid = reservationPolicyService.createReservationPolicy(rp);

          return rpid;

     }catch(e){

          return null;

     }

}

function getReservationsMissingPolicies(reservationService){

     //set up the filter you want to use for the query i.e. the reservation name 

     var conditions = new Array();

     conditions[0] = vCACCAFEFilterParam.isNull("reservationPolicyId");    

     conditions[1] =  vCACCAFEFilterParam.equal("enabled", true);

     var filter = new Array();

     filter[0] = vCACCAFEFilterParam.and(conditions);

      

     var query = vCACCAFEOdataQuery.query().addFilter(filter); 

      

     //set request parameters as 1 page with 10,000 results and use the filtered query built in the previous steps 

     var oDataRequest = new vCACCAFEPageOdataRequest(1, 10000, query); 

      

     //perform the request 

     var results = reservationService.getAllReservations(oDataRequest); 

      

     //retrieve the results 

     var reservations = results.getContent();

    

     return reservations;

}

function getReservationPolicyIdByName(reservationPolicyService, reservationName){

     var rpid = null;

      

     //set up the filter you want to use for the query i.e. the reservation name 

     var filter = new Array(); 

     filter[0] = vCACCAFEFilterParam.equal("name",vCACCAFEFilterParam.string(reservationName)); 

      

     var query = vCACCAFEOdataQuery.query().addFilter(filter); 

      

     //set request parameters as 1 page with 10,000 results and use the filtered query built in the previous steps 

     var oDataRequest = new vCACCAFEPageOdataRequest(1, 10000, query); 

      

     //perform the request 

     var results = reservationPolicyService.getAllReservationPolicies(oDataRequest); 

      

     //retrieve the results 

     var reservations = results.getContent(); 

     if(reservations.length == 1){ 

          var rpid = reservations[0].id; 

    

     else{ 

          System.log("More than one reservation found by the search"); 

     }

     return rpid;

}

Reply
0 Kudos