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