github.com/jasonkeene/cli@v6.14.1-0.20160816203908-ca5715166dfb+incompatible/cf/configuration/coreconfig/config_repository.go (about)

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