Skip to content

Commit

Permalink
Add more RDE Type behavior methods
Browse files Browse the repository at this point in the history
Signed-off-by: abarreiro <abarreiro@vmware.com>
  • Loading branch information
abarreiro committed Jun 30, 2023
1 parent 1b33343 commit b80109a
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 20 deletions.
60 changes: 57 additions & 3 deletions govcd/defined_entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func (rdeType *DefinedEntityType) GetAllBehaviors(queryParameters url.Values) ([
}

// GetBehaviorById retrieves a unique Behavior that belongs to the receiver RDE Type and is determined by the
// input ID.
// input ID. The ID can be a RDE Interface Behavior ID or a RDE Type overridden Behavior ID.
func (rdeType *DefinedEntityType) GetBehaviorById(id string) (*types.Behavior, error) {
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeTypeBehaviors
apiVersion, err := rdeType.client.getOpenApiHighestElevatedVersion(endpoint)
Expand All @@ -240,14 +240,68 @@ func (rdeType *DefinedEntityType) GetBehaviorById(id string) (*types.Behavior, e
func (rdeType *DefinedEntityType) GetBehaviorByName(name string) (*types.Behavior, error) {
behaviors, err := rdeType.GetAllBehaviors(nil)
if err != nil {
return nil, fmt.Errorf("could not get the Behaviors of the RDE Type with ID '%s': %s", rdeType.DefinedEntityType.ID, err)
return nil, fmt.Errorf("could not get the Behaviors of the Defined Entity Type with ID '%s': %s", rdeType.DefinedEntityType.ID, err)
}
for _, b := range behaviors {
if b.Name == name {
return b, nil
}
}
return nil, fmt.Errorf("could not find any Behavior with name '%s' in RDE Type with ID '%s': %s", name, rdeType.DefinedEntityType.ID, ErrorEntityNotFound)
return nil, fmt.Errorf("could not find any Behavior with name '%s' in Defined Entity Type with ID '%s': %s", name, rdeType.DefinedEntityType.ID, ErrorEntityNotFound)
}

// OverrideBehavior given a valid input Behavior with a valid ID, overrides it.
// Only Behavior description and execution can be overridden.
// It returns the new Behavior, result of the override (with a new ID).
func (rdeType *DefinedEntityType) OverrideBehavior(behavior types.Behavior) (*types.Behavior, error) {
if rdeType.DefinedEntityType.ID == "" {
return nil, fmt.Errorf("ID of the receiver Defined Entity Type is empty")
}
if behavior.ID == "" {
return nil, fmt.Errorf("ID of the Behavior to override is empty")
}

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeTypeBehaviors
apiVersion, err := rdeType.client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}

urlRef, err := rdeType.client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, rdeType.DefinedEntityType.ID), behavior.ID)
if err != nil {
return nil, err
}
response := types.Behavior{}
err = rdeType.client.OpenApiPutItem(apiVersion, urlRef, nil, behavior, &response, nil)
if err != nil {
return nil, err
}

return &response, nil
}

// DeleteBehaviorOverride removes a Behavior specified by its ID from the receiver Defined Entity Type.
func (rdeType *DefinedEntityType) DeleteBehaviorOverride(behaviorId string) error {
if rdeType.DefinedEntityType.ID == "" {
return fmt.Errorf("ID of the receiver Defined Entity Type is empty")
}

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeTypeBehaviors
apiVersion, err := rdeType.client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return err
}

urlRef, err := rdeType.client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, rdeType.DefinedEntityType.ID), behaviorId)
if err != nil {
return err
}
err = rdeType.client.OpenApiDeleteItem(apiVersion, urlRef, nil, nil)
if err != nil {
return err
}

return nil
}

