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