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  }