Commit b2570ef1 authored by jackgr's avatar jackgr

Make Repo struct public

parent 09ebdd36
......@@ -27,7 +27,7 @@ import (
// FilebasedCredentialProvider provides credentials for registries.
type FilebasedCredentialProvider struct {
// Actual backing store
backingCredentialProvider CredentialProvider
backingCredentialProvider ICredentialProvider
}
// NamedRepoCredential associates a name with a RepoCredential.
......@@ -37,7 +37,7 @@ type NamedRepoCredential struct {
}
// NewFilebasedCredentialProvider creates a file based credential provider.
func NewFilebasedCredentialProvider(filename string) (CredentialProvider, error) {
func NewFilebasedCredentialProvider(filename string) (ICredentialProvider, error) {
icp := NewInmemCredentialProvider()
log.Printf("Using credentials file %s", filename)
c, err := readCredentialsFile(filename)
......
......@@ -47,7 +47,7 @@ func TestSetAndGetBasicAuthFilebased(t *testing.T) {
testGetCredential(t, cp, tc)
}
func getProvider(t *testing.T) CredentialProvider {
func getProvider(t *testing.T) ICredentialProvider {
cp, err := NewFilebasedCredentialProvider(filename)
if err != nil {
t.Fatalf("cannot create a new provider from file %s: %s", filename, err)
......
......@@ -53,21 +53,21 @@ const (
GCSPublicRepoBucket = GCSPublicRepoName
)
// gcsRepo implements the ObjectStorageRepo interface for Google Cloud Storage.
type gcsRepo struct {
repo
// GCSRepo implements the IStorageRepo interface for Google Cloud Storage.
type GCSRepo struct {
Repo
bucket string
httpClient *http.Client
service *storage.Service
}
// NewPublicGCSRepo creates a new an ObjectStorageRepo for the public GCS repository.
func NewPublicGCSRepo(httpClient *http.Client) (ObjectStorageRepo, error) {
// NewPublicGCSRepo creates a new an IStorageRepo for the public GCS repository.
func NewPublicGCSRepo(httpClient *http.Client) (IStorageRepo, error) {
return NewGCSRepo(GCSPublicRepoName, GCSPublicRepoURL, "", nil)
}
// NewGCSRepo creates a new ObjectStorageRepo for a given GCS repository.
func NewGCSRepo(name, URL, credentialName string, httpClient *http.Client) (ObjectStorageRepo, error) {
// NewGCSRepo creates a new IStorageRepo for a given GCS repository.
func NewGCSRepo(name, URL, credentialName string, httpClient *http.Client) (IStorageRepo, error) {
r, err := newRepo(name, URL, credentialName, GCSRepoFormat, GCSRepoType)
if err != nil {
return nil, err
......@@ -76,7 +76,7 @@ func NewGCSRepo(name, URL, credentialName string, httpClient *http.Client) (Obje
return newGCSRepo(r, httpClient)
}
func newGCSRepo(r *repo, httpClient *http.Client) (*gcsRepo, error) {
func newGCSRepo(r *Repo, httpClient *http.Client) (*GCSRepo, error) {
URL := r.GetURL()
m := GCSRepoURLMatcher.FindStringSubmatch(URL)
if len(m) != 2 {
......@@ -96,8 +96,8 @@ func newGCSRepo(r *repo, httpClient *http.Client) (*gcsRepo, error) {
return nil, fmt.Errorf("cannot create storage service for %s: %s", URL, err)
}
gcsr := &gcsRepo{
repo: *r,
gcsr := &GCSRepo{
Repo: *r,
httpClient: httpClient,
service: gcs,
bucket: m[1],
......@@ -117,7 +117,7 @@ func validateRepoType(repoType RepoType) error {
// ListCharts lists charts in this chart repository whose string values conform to the
// supplied regular expression, or all charts, if the regular expression is nil.
func (g *gcsRepo) ListCharts(regex *regexp.Regexp) ([]string, error) {
func (g *GCSRepo) ListCharts(regex *regexp.Regexp) ([]string, error) {
charts := []string{}
// List all objects in a bucket using pagination
......@@ -155,7 +155,7 @@ func (g *gcsRepo) ListCharts(regex *regexp.Regexp) ([]string, error) {
}
// GetChart retrieves, unpacks and returns a chart by name.
func (g *gcsRepo) GetChart(name string) (*chart.Chart, error) {
func (g *GCSRepo) GetChart(name string) (*chart.Chart, error) {
// Charts should be named bucket/chart-X.Y.Z.tgz, so check that the name matches
if !ChartNameMatcher.MatchString(name) {
return nil, fmt.Errorf("name must be of the form <name>-<version>.tgz, was %s", name)
......@@ -184,11 +184,11 @@ func (g *gcsRepo) GetChart(name string) (*chart.Chart, error) {
}
// GetBucket returns the repository bucket.
func (g *gcsRepo) GetBucket() string {
func (g *GCSRepo) GetBucket() string {
return g.bucket
}
// Do performs an HTTP operation on the receiver's httpClient.
func (g *gcsRepo) Do(req *http.Request) (resp *http.Response, err error) {
func (g *GCSRepo) Do(req *http.Request) (resp *http.Response, err error) {
return g.httpClient.Do(req)
}
......@@ -125,7 +125,7 @@ func TestGetChartWithInvalidName(t *testing.T) {
}
}
func getTestRepo(t *testing.T) ObjectStorageRepo {
func getTestRepo(t *testing.T) IStorageRepo {
tr, err := NewGCSRepo(TestRepoName, TestRepoURL, TestRepoCredentialName, nil)
if err != nil {
t.Fatal(err)
......
......@@ -28,7 +28,7 @@ type InmemCredentialProvider struct {
}
// NewInmemCredentialProvider creates a new memory based credential provider.
func NewInmemCredentialProvider() CredentialProvider {
func NewInmemCredentialProvider() ICredentialProvider {
return &InmemCredentialProvider{credentials: make(map[string]*RepoCredential)}
}
......
......@@ -32,7 +32,7 @@ func createMissingError(name string) error {
return fmt.Errorf("no such credential: %s", name)
}
func testGetCredential(t *testing.T, cp CredentialProvider, tc *testCase) {
func testGetCredential(t *testing.T, cp ICredentialProvider, tc *testCase) {
actual, actualErr := cp.GetCredential(tc.name)
if !reflect.DeepEqual(actual, tc.exp) {
t.Fatalf("test case %s failed: want: %#v, have: %#v", tc.name, tc.exp, actual)
......@@ -43,7 +43,7 @@ func testGetCredential(t *testing.T, cp CredentialProvider, tc *testCase) {
}
}
func verifySetAndGetCredential(t *testing.T, cp CredentialProvider, tc *testCase) {
func verifySetAndGetCredential(t *testing.T, cp ICredentialProvider, tc *testCase) {
err := cp.SetCredential(tc.name, tc.exp)
if err != nil {
t.Fatalf("test case %s failed: cannot set credential: %v", tc.name, err)
......
......@@ -24,13 +24,13 @@ import (
type inmemRepoService struct {
sync.RWMutex
repositories map[string]Repo
repositories map[string]IRepo
}
// NewInmemRepoService returns a new memory based repository service.
func NewInmemRepoService() Service {
func NewInmemRepoService() IRepoService {
rs := &inmemRepoService{
repositories: make(map[string]Repo),
repositories: make(map[string]IRepo),
}
r, err := NewPublicGCSRepo(nil)
......@@ -42,11 +42,11 @@ func NewInmemRepoService() Service {
}
// List returns the list of all known chart repositories
func (rs *inmemRepoService) List() ([]Repo, error) {
func (rs *inmemRepoService) List() ([]IRepo, error) {
rs.RLock()
defer rs.RUnlock()
ret := []Repo{}
ret := []IRepo{}
for _, r := range rs.repositories {
ret = append(ret, r)
}
......@@ -55,7 +55,7 @@ func (rs *inmemRepoService) List() ([]Repo, error) {
}
// Create adds a known repository to the list
func (rs *inmemRepoService) Create(repository Repo) error {
func (rs *inmemRepoService) Create(repository IRepo) error {
rs.Lock()
defer rs.Unlock()
......@@ -70,7 +70,7 @@ func (rs *inmemRepoService) Create(repository Repo) error {
}
// Get returns the repository with the given name
func (rs *inmemRepoService) Get(name string) (Repo, error) {
func (rs *inmemRepoService) Get(name string) (IRepo, error) {
rs.RLock()
defer rs.RUnlock()
......@@ -83,11 +83,11 @@ func (rs *inmemRepoService) Get(name string) (Repo, error) {
}
// GetByURL returns the repository that backs the given URL
func (rs *inmemRepoService) GetByURL(URL string) (Repo, error) {
func (rs *inmemRepoService) GetByURL(URL string) (IRepo, error) {
rs.RLock()
defer rs.RUnlock()
var found Repo
var found IRepo
for _, r := range rs.repositories {
rURL := r.GetURL()
if strings.HasPrefix(URL, rURL) {
......
......@@ -21,21 +21,12 @@ import (
"net/url"
)
// repo describes a repository
type repo struct {
Name string `json:"name"` // Friendly name for this repository
URL string `json:"url"` // URL to the root of this repository
CredentialName string `json:"credentialname"` // Credential name used to access this repository
Format RepoFormat `json:"format"` // Format of this repository
Type RepoType `json:"type"` // Technology implementing this repository
}
// NewRepo takes params and returns a Repo
func NewRepo(name, URL, credentialName, repoFormat, repoType string) (Repo, error) {
// NewRepo takes params and returns a IRepo
func NewRepo(name, URL, credentialName, repoFormat, repoType string) (IRepo, error) {
return newRepo(name, URL, credentialName, RepoFormat(repoFormat), RepoType(repoType))
}
func newRepo(name, URL, credentialName string, repoFormat RepoFormat, repoType RepoType) (*repo, error) {
func newRepo(name, URL, credentialName string, repoFormat RepoFormat, repoType RepoType) (*Repo, error) {
if name == "" {
return nil, fmt.Errorf("name must not be empty")
}
......@@ -53,7 +44,7 @@ func newRepo(name, URL, credentialName string, repoFormat RepoFormat, repoType R
return nil, err
}
r := &repo{
r := &Repo{
Name: name,
Type: repoType,
URL: URL,
......@@ -75,39 +66,39 @@ func validateRepoFormat(repoFormat RepoFormat) error {
}
// GetName returns the friendly name of this repository.
func (r *repo) GetName() string {
func (r *Repo) GetName() string {
return r.Name
}
// GetType returns the technology implementing this repository.
func (r *repo) GetType() RepoType {
func (r *Repo) GetType() RepoType {
return r.Type
}
// GetURL returns the URL to the root of this repository.
func (r *repo) GetURL() string {
func (r *Repo) GetURL() string {
return r.URL
}
// GetFormat returns the format of this repository.
func (r *repo) GetFormat() RepoFormat {
func (r *Repo) GetFormat() RepoFormat {
return r.Format
}
// GetCredentialName returns the credential name used to access this repository.
func (r *repo) GetCredentialName() string {
func (r *Repo) GetCredentialName() string {
return r.CredentialName
}
func validateRepo(tr Repo, wantName, wantURL, wantCredentialName string, wantFormat RepoFormat, wantType RepoType) error {
func validateRepo(tr IRepo, wantName, wantURL, wantCredentialName string, wantFormat RepoFormat, wantType RepoType) error {
haveName := tr.GetName()
if haveName != wantName {
return fmt.Errorf("unexpected repo name; want: %s, have %s", wantName, haveName)
return fmt.Errorf("unexpected repository name; want: %s, have %s", wantName, haveName)
}
haveURL := tr.GetURL()
if haveURL != wantURL {
return fmt.Errorf("unexpected repo url; want: %s, have %s", wantURL, haveURL)
return fmt.Errorf("unexpected repository url; want: %s, have %s", wantURL, haveURL)
}
haveCredentialName := tr.GetCredentialName()
......@@ -116,17 +107,17 @@ func validateRepo(tr Repo, wantName, wantURL, wantCredentialName string, wantFor
}
if haveCredentialName != wantCredentialName {
return fmt.Errorf("unexpected repo credential name; want: %s, have %s", wantCredentialName, haveCredentialName)
return fmt.Errorf("unexpected repository credential name; want: %s, have %s", wantCredentialName, haveCredentialName)
}
haveFormat := tr.GetFormat()
if haveFormat != wantFormat {
return fmt.Errorf("unexpected repo format; want: %s, have %s", wantFormat, haveFormat)
return fmt.Errorf("unexpected repository format; want: %s, have %s", wantFormat, haveFormat)
}
haveType := tr.GetType()
if haveType != wantType {
return fmt.Errorf("unexpected repo type; want: %s, have %s", wantType, haveType)
return fmt.Errorf("unexpected repository type; want: %s, have %s", wantType, haveType)
}
return nil
......
......@@ -29,28 +29,28 @@ import (
"sync"
)
// RepoProvider is a factory for ChartRepo instances.
// RepoProvider is a factory for IChartRepo instances.
type RepoProvider interface {
GetRepoByURL(URL string) (ChartRepo, error)
GetRepoByName(repoName string) (ChartRepo, error)
GetRepoByURL(URL string) (IChartRepo, error)
GetRepoByName(repoName string) (IChartRepo, error)
GetChartByReference(reference string) (*chart.Chart, error)
}
type repoProvider struct {
sync.RWMutex
rs Service
cp CredentialProvider
rs IRepoService
cp ICredentialProvider
gcsrp GCSRepoProvider
repos map[string]ChartRepo
repos map[string]IChartRepo
}
// NewRepoProvider creates a new repository provider.
func NewRepoProvider(rs Service, gcsrp GCSRepoProvider, cp CredentialProvider) RepoProvider {
func NewRepoProvider(rs IRepoService, gcsrp GCSRepoProvider, cp ICredentialProvider) RepoProvider {
return newRepoProvider(rs, gcsrp, cp)
}
// newRepoProvider creates a new repository provider.
func newRepoProvider(rs Service, gcsrp GCSRepoProvider, cp CredentialProvider) *repoProvider {
func newRepoProvider(rs IRepoService, gcsrp GCSRepoProvider, cp ICredentialProvider) *repoProvider {
if rs == nil {
rs = NewInmemRepoService()
}
......@@ -63,18 +63,18 @@ func newRepoProvider(rs Service, gcsrp GCSRepoProvider, cp CredentialProvider) *
gcsrp = NewGCSRepoProvider(cp)
}
repos := make(map[string]ChartRepo)
repos := make(map[string]IChartRepo)
rp := &repoProvider{rs: rs, gcsrp: gcsrp, cp: cp, repos: repos}
return rp
}
// GetRepoService returns the repository service used by this repository provider.
func (rp *repoProvider) GetRepoService() Service {
func (rp *repoProvider) GetRepoService() IRepoService {
return rp.rs
}
// GetCredentialProvider returns the credential provider used by this repository provider.
func (rp *repoProvider) GetCredentialProvider() CredentialProvider {
func (rp *repoProvider) GetCredentialProvider() ICredentialProvider {
return rp.cp
}
......@@ -84,7 +84,7 @@ func (rp *repoProvider) GetGCSRepoProvider() GCSRepoProvider {
}
// GetRepoByName returns the repository with the given name.
func (rp *repoProvider) GetRepoByName(repoName string) (ChartRepo, error) {
func (rp *repoProvider) GetRepoByName(repoName string) (IChartRepo, error) {
rp.Lock()
defer rp.Unlock()
......@@ -100,7 +100,7 @@ func (rp *repoProvider) GetRepoByName(repoName string) (ChartRepo, error) {
return rp.createRepoByType(cr)
}
func (rp *repoProvider) createRepoByType(r Repo) (ChartRepo, error) {
func (rp *repoProvider) createRepoByType(r IRepo) (IChartRepo, error) {
switch r.GetType() {
case GCSRepoType:
cr, err := rp.gcsrp.GetGCSRepo(r)
......@@ -114,7 +114,7 @@ func (rp *repoProvider) createRepoByType(r Repo) (ChartRepo, error) {
return nil, fmt.Errorf("unknown repository type: %s", r.GetType())
}
func (rp *repoProvider) createRepo(cr ChartRepo) (ChartRepo, error) {
func (rp *repoProvider) createRepo(cr IChartRepo) (IChartRepo, error) {
name := cr.GetName()
if _, ok := rp.repos[name]; ok {
return nil, fmt.Errorf("respository named %s already exists", name)
......@@ -125,7 +125,7 @@ func (rp *repoProvider) createRepo(cr ChartRepo) (ChartRepo, error) {
}
// GetRepoByURL returns the repository whose URL is a prefix of the given URL.
func (rp *repoProvider) GetRepoByURL(URL string) (ChartRepo, error) {
func (rp *repoProvider) GetRepoByURL(URL string) (IChartRepo, error) {
rp.Lock()
defer rp.Unlock()
......@@ -141,8 +141,8 @@ func (rp *repoProvider) GetRepoByURL(URL string) (ChartRepo, error) {
return rp.createRepoByType(cr)
}
func (rp *repoProvider) findRepoByURL(URL string) ChartRepo {
var found ChartRepo
func (rp *repoProvider) findRepoByURL(URL string) IChartRepo {
var found IChartRepo
for _, r := range rp.repos {
rURL := r.GetURL()
if strings.HasPrefix(URL, rURL) {
......@@ -178,17 +178,17 @@ func (rp *repoProvider) GetChartByReference(reference string) (*chart.Chart, err
return r.GetChart(name)
}
// GCSRepoProvider is a factory for GCS Repo instances.
// GCSRepoProvider is a factory for GCS IRepo instances.
type GCSRepoProvider interface {
GetGCSRepo(r Repo) (ObjectStorageRepo, error)
GetGCSRepo(r IRepo) (IStorageRepo, error)
}
type gcsRepoProvider struct {
cp CredentialProvider
cp ICredentialProvider
}
// NewGCSRepoProvider creates a GCSRepoProvider.
func NewGCSRepoProvider(cp CredentialProvider) GCSRepoProvider {
func NewGCSRepoProvider(cp ICredentialProvider) GCSRepoProvider {
if cp == nil {
cp = NewInmemCredentialProvider()
}
......@@ -198,7 +198,7 @@ func NewGCSRepoProvider(cp CredentialProvider) GCSRepoProvider {
// GetGCSRepo returns a new Google Cloud Storage repository. If a credential is specified, it will try to
// fetch it and use it, and if the credential isn't found, it will fall back to an unauthenticated client.
func (gcsrp gcsRepoProvider) GetGCSRepo(r Repo) (ObjectStorageRepo, error) {
func (gcsrp gcsRepoProvider) GetGCSRepo(r IRepo) (IStorageRepo, error) {
client, err := gcsrp.createGCSClient(r.GetCredentialName())
if err != nil {
return nil, err
......
......@@ -50,9 +50,9 @@ func TestRepoProvider(t *testing.T) {
t.Fatal(err)
}
castRepo, ok := haveRepo.(ObjectStorageRepo)
castRepo, ok := haveRepo.(IStorageRepo)
if !ok {
t.Fatalf("invalid repo type, want: ObjectStorageRepo, have: %T.", haveRepo)
t.Fatalf("invalid repo type, want: IStorageRepo, have: %T.", haveRepo)
}
wantBucket := GCSPublicRepoBucket
......
......@@ -53,7 +53,7 @@ type SecretsCredentialProvider struct {
}
// NewSecretsCredentialProvider creates a new secrets credential provider.
func NewSecretsCredentialProvider() CredentialProvider {
func NewSecretsCredentialProvider() ICredentialProvider {
kubernetesConfig := &util.KubernetesConfig{
KubePath: *kubePath,
KubeService: *kubeService,
......
......@@ -44,8 +44,8 @@ type RepoCredential struct {
ServiceAccount JWTTokenCredential `json:"serviceaccount,omitempty"`
}
// CredentialProvider provides credentials for chart repositories.
type CredentialProvider interface {
// ICredentialProvider provides credentials for chart repositories.
type ICredentialProvider interface {
// SetCredential sets the credential for a repository.
// May not be supported by some repository services.
SetCredential(name string, credential *RepoCredential) error
......@@ -68,8 +68,17 @@ const (
FlatRepoFormat = RepoFormat("flat")
)
// Repo abstracts a repository.
type Repo interface {
// Repo describes a repository
type Repo struct {
Name string `json:"name"` // Friendly name for this repository
URL string `json:"url"` // URL to the root of this repository
CredentialName string `json:"credentialname"` // Credential name used to access this repository
Format RepoFormat `json:"format"` // Format of this repository
Type RepoType `json:"type"` // Technology implementing this repository
}
// IRepo abstracts a repository.
type IRepo interface {
// GetName returns the friendly name of this repository.
GetName() string
// GetURL returns the URL to the root of this repository.
......@@ -82,10 +91,10 @@ type Repo interface {
GetType() RepoType
}
// ChartRepo abstracts a place that holds charts.
type ChartRepo interface {
// A ChartRepo is a Repo
Repo
// IChartRepo abstracts a place that holds charts.
type IChartRepo interface {
// A IChartRepo is a IRepo
IRepo
// ListCharts lists charts in this repository whose string values
// conform to the supplied regular expression, or all charts if regex is nil
......@@ -95,27 +104,27 @@ type ChartRepo interface {
GetChart(name string) (*chart.Chart, error)
}
// ObjectStorageRepo abstracts a repository that resides in Object Storage,
// IStorageRepo abstracts a repository that resides in Object Storage,
// such as Google Cloud Storage, AWS S3, etc.
type ObjectStorageRepo interface {
// An ObjectStorageRepo is a ChartRepo
ChartRepo
type IStorageRepo interface {
// An IStorageRepo is a IChartRepo
IChartRepo
// GetBucket returns the name of the bucket that contains this repository.
GetBucket() string
}
// Service maintains a list of chart repositories that defines the scope of all
// IRepoService maintains a list of chart repositories that defines the scope of all
// repository based operations, such as search and chart reference resolution.
type Service interface {
type IRepoService interface {
// List returns the list of all known chart repositories
List() ([]Repo, error)
List() ([]IRepo, error)
// Create adds a known repository to the list
Create(repository Repo) error
Create(repository IRepo) error
// Get returns the repository with the given name
Get(name string) (Repo, error)
Get(name string) (IRepo, error)
// GetByURL returns the repository that backs the given URL
GetByURL(URL string) (Repo, error)
GetByURL(URL string) (IRepo, error)
// Delete removes a known repository from the list
Delete(name string) error
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment