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  }