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  }