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