github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/cf/api/domains.go (about)

     1  package api
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/url"
     8  
     9  	. "code.cloudfoundry.org/cli/cf/i18n"
    10  
    11  	"code.cloudfoundry.org/cli/cf/api/resources"
    12  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    13  	"code.cloudfoundry.org/cli/cf/errors"
    14  	"code.cloudfoundry.org/cli/cf/models"
    15  	"code.cloudfoundry.org/cli/cf/net"
    16  )
    17  
    18  //go:generate counterfeiter . DomainRepository
    19  
    20  type DomainRepository interface {
    21  	ListDomainsForOrg(orgGUID string, cb func(models.DomainFields) bool) error
    22  	FindSharedByName(name string) (domain models.DomainFields, apiErr error)
    23  	FindPrivateByName(name string) (domain models.DomainFields, apiErr error)
    24  	FindByNameInOrg(name string, owningOrgGUID string) (domain models.DomainFields, apiErr error)
    25  	Create(domainName string, owningOrgGUID string) (createdDomain models.DomainFields, apiErr error)
    26  	CreateSharedDomain(domainName string, routerGroupGUID string) (apiErr error)
    27  	Delete(domainGUID string) (apiErr error)
    28  	DeleteSharedDomain(domainGUID string) (apiErr error)
    29  	FirstOrDefault(orgGUID string, name *string) (domain models.DomainFields, error error)
    30  }
    31  
    32  type CloudControllerDomainRepository struct {
    33  	config  coreconfig.Reader
    34  	gateway net.Gateway
    35  }
    36  
    37  func NewCloudControllerDomainRepository(config coreconfig.Reader, gateway net.Gateway) CloudControllerDomainRepository {
    38  	return CloudControllerDomainRepository{
    39  		config:  config,
    40  		gateway: gateway,
    41  	}
    42  }
    43  
    44  func (repo CloudControllerDomainRepository) ListDomainsForOrg(orgGUID string, cb func(models.DomainFields) bool) error {
    45  	path := fmt.Sprintf("/v2/organizations/%s/private_domains", orgGUID)
    46  	err := repo.listDomains(path, cb)
    47  	if err != nil {
    48  		return err
    49  	}
    50  	err = repo.listDomains("/v2/shared_domains?inline-relations-depth=1", cb)
    51  	return err
    52  }
    53  
    54  func (repo CloudControllerDomainRepository) listDomains(path string, cb func(models.DomainFields) bool) error {
    55  	return repo.gateway.ListPaginatedResources(
    56  		repo.config.APIEndpoint(),
    57  		path,
    58  		resources.DomainResource{},
    59  		func(resource interface{}) bool {
    60  			return cb(resource.(resources.DomainResource).ToFields())
    61  		})
    62  }
    63  
    64  func (repo CloudControllerDomainRepository) isOrgDomain(orgGUID string, domain models.DomainFields) bool {
    65  	return orgGUID == domain.OwningOrganizationGUID || domain.Shared
    66  }
    67  
    68  func (repo CloudControllerDomainRepository) FindSharedByName(name string) (domain models.DomainFields, apiErr error) {
    69  	path := fmt.Sprintf("/v2/shared_domains?inline-relations-depth=1&q=name:%s", url.QueryEscape(name))
    70  	return repo.findOneWithPath(path, name)
    71  }
    72  
    73  func (repo CloudControllerDomainRepository) FindPrivateByName(name string) (domain models.DomainFields, apiErr error) {
    74  	path := fmt.Sprintf("/v2/private_domains?inline-relations-depth=1&q=name:%s", url.QueryEscape(name))
    75  	return repo.findOneWithPath(path, name)
    76  }
    77  
    78  func (repo CloudControllerDomainRepository) FindByNameInOrg(name string, orgGUID string) (models.DomainFields, error) {
    79  	path := fmt.Sprintf("/v2/organizations/%s/private_domains?inline-relations-depth=1&q=name:%s", orgGUID, url.QueryEscape(name))
    80  	domain, err := repo.findOneWithPath(path, name)
    81  
    82  	switch err.(type) {
    83  	case *errors.ModelNotFoundError:
    84  		domain, err = repo.FindSharedByName(name)
    85  		if err != nil {
    86  			return models.DomainFields{}, err
    87  		}
    88  		if !domain.Shared {
    89  			err = errors.NewModelNotFoundError("Domain", name)
    90  		}
    91  	}
    92  
    93  	return domain, err
    94  }
    95  
    96  func (repo CloudControllerDomainRepository) findOneWithPath(path, name string) (models.DomainFields, error) {
    97  	var domain models.DomainFields
    98  
    99  	foundDomain := false
   100  	err := repo.listDomains(path, func(result models.DomainFields) bool {
   101  		domain = result
   102  		foundDomain = true
   103  		return false
   104  	})
   105  
   106  	if err == nil && !foundDomain {
   107  		err = errors.NewModelNotFoundError("Domain", name)
   108  	}
   109  
   110  	return domain, err
   111  }
   112  
   113  func (repo CloudControllerDomainRepository) Create(domainName string, owningOrgGUID string) (createdDomain models.DomainFields, err error) {
   114  	data, err := json.Marshal(resources.DomainEntity{
   115  		Name:                   domainName,
   116  		OwningOrganizationGUID: owningOrgGUID,
   117  		Wildcard:               true,
   118  	})
   119  
   120  	if err != nil {
   121  		return
   122  	}
   123  
   124  	resource := new(resources.DomainResource)
   125  	err = repo.gateway.CreateResource(
   126  		repo.config.APIEndpoint(),
   127  		"/v2/private_domains",
   128  		bytes.NewReader(data),
   129  		resource)
   130  
   131  	if err != nil {
   132  		return
   133  	}
   134  
   135  	createdDomain = resource.ToFields()
   136  	return
   137  }
   138  
   139  func (repo CloudControllerDomainRepository) CreateSharedDomain(domainName string, routerGroupGUID string) error {
   140  	data, err := json.Marshal(resources.DomainEntity{
   141  		Name:            domainName,
   142  		RouterGroupGUID: routerGroupGUID,
   143  		Wildcard:        true,
   144  	})
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	return repo.gateway.CreateResource(
   150  		repo.config.APIEndpoint(),
   151  		"/v2/shared_domains",
   152  		bytes.NewReader(data),
   153  	)
   154  }
   155  
   156  func (repo CloudControllerDomainRepository) Delete(domainGUID string) error {
   157  	path := fmt.Sprintf("/v2/private_domains/%s?recursive=true", domainGUID)
   158  	return repo.gateway.DeleteResource(
   159  		repo.config.APIEndpoint(),
   160  		path)
   161  }
   162  
   163  func (repo CloudControllerDomainRepository) DeleteSharedDomain(domainGUID string) error {
   164  	path := fmt.Sprintf("/v2/shared_domains/%s?recursive=true", domainGUID)
   165  	return repo.gateway.DeleteResource(
   166  		repo.config.APIEndpoint(),
   167  		path)
   168  }
   169  
   170  func (repo CloudControllerDomainRepository) FirstOrDefault(orgGUID string, name *string) (domain models.DomainFields, error error) {
   171  	if name == nil {
   172  		domain, error = repo.defaultDomain(orgGUID)
   173  	} else {
   174  		domain, error = repo.FindByNameInOrg(*name, orgGUID)
   175  	}
   176  	return
   177  }
   178  
   179  func (repo CloudControllerDomainRepository) defaultDomain(orgGUID string) (models.DomainFields, error) {
   180  	var foundDomain *models.DomainFields
   181  	err := repo.ListDomainsForOrg(orgGUID, func(domain models.DomainFields) bool {
   182  		foundDomain = &domain
   183  		return !domain.Shared
   184  	})
   185  	if err != nil {
   186  		return models.DomainFields{}, err
   187  	}
   188  
   189  	if foundDomain == nil {
   190  		return models.DomainFields{}, errors.New(T("Could not find a default domain"))
   191  	}
   192  
   193  	return *foundDomain, nil
   194  }