github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/defined_interface.go (about)

     1  /*
     2   * Copyright 2023 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     3   */
     4  
     5  package govcd
     6  
     7  import (
     8  	"fmt"
     9  	"net/url"
    10  	"strings"
    11  
    12  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    13  )
    14  
    15  const (
    16  	labelDefinedInterface         = "Defined Interface"
    17  	labelDefinedInterfaceBehavior = "Defined Interface Behavior"
    18  )
    19  
    20  // DefinedInterface is a type for handling Defined Interfaces, from the Runtime Defined Entities framework, in VCD.
    21  // This is often referred as Runtime Defined Entity Interface or RDE Interface in documentation.
    22  type DefinedInterface struct {
    23  	DefinedInterface *types.DefinedInterface
    24  	client           *Client
    25  }
    26  
    27  // wrap is a hidden helper that facilitates the usage of a generic CRUD function
    28  //
    29  //lint:ignore U1000 this method is used in generic functions, but annoys staticcheck
    30  func (d DefinedInterface) wrap(inner *types.DefinedInterface) *DefinedInterface {
    31  	d.DefinedInterface = inner
    32  	return &d
    33  }
    34  
    35  // CreateDefinedInterface creates a Defined Interface.
    36  // Only System administrator can create Defined Interfaces.
    37  func (vcdClient *VCDClient) CreateDefinedInterface(definedInterface *types.DefinedInterface) (*DefinedInterface, error) {
    38  	c := crudConfig{
    39  		endpoint:    types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaces,
    40  		entityLabel: labelDefinedInterface,
    41  	}
    42  	outerType := DefinedInterface{client: &vcdClient.Client}
    43  	return createOuterEntity(&vcdClient.Client, outerType, c, definedInterface)
    44  }
    45  
    46  // GetAllDefinedInterfaces retrieves all Defined Interfaces. Query parameters can be supplied to perform additional filtering.
    47  func (vcdClient *VCDClient) GetAllDefinedInterfaces(queryParameters url.Values) ([]*DefinedInterface, error) {
    48  	c := crudConfig{
    49  		endpoint:        types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaces,
    50  		entityLabel:     labelDefinedInterface,
    51  		queryParameters: queryParameters,
    52  	}
    53  
    54  	outerType := DefinedInterface{client: &vcdClient.Client}
    55  	return getAllOuterEntities(&vcdClient.Client, outerType, c)
    56  }
    57  
    58  // GetDefinedInterface retrieves a single Defined Interface defined by its unique combination of vendor, nss and version.
    59  func (vcdClient *VCDClient) GetDefinedInterface(vendor, nss, version string) (*DefinedInterface, error) {
    60  	queryParameters := url.Values{}
    61  	queryParameters.Add("filter", fmt.Sprintf("vendor==%s;nss==%s;version==%s", vendor, nss, version))
    62  	interfaces, err := vcdClient.GetAllDefinedInterfaces(queryParameters)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	if len(interfaces) == 0 {
    68  		return nil, fmt.Errorf("%s could not find the Defined Interface with vendor %s, nss %s and version %s", ErrorEntityNotFound, vendor, nss, version)
    69  	}
    70  
    71  	if len(interfaces) > 1 {
    72  		return nil, fmt.Errorf("found more than 1 Defined Interface with vendor %s, nss %s and version %s", vendor, nss, version)
    73  	}
    74  
    75  	return interfaces[0], nil
    76  }
    77  
    78  // GetDefinedInterfaceById gets a Defined Interface identified by its unique URN.
    79  func (vcdClient *VCDClient) GetDefinedInterfaceById(id string) (*DefinedInterface, error) {
    80  	c := crudConfig{
    81  		entityLabel:    labelDefinedInterface,
    82  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaces,
    83  		endpointParams: []string{id},
    84  	}
    85  
    86  	outerType := DefinedInterface{client: &vcdClient.Client}
    87  	return getOuterEntity(&vcdClient.Client, outerType, c)
    88  }
    89  
    90  // Update updates the receiver Defined Interface with the values given by the input.
    91  // Only System administrator can update Defined Interfaces.
    92  func (di *DefinedInterface) Update(definedInterface types.DefinedInterface) error {
    93  	if di.DefinedInterface.ID == "" {
    94  		return fmt.Errorf("ID of the receiver Defined Interface is empty")
    95  	}
    96  
    97  	if definedInterface.ID != "" && definedInterface.ID != di.DefinedInterface.ID {
    98  		return fmt.Errorf("ID of the receiver Defined Interface and the input ID don't match")
    99  	}
   100  
   101  	// We override these as they need to be always sent on updates
   102  	definedInterface.Version = di.DefinedInterface.Version
   103  	definedInterface.Nss = di.DefinedInterface.Nss
   104  	definedInterface.Vendor = di.DefinedInterface.Vendor
   105  
   106  	c := crudConfig{
   107  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaces,
   108  		endpointParams: []string{di.DefinedInterface.ID},
   109  		entityLabel:    labelDefinedInterface,
   110  	}
   111  	resultDefinedInterface, err := updateInnerEntity(di.client, c, &definedInterface)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	// Only if there was no error in request we overwrite pointer receiver as otherwise it would
   116  	// wipe out existing data
   117  	di.DefinedInterface = resultDefinedInterface
   118  	return err
   119  }
   120  
   121  // Delete deletes the receiver Defined Interface.
   122  // Only System administrator can delete Defined Interfaces.
   123  func (di *DefinedInterface) Delete() error {
   124  	if di.DefinedInterface.ID == "" {
   125  		return fmt.Errorf("ID of the receiver Defined Interface is empty")
   126  	}
   127  
   128  	c := crudConfig{
   129  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaces,
   130  		endpointParams: []string{di.DefinedInterface.ID},
   131  		entityLabel:    labelDefinedInterface,
   132  	}
   133  
   134  	err := deleteEntityById(di.client, c)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	di.DefinedInterface = &types.DefinedInterface{}
   140  	return nil
   141  }
   142  
   143  // AddBehavior adds a new Behavior to the receiver DefinedInterface.
   144  // Only allowed if the Interface is not in use.
   145  func (di *DefinedInterface) AddBehavior(behavior types.Behavior) (*types.Behavior, error) {
   146  	if di.DefinedInterface.ID == "" {
   147  		return nil, fmt.Errorf("ID of the receiver Defined Interface is empty")
   148  	}
   149  
   150  	c := crudConfig{
   151  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaceBehaviors,
   152  		endpointParams: []string{di.DefinedInterface.ID},
   153  		entityLabel:    labelDefinedInterfaceBehavior,
   154  	}
   155  	return createInnerEntity(di.client, c, &behavior)
   156  }
   157  
   158  // GetAllBehaviors retrieves all the Behaviors of the receiver Defined Interface.
   159  func (di *DefinedInterface) GetAllBehaviors(queryParameters url.Values) ([]*types.Behavior, error) {
   160  	if di.DefinedInterface.ID == "" {
   161  		return nil, fmt.Errorf("ID of the receiver Defined Interface is empty")
   162  	}
   163  	return getAllBehaviors(di.client, di.DefinedInterface.ID, types.OpenApiEndpointRdeInterfaceBehaviors, queryParameters)
   164  }
   165  
   166  // getAllBehaviors gets all the Behaviors from the object referenced by the input Object ID with the given OpenAPI endpoint.
   167  func getAllBehaviors(client *Client, objectId, openApiEndpoint string, queryParameters url.Values) ([]*types.Behavior, error) {
   168  	c := crudConfig{
   169  		endpoint:        types.OpenApiPathVersion1_0_0 + openApiEndpoint,
   170  		entityLabel:     labelDefinedInterfaceBehavior,
   171  		endpointParams:  []string{objectId},
   172  		queryParameters: queryParameters,
   173  	}
   174  	return getAllInnerEntities[types.Behavior](client, c)
   175  }
   176  
   177  // GetBehaviorById retrieves a unique Behavior that belongs to the receiver Defined Interface and is determined by the
   178  // input ID.
   179  func (di *DefinedInterface) GetBehaviorById(id string) (*types.Behavior, error) {
   180  	c := crudConfig{
   181  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaceBehaviors,
   182  		endpointParams: []string{di.DefinedInterface.ID, id},
   183  		entityLabel:    labelDefinedInterfaceBehavior,
   184  	}
   185  	return getInnerEntity[types.Behavior](di.client, c)
   186  }
   187  
   188  // GetBehaviorByName retrieves a unique Behavior that belongs to the receiver Defined Interface and is named after
   189  // the input.
   190  func (di *DefinedInterface) GetBehaviorByName(name string) (*types.Behavior, error) {
   191  	behaviors, err := di.GetAllBehaviors(nil)
   192  	if err != nil {
   193  		return nil, fmt.Errorf("could not get the Behaviors of the Defined Interface with ID '%s': %s", di.DefinedInterface.ID, err)
   194  	}
   195  	label := fmt.Sprintf("Defined Interface Behavior with name '%s' in Defined Interface with ID '%s': %s", name, di.DefinedInterface.ID, ErrorEntityNotFound)
   196  	return localFilterOneOrError(label, behaviors, "Name", name)
   197  }
   198  
   199  // UpdateBehavior updates a Behavior specified by the input.
   200  func (di *DefinedInterface) UpdateBehavior(behavior types.Behavior) (*types.Behavior, error) {
   201  	if di.DefinedInterface.ID == "" {
   202  		return nil, fmt.Errorf("ID of the receiver Defined Interface is empty")
   203  	}
   204  	if behavior.ID == "" {
   205  		return nil, fmt.Errorf("ID of the Behavior to update is empty")
   206  	}
   207  
   208  	c := crudConfig{
   209  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaceBehaviors,
   210  		endpointParams: []string{di.DefinedInterface.ID, behavior.ID},
   211  		entityLabel:    labelDefinedInterfaceBehavior,
   212  	}
   213  	return updateInnerEntity(di.client, c, &behavior)
   214  }
   215  
   216  // DeleteBehavior removes a Behavior specified by its ID from the receiver Defined Interface.
   217  func (di *DefinedInterface) DeleteBehavior(behaviorId string) error {
   218  	if di.DefinedInterface.ID == "" {
   219  		return fmt.Errorf("ID of the receiver Defined Interface is empty")
   220  	}
   221  
   222  	c := crudConfig{
   223  		endpoint:       types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaceBehaviors,
   224  		endpointParams: []string{di.DefinedInterface.ID, behaviorId},
   225  		entityLabel:    labelDefinedInterfaceBehavior,
   226  	}
   227  	return deleteEntityById(di.client, c)
   228  }
   229  
   230  // amendRdeApiError fixes a wrong type of error returned by VCD API <= v36.0 on GET operations
   231  // when the defined interface does not exist.
   232  func amendRdeApiError(client *Client, err error) error {
   233  	if client.APIClientVersionIs("<= 36.0") && err != nil && strings.Contains(err.Error(), "does not exist") {
   234  		return fmt.Errorf("%s: %s", ErrorEntityNotFound.Error(), err)
   235  	}
   236  	return err
   237  }