github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/actor/v2action/service_instance_summary.go (about)

     1  package v2action
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     5  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
     6  )
     7  
     8  type ServiceInstanceShareType string
     9  
    10  const (
    11  	ServiceInstanceIsSharedFrom ServiceInstanceShareType = "SharedFrom"
    12  	ServiceInstanceIsSharedTo   ServiceInstanceShareType = "SharedTo"
    13  	ServiceInstanceIsNotShared  ServiceInstanceShareType = "NotShared"
    14  )
    15  
    16  type ServiceInstanceSummary struct {
    17  	ServiceInstance
    18  
    19  	ServicePlan                       ServicePlan
    20  	Service                           Service
    21  	ServiceInstanceSharingFeatureFlag bool
    22  	ServiceInstanceShareType          ServiceInstanceShareType
    23  	ServiceInstanceSharedFrom         ServiceInstanceSharedFrom
    24  	ServiceInstanceSharedTos          []ServiceInstanceSharedTo
    25  	BoundApplications                 []string
    26  }
    27  
    28  func (s ServiceInstanceSummary) IsShareable() bool {
    29  	return s.ServiceInstanceSharingFeatureFlag && s.Service.Extra.Shareable
    30  }
    31  
    32  func (s ServiceInstanceSummary) IsNotShared() bool {
    33  	return s.ServiceInstanceShareType == ServiceInstanceIsNotShared
    34  }
    35  
    36  func (s ServiceInstanceSummary) IsSharedFrom() bool {
    37  	return s.ServiceInstanceShareType == ServiceInstanceIsSharedFrom
    38  }
    39  
    40  func (s ServiceInstanceSummary) IsSharedTo() bool {
    41  	return s.ServiceInstanceShareType == ServiceInstanceIsSharedTo
    42  }
    43  
    44  func (actor Actor) GetServiceInstanceSummaryByNameAndSpace(name string, spaceGUID string) (ServiceInstanceSummary, Warnings, error) {
    45  	serviceInstanceSummary := ServiceInstanceSummary{}
    46  
    47  	serviceInstance, instanceWarnings, instanceErr := actor.GetServiceInstanceByNameAndSpace(name, spaceGUID)
    48  	allWarnings := Warnings(instanceWarnings)
    49  	if instanceErr != nil {
    50  		return serviceInstanceSummary, allWarnings, instanceErr
    51  	}
    52  	serviceInstanceSummary.ServiceInstance = serviceInstance
    53  
    54  	var (
    55  		serviceBindings  []ServiceBinding
    56  		bindingsWarnings Warnings
    57  		bindingsErr      error
    58  	)
    59  
    60  	if serviceInstance.IsManaged() {
    61  		sharedWarnings, sharedErr := actor.getAndSetSharedInformation(&serviceInstanceSummary, spaceGUID)
    62  		allWarnings = append(allWarnings, sharedWarnings...)
    63  		if sharedErr != nil {
    64  			return serviceInstanceSummary, allWarnings, sharedErr
    65  		}
    66  
    67  		servicePlan, planWarnings, planErr := actor.GetServicePlan(serviceInstance.ServicePlanGUID)
    68  		allWarnings = append(allWarnings, planWarnings...)
    69  		if planErr != nil {
    70  			return serviceInstanceSummary, allWarnings, planErr
    71  		}
    72  		serviceInstanceSummary.ServicePlan = servicePlan
    73  
    74  		service, serviceWarnings, serviceErr := actor.GetService(servicePlan.ServiceGUID)
    75  		allWarnings = append(allWarnings, serviceWarnings...)
    76  		if serviceErr != nil {
    77  			return serviceInstanceSummary, allWarnings, serviceErr
    78  		}
    79  		serviceInstanceSummary.Service = service
    80  
    81  		serviceBindings, bindingsWarnings, bindingsErr = actor.GetServiceBindingsByServiceInstance(serviceInstance.GUID)
    82  	} else {
    83  		serviceBindings, bindingsWarnings, bindingsErr = actor.GetServiceBindingsByUserProvidedServiceInstance(serviceInstance.GUID)
    84  	}
    85  
    86  	allWarnings = append(allWarnings, bindingsWarnings...)
    87  	if bindingsErr != nil {
    88  		return serviceInstanceSummary, allWarnings, bindingsErr
    89  	}
    90  
    91  	for _, serviceBinding := range serviceBindings {
    92  		app, appWarnings, appErr := actor.GetApplication(serviceBinding.AppGUID)
    93  		allWarnings = append(allWarnings, appWarnings...)
    94  		if appErr != nil {
    95  			return serviceInstanceSummary, allWarnings, appErr
    96  		}
    97  		serviceInstanceSummary.BoundApplications = append(serviceInstanceSummary.BoundApplications, app.Name)
    98  	}
    99  
   100  	return serviceInstanceSummary, allWarnings, nil
   101  }
   102  
   103  // getAndSetSharedInformation gets a service instance's shared from or shared to information,
   104  func (actor Actor) getAndSetSharedInformation(summary *ServiceInstanceSummary, spaceGUID string) (Warnings, error) {
   105  	var (
   106  		warnings Warnings
   107  		err      error
   108  	)
   109  
   110  	// Part of determining if a service instance is shareable, we need to find
   111  	// out if the service_instance_sharing feature flag is enabled
   112  	featureFlags, featureFlagsWarnings, featureFlagsErr := actor.CloudControllerClient.GetConfigFeatureFlags()
   113  	allWarnings := Warnings(featureFlagsWarnings)
   114  	if featureFlagsErr != nil {
   115  		return allWarnings, featureFlagsErr
   116  	}
   117  
   118  	for _, flag := range featureFlags {
   119  		if flag.Name == string(ccv2.FeatureFlagServiceInstanceSharing) {
   120  			summary.ServiceInstanceSharingFeatureFlag = flag.Enabled
   121  		}
   122  	}
   123  
   124  	// Service instance is shared from if:
   125  	// 1. the source space of the service instance is empty (API returns json null)
   126  	// 2. the targeted space is not the same as the source space of the service instance AND
   127  	//    we call the shared_from url and it returns a non-empty resource
   128  	if summary.ServiceInstance.SpaceGUID == "" || summary.ServiceInstance.SpaceGUID != spaceGUID {
   129  		summary.ServiceInstanceSharedFrom, warnings, err = actor.GetServiceInstanceSharedFromByServiceInstance(summary.ServiceInstance.GUID)
   130  		allWarnings = append(allWarnings, warnings...)
   131  		if err != nil {
   132  			// if the API version does not support service instance sharing, ignore the 404
   133  			if _, ok := err.(ccerror.ResourceNotFoundError); !ok {
   134  				return allWarnings, err
   135  			}
   136  		}
   137  
   138  		if summary.ServiceInstanceSharedFrom.SpaceGUID != "" {
   139  			summary.ServiceInstanceShareType = ServiceInstanceIsSharedFrom
   140  		} else {
   141  			summary.ServiceInstanceShareType = ServiceInstanceIsNotShared
   142  		}
   143  
   144  		return allWarnings, nil
   145  	}
   146  
   147  	// Service instance is shared to if:
   148  	// the targeted space is the same as the source space of the service instance AND
   149  	// we call the shared_to url and get a non-empty list
   150  	summary.ServiceInstanceSharedTos, warnings, err = actor.GetServiceInstanceSharedTosByServiceInstance(summary.ServiceInstance.GUID)
   151  	allWarnings = append(allWarnings, warnings...)
   152  	if err != nil {
   153  		// if the API version does not support service instance sharing, ignore the 404
   154  		if _, ok := err.(ccerror.ResourceNotFoundError); !ok {
   155  			return allWarnings, err
   156  		}
   157  	}
   158  
   159  	if len(summary.ServiceInstanceSharedTos) > 0 {
   160  		summary.ServiceInstanceShareType = ServiceInstanceIsSharedTo
   161  	} else {
   162  		summary.ServiceInstanceShareType = ServiceInstanceIsNotShared
   163  	}
   164  
   165  	return allWarnings, nil
   166  }