// AddBehaviorAccessControl adds a new Behavior to the receiver DefinedInterface.
Expand Down
77 changes: 60 additions & 17 deletions govcd/defined_entity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,14 @@ func (vcd *TestVCD) Test_RdeTypeBehavior(check *C) {

// Get all the behaviors of the RDE Type. As it referenced the K8s Interface, it inherits its Behaviors, so it
// has one Behavior without anyone creating it.
allBehaviors, err := rdeType.GetAllBehaviors(nil)
originalBehaviors, err := rdeType.GetAllBehaviors(nil)
check.Assert(err, IsNil)
check.Assert(len(allBehaviors), Equals, 1)
check.Assert(allBehaviors[0].Name, Equals, "createKubeConfig")
check.Assert(len(allBehaviors[0].Execution), Equals, 2)
check.Assert(allBehaviors[0].Execution["id"], Equals, "CreateKubeConfigActivity")
check.Assert(allBehaviors[0].Execution["type"], Equals, "Activity")
check.Assert(len(originalBehaviors), Equals, 1)
check.Assert(originalBehaviors[0].Name, Equals, "createKubeConfig")
check.Assert(originalBehaviors[0].Description, Equals, "Creates and returns a kubeconfig")
check.Assert(len(originalBehaviors[0].Execution), Equals, 2)
check.Assert(originalBehaviors[0].Execution["id"], Equals, "CreateKubeConfigActivity")
check.Assert(originalBehaviors[0].Execution["type"], Equals, "Activity")

// Error getting non-existing Behaviors
_, err = rdeType.GetBehaviorById("urn:vcloud:behavior-type:notexist:notexist:notexist:9.9.9")
Expand All @@ -403,24 +404,66 @@ func (vcd *TestVCD) Test_RdeTypeBehavior(check *C) {
check.Assert(strings.Contains(err.Error(), ErrorEntityNotFound.Error()), Equals, true)

// Getting behaviors correctly
retrievedBehavior, err := rdeType.GetBehaviorById(allBehaviors[0].ID)
originalBehavior, err := rdeType.GetBehaviorById(originalBehaviors[0].ID)
check.Assert(err, IsNil)
check.Assert(originalBehavior, NotNil)
check.Assert(originalBehavior.Name, Equals, originalBehaviors[0].Name)
check.Assert(originalBehavior.Description, Equals, originalBehaviors[0].Description)
check.Assert(originalBehavior.Execution, DeepEquals, originalBehaviors[0].Execution)

behavior2, err := rdeType.GetBehaviorByName(originalBehaviors[0].Name)
check.Assert(err, IsNil)
check.Assert(originalBehavior, NotNil)
check.Assert(originalBehavior, DeepEquals, behavior2)

// Override the behavior
rdeTypeBehavior, err := rdeType.OverrideBehavior(types.Behavior{
ID: originalBehavior.ID,
Description: originalBehavior.Description + "Overridden",
Execution: map[string]interface{}{
"id": originalBehavior.Execution["id"].(string) + "Overridden",
"type": "Activity",
},
Name: "WillNotBeOverridden",
})
check.Assert(err, IsNil)
check.Assert(retrievedBehavior, NotNil)
check.Assert(retrievedBehavior.Name, Equals, allBehaviors[0].Name)
check.Assert(retrievedBehavior.Description, Equals, allBehaviors[0].Description)
check.Assert(retrievedBehavior.Execution, DeepEquals, allBehaviors[0].Execution)
check.Assert(rdeTypeBehavior.ID, Not(Equals), originalBehavior.ID) // Now that it is overridden, ID changes to behavior-type
check.Assert(rdeTypeBehavior.Ref, Equals, originalBehavior.ID)
check.Assert(rdeTypeBehavior.Description, Equals, originalBehavior.Description+"Overridden")
check.Assert(rdeTypeBehavior.Execution["id"], Equals, originalBehavior.Execution["id"].(string)+"Overridden")
check.Assert(rdeTypeBehavior.Execution["type"], Equals, originalBehavior.Execution["type"])
check.Assert(rdeTypeBehavior.Name, Equals, originalBehavior.Name) // Name can't be overridden

retrievedBehavior2, err := rdeType.GetBehaviorByName(allBehaviors[0].Name)
// Check that it can be retrieved with new Behavior ID (generated by the override) and old one
retrOverridden, err := rdeType.GetBehaviorById(rdeTypeBehavior.ID)
check.Assert(err, IsNil)
check.Assert(retrievedBehavior, NotNil)
check.Assert(retrievedBehavior, DeepEquals, retrievedBehavior2)
check.Assert(retrOverridden, DeepEquals, rdeTypeBehavior)

allAccCtrl, err := rdeType.GetAllBehaviorsAccessControls(nil)
retrOverridden, err = rdeType.GetBehaviorById(rdeTypeBehavior.Ref) // Ref is the Interface Behavior ID
check.Assert(err, IsNil)
check.Assert(len(allAccCtrl), Equals, 0)
check.Assert(retrOverridden, DeepEquals, rdeTypeBehavior)

// TODO: Test rdeType.AddBehaviorAccessControl()
testRdeTypeAccessControls(check, rdeType)

// Delete the Behavior with original RDE Interface Behavior ID. It doesn't care if we use the original or the overridden.
err = rdeType.DeleteBehaviorOverride(originalBehavior.ID)
check.Assert(err, IsNil)

// Check that the deletion was done correctly
originalBehaviors, err = rdeType.GetAllBehaviors(nil)
check.Assert(err, IsNil)
check.Assert(len(originalBehaviors), Equals, 1) // We still have 1: The original RDE Interface Behavior
check.Assert(originalBehaviors[0].ID, Not(Equals), retrOverridden.ID) // The ID should not be the overridden one as we deleted it
check.Assert(originalBehaviors[0].ID, Equals, originalBehavior.ID) // The ID should not be the overridden one as we deleted it

err = rdeType.Delete()
check.Assert(err, IsNil)
}

func testRdeTypeAccessControls(check *C, rdeType *DefinedEntityType) {
allAccCtrl, err := rdeType.GetAllBehaviorsAccessControls(nil)
check.Assert(err, IsNil)
check.Assert(len(allAccCtrl), Equals, 0)

// TODO: Test rdeType.AddBehaviorAccessControl()
}

0 comments on commit b80109a

Please sign in to comment.