github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/cf/configuration/coreconfig/config_repository.go (about) 1 package coreconfig 2 3 import ( 4 "strings" 5 "sync" 6 7 "code.cloudfoundry.org/cli/cf/configuration" 8 "code.cloudfoundry.org/cli/cf/models" 9 "code.cloudfoundry.org/cli/version" 10 "github.com/blang/semver" 11 ) 12 13 type ConfigRepository struct { 14 CFCLIVersion string 15 data *Data 16 mutex *sync.RWMutex 17 initOnce *sync.Once 18 persistor configuration.Persistor 19 onError func(error) 20 } 21 22 type CCInfo struct { 23 APIVersion string `json:"api_version"` 24 AuthorizationEndpoint string `json:"authorization_endpoint"` 25 DopplerEndpoint string `json:"doppler_logging_endpoint"` 26 MinCLIVersion string `json:"min_cli_version"` 27 MinRecommendedCLIVersion string `json:"min_recommended_cli_version"` 28 SSHOAuthClient string `json:"app_ssh_oauth_client"` 29 RoutingAPIEndpoint string `json:"routing_endpoint"` 30 } 31 32 func NewRepositoryFromFilepath(filepath string, errorHandler func(error)) Repository { 33 if errorHandler == nil { 34 return nil 35 } 36 return NewRepositoryFromPersistor(configuration.NewDiskPersistor(filepath), errorHandler) 37 } 38 39 func NewRepositoryFromPersistor(persistor configuration.Persistor, errorHandler func(error)) Repository { 40 data := NewData() 41 if !persistor.Exists() { 42 //set default plugin repo 43 data.PluginRepos = append(data.PluginRepos, models.PluginRepo{ 44 Name: "CF-Community", 45 URL: "https://plugins.cloudfoundry.org", 46 }) 47 } 48 49 return &ConfigRepository{ 50 data: data, 51 mutex: new(sync.RWMutex), 52 initOnce: new(sync.Once), 53 persistor: persistor, 54 onError: errorHandler, 55 } 56 } 57 58 type Reader interface { 59 APIEndpoint() string 60 APIVersion() string 61 HasAPIEndpoint() bool 62 63 AuthenticationEndpoint() string 64 DopplerEndpoint() string 65 UaaEndpoint() string 66 RoutingAPIEndpoint() string 67 AccessToken() string 68 UAAOAuthClient() string 69 UAAOAuthClientSecret() string 70 SSHOAuthClient() string 71 RefreshToken() string 72 73 OrganizationFields() models.OrganizationFields 74 HasOrganization() bool 75 76 SpaceFields() models.SpaceFields 77 HasSpace() bool 78 79 Username() string 80 UserGUID() string 81 UserEmail() string 82 IsLoggedIn() bool 83 IsSSLDisabled() bool 84 IsMinAPIVersion(semver.Version) bool 85 IsMinCLIVersion(string) bool 86 MinCLIVersion() string 87 MinRecommendedCLIVersion() string 88 CLIVersion() string 89 90 AsyncTimeout() uint 91 Trace() string 92 93 ColorEnabled() string 94 95 Locale() string 96 97 PluginRepos() []models.PluginRepo 98 } 99 100 //go:generate counterfeiter . ReadWriter 101 102 type ReadWriter interface { 103 Reader 104 ClearSession() 105 SetAccessToken(string) 106 SetAPIEndpoint(string) 107 SetAPIVersion(string) 108 SetAsyncTimeout(uint) 109 SetAuthenticationEndpoint(string) 110 SetCLIVersion(string) 111 SetColorEnabled(string) 112 SetDopplerEndpoint(string) 113 SetLocale(string) 114 SetMinCLIVersion(string) 115 SetMinRecommendedCLIVersion(string) 116 SetOrganizationFields(models.OrganizationFields) 117 SetPluginRepo(models.PluginRepo) 118 SetRefreshToken(string) 119 SetRoutingAPIEndpoint(string) 120 SetSpaceFields(models.SpaceFields) 121 SetSSHOAuthClient(string) 122 SetSSLDisabled(bool) 123 SetTrace(string) 124 SetUaaEndpoint(string) 125 SetUAAGrantType(string) 126 SetUAAOAuthClient(string) 127 SetUAAOAuthClientSecret(string) 128 UAAGrantType() string 129 UnSetPluginRepo(int) 130 } 131 132 //go:generate counterfeiter . Repository 133 134 type Repository interface { 135 ReadWriter 136 Close() 137 } 138 139 // ACCESS CONTROL 140 141 func (c *ConfigRepository) init() { 142 c.initOnce.Do(func() { 143 err := c.persistor.Load(c.data) 144 if err != nil { 145 c.onError(err) 146 } 147 }) 148 } 149 150 func (c *ConfigRepository) read(cb func()) { 151 c.mutex.RLock() 152 defer c.mutex.RUnlock() 153 c.init() 154 155 cb() 156 } 157 158 func (c *ConfigRepository) write(cb func()) { 159 c.mutex.Lock() 160 defer c.mutex.Unlock() 161 c.init() 162 163 cb() 164 165 err := c.persistor.Save(c.data) 166 if err != nil { 167 c.onError(err) 168 } 169 } 170 171 // CLOSERS 172 173 func (c *ConfigRepository) Close() { 174 c.read(func() { 175 // perform a read to ensure write lock has been cleared 176 }) 177 } 178 179 // GETTERS 180 181 func (c *ConfigRepository) APIVersion() (apiVersion string) { 182 c.read(func() { 183 apiVersion = c.data.APIVersion 184 }) 185 return 186 } 187 188 func (c *ConfigRepository) AuthenticationEndpoint() (authEndpoint string) { 189 c.read(func() { 190 authEndpoint = c.data.AuthorizationEndpoint 191 }) 192 return 193 } 194 195 func (c *ConfigRepository) DopplerEndpoint() (dopplerEndpoint string) { 196 c.read(func() { 197 dopplerEndpoint = c.data.DopplerEndPoint 198 }) 199 200 return 201 } 202 203 func (c *ConfigRepository) UaaEndpoint() (uaaEndpoint string) { 204 c.read(func() { 205 uaaEndpoint = c.data.UaaEndpoint 206 }) 207 return 208 } 209 210 func (c *ConfigRepository) RoutingAPIEndpoint() (routingAPIEndpoint string) { 211 c.read(func() { 212 routingAPIEndpoint = c.data.RoutingAPIEndpoint 213 }) 214 return 215 } 216 217 func (c *ConfigRepository) APIEndpoint() string { 218 var apiEndpoint string 219 c.read(func() { 220 apiEndpoint = c.data.Target 221 }) 222 apiEndpoint = strings.TrimRight(apiEndpoint, "/") 223 224 return apiEndpoint 225 } 226 227 func (c *ConfigRepository) HasAPIEndpoint() (hasEndpoint bool) { 228 c.read(func() { 229 hasEndpoint = c.data.APIVersion != "" && c.data.Target != "" 230 }) 231 return 232 } 233 234 func (c *ConfigRepository) AccessToken() (accessToken string) { 235 c.read(func() { 236 accessToken = c.data.AccessToken 237 }) 238 return 239 } 240 241 func (c *ConfigRepository) UAAOAuthClient() (clientID string) { 242 c.read(func() { 243 clientID = c.data.UAAOAuthClient 244 }) 245 return 246 } 247 248 func (c *ConfigRepository) UAAOAuthClientSecret() (clientID string) { 249 c.read(func() { 250 clientID = c.data.UAAOAuthClientSecret 251 }) 252 return 253 } 254 255 func (c *ConfigRepository) SSHOAuthClient() (clientID string) { 256 c.read(func() { 257 clientID = c.data.SSHOAuthClient 258 }) 259 return 260 } 261 262 func (c *ConfigRepository) RefreshToken() (refreshToken string) { 263 c.read(func() { 264 refreshToken = c.data.RefreshToken 265 }) 266 return 267 } 268 269 func (c *ConfigRepository) OrganizationFields() (org models.OrganizationFields) { 270 c.read(func() { 271 org = c.data.OrganizationFields 272 }) 273 return 274 } 275 276 func (c *ConfigRepository) SpaceFields() (space models.SpaceFields) { 277 c.read(func() { 278 space = c.data.SpaceFields 279 }) 280 return 281 } 282 283 func (c *ConfigRepository) UserEmail() (email string) { 284 c.read(func() { 285 email = NewTokenInfo(c.data.AccessToken).Email 286 }) 287 return 288 } 289 290 func (c *ConfigRepository) UserGUID() (guid string) { 291 c.read(func() { 292 guid = NewTokenInfo(c.data.AccessToken).UserGUID 293 }) 294 return 295 } 296 297 func (c *ConfigRepository) Username() (name string) { 298 c.read(func() { 299 name = NewTokenInfo(c.data.AccessToken).Username 300 }) 301 return 302 } 303 304 func (c *ConfigRepository) IsLoggedIn() (loggedIn bool) { 305 c.read(func() { 306 loggedIn = c.data.AccessToken != "" 307 }) 308 return 309 } 310 311 func (c *ConfigRepository) HasOrganization() (hasOrg bool) { 312 c.read(func() { 313 hasOrg = c.data.OrganizationFields.GUID != "" && c.data.OrganizationFields.Name != "" 314 }) 315 return 316 } 317 318 func (c *ConfigRepository) HasSpace() (hasSpace bool) { 319 c.read(func() { 320 hasSpace = c.data.SpaceFields.GUID != "" && c.data.SpaceFields.Name != "" 321 }) 322 return 323 } 324 325 func (c *ConfigRepository) IsSSLDisabled() (isSSLDisabled bool) { 326 c.read(func() { 327 isSSLDisabled = c.data.SSLDisabled 328 }) 329 return 330 } 331 332 // SetCLIVersion should only be used in testing 333 func (c *ConfigRepository) SetCLIVersion(v string) { 334 c.CFCLIVersion = v 335 } 336 337 func (c *ConfigRepository) CLIVersion() string { 338 if c.CFCLIVersion == "" { 339 return version.VersionString() 340 } else { 341 return c.CFCLIVersion 342 } 343 } 344 345 func (c *ConfigRepository) IsMinAPIVersion(requiredVersion semver.Version) bool { 346 var apiVersion string 347 c.read(func() { 348 apiVersion = c.data.APIVersion 349 }) 350 351 actualVersion, err := semver.Make(apiVersion) 352 if err != nil { 353 return false 354 } 355 return actualVersion.GTE(requiredVersion) 356 } 357 358 func (c *ConfigRepository) IsMinCLIVersion(checkVersion string) bool { 359 if checkVersion == version.DefaultVersion { 360 return true 361 } 362 var minCLIVersion string 363 c.read(func() { 364 minCLIVersion = c.data.MinCLIVersion 365 }) 366 if minCLIVersion == "" { 367 return true 368 } 369 370 actualVersion, err := semver.Make(checkVersion) 371 if err != nil { 372 return false 373 } 374 requiredVersion, err := semver.Make(minCLIVersion) 375 if err != nil { 376 return false 377 } 378 return actualVersion.GTE(requiredVersion) 379 } 380 381 func (c *ConfigRepository) MinCLIVersion() (minCLIVersion string) { 382 c.read(func() { 383 minCLIVersion = c.data.MinCLIVersion 384 }) 385 return 386 } 387 388 func (c *ConfigRepository) MinRecommendedCLIVersion() (minRecommendedCLIVersion string) { 389 c.read(func() { 390 minRecommendedCLIVersion = c.data.MinRecommendedCLIVersion 391 }) 392 return 393 } 394 395 func (c *ConfigRepository) AsyncTimeout() (timeout uint) { 396 c.read(func() { 397 timeout = c.data.AsyncTimeout 398 }) 399 return 400 } 401 402 func (c *ConfigRepository) Trace() (trace string) { 403 c.read(func() { 404 trace = c.data.Trace 405 }) 406 return 407 } 408 409 func (c *ConfigRepository) ColorEnabled() (enabled string) { 410 c.read(func() { 411 enabled = c.data.ColorEnabled 412 }) 413 return 414 } 415 416 func (c *ConfigRepository) Locale() (locale string) { 417 c.read(func() { 418 locale = c.data.Locale 419 }) 420 return 421 } 422 423 func (c *ConfigRepository) PluginRepos() (repos []models.PluginRepo) { 424 c.read(func() { 425 repos = c.data.PluginRepos 426 }) 427 return 428 } 429 430 // SETTERS 431 432 func (c *ConfigRepository) ClearSession() { 433 c.write(func() { 434 c.data.AccessToken = "" 435 c.data.RefreshToken = "" 436 c.data.OrganizationFields = models.OrganizationFields{} 437 c.data.SpaceFields = models.SpaceFields{} 438 }) 439 } 440 441 func (c *ConfigRepository) SetAPIEndpoint(endpoint string) { 442 c.write(func() { 443 c.data.Target = endpoint 444 }) 445 } 446 447 func (c *ConfigRepository) SetAPIVersion(version string) { 448 c.write(func() { 449 c.data.APIVersion = version 450 }) 451 } 452 453 func (c *ConfigRepository) SetMinCLIVersion(version string) { 454 c.write(func() { 455 c.data.MinCLIVersion = version 456 }) 457 } 458 459 func (c *ConfigRepository) SetMinRecommendedCLIVersion(version string) { 460 c.write(func() { 461 c.data.MinRecommendedCLIVersion = version 462 }) 463 } 464 465 func (c *ConfigRepository) SetAuthenticationEndpoint(endpoint string) { 466 c.write(func() { 467 c.data.AuthorizationEndpoint = endpoint 468 }) 469 } 470 471 func (c *ConfigRepository) SetDopplerEndpoint(endpoint string) { 472 c.write(func() { 473 c.data.DopplerEndPoint = endpoint 474 }) 475 } 476 477 func (c *ConfigRepository) SetUaaEndpoint(uaaEndpoint string) { 478 c.write(func() { 479 c.data.UaaEndpoint = uaaEndpoint 480 }) 481 } 482 483 func (c *ConfigRepository) SetRoutingAPIEndpoint(routingAPIEndpoint string) { 484 c.write(func() { 485 c.data.RoutingAPIEndpoint = routingAPIEndpoint 486 }) 487 } 488 489 func (c *ConfigRepository) SetAccessToken(token string) { 490 c.write(func() { 491 c.data.AccessToken = token 492 }) 493 } 494 495 func (c *ConfigRepository) SetUAAOAuthClient(clientID string) { 496 c.write(func() { 497 c.data.UAAOAuthClient = clientID 498 }) 499 } 500 501 func (c *ConfigRepository) SetUAAOAuthClientSecret(clientID string) { 502 c.write(func() { 503 c.data.UAAOAuthClientSecret = clientID 504 }) 505 } 506 507 func (c *ConfigRepository) SetSSHOAuthClient(clientID string) { 508 c.write(func() { 509 c.data.SSHOAuthClient = clientID 510 }) 511 } 512 513 func (c *ConfigRepository) SetRefreshToken(token string) { 514 c.write(func() { 515 c.data.RefreshToken = token 516 }) 517 } 518 519 func (c *ConfigRepository) SetOrganizationFields(org models.OrganizationFields) { 520 c.write(func() { 521 c.data.OrganizationFields = org 522 }) 523 } 524 525 func (c *ConfigRepository) SetSpaceFields(space models.SpaceFields) { 526 c.write(func() { 527 c.data.SpaceFields = space 528 }) 529 } 530 531 func (c *ConfigRepository) SetSSLDisabled(disabled bool) { 532 c.write(func() { 533 c.data.SSLDisabled = disabled 534 }) 535 } 536 537 func (c *ConfigRepository) SetAsyncTimeout(timeout uint) { 538 c.write(func() { 539 c.data.AsyncTimeout = timeout 540 }) 541 } 542 543 func (c *ConfigRepository) SetTrace(value string) { 544 c.write(func() { 545 c.data.Trace = value 546 }) 547 } 548 549 func (c *ConfigRepository) SetColorEnabled(enabled string) { 550 c.write(func() { 551 c.data.ColorEnabled = enabled 552 }) 553 } 554 555 func (c *ConfigRepository) SetLocale(locale string) { 556 c.write(func() { 557 c.data.Locale = locale 558 }) 559 } 560 561 func (c *ConfigRepository) SetPluginRepo(repo models.PluginRepo) { 562 c.write(func() { 563 c.data.PluginRepos = append(c.data.PluginRepos, repo) 564 }) 565 } 566 567 func (c *ConfigRepository) UnSetPluginRepo(index int) { 568 c.write(func() { 569 c.data.PluginRepos = append(c.data.PluginRepos[:index], c.data.PluginRepos[index+1:]...) 570 }) 571 } 572 573 func (c *ConfigRepository) UAAGrantType() string { 574 grantType := "" 575 c.read(func() { 576 grantType = c.data.UAAGrantType 577 }) 578 return grantType 579 } 580 581 func (c *ConfigRepository) SetUAAGrantType(grantType string) { 582 c.write(func() { 583 c.data.UAAGrantType = grantType 584 }) 585 }