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 }