Alexander Belanger před 5 roky
rodič
revize
99808f4bd6

+ 123 - 43
internal/registry/registry.go

@@ -66,62 +66,77 @@ type gcrRepositoryResp struct {
 func (r *Registry) listGCRRepositories(
 	repo repository.Repository,
 ) ([]*Repository, error) {
-	jwtTok := string(r.DockerTokenCache.Token)
+	// jwtTok := string(r.DockerTokenCache.Token)
 
-	// if a jwt token does not exist or is expired, refresh it
-	if r.DockerTokenCache.IsExpired() || len(jwtTok) == 0 {
-		gcp, err := repo.GCPIntegration.ReadGCPIntegration(
-			r.GCPIntegrationID,
-		)
+	// // if a jwt token does not exist or is expired, refresh it
+	// if r.DockerTokenCache.IsExpired() || len(jwtTok) == 0 {
+	// 	gcp, err := repo.GCPIntegration.ReadGCPIntegration(
+	// 		r.GCPIntegrationID,
+	// 	)
 
-		if err != nil {
-			return nil, err
-		}
+	// 	if err != nil {
+	// 		return nil, err
+	// 	}
 
-		// get oauth2 access token
-		oauthTok, err := gcp.GetBearerToken(r.getTokenCache, r.setTokenCacheFunc(repo))
+	// 	// get oauth2 access token
+	// 	oauthTok, err := gcp.GetBearerToken(r.getTokenCache, r.setTokenCacheFunc(repo))
 
-		if err != nil {
-			return nil, err
-		}
+	// 	if err != nil {
+	// 		return nil, err
+	// 	}
 
-		// get jwt token
-		client := &http.Client{}
+	// 	// get jwt token
+	// 	client := &http.Client{}
 
-		req, err := http.NewRequest(
-			"GET",
-			"https://gcr.io/v2/token?service=gcr.io&scope=registry:catalog:*",
-			nil,
-		)
+	// 	req, err := http.NewRequest(
+	// 		"GET",
+	// 		"https://gcr.io/v2/token?service=gcr.io&scope=registry:catalog:*",
+	// 		nil,
+	// 	)
 
-		req.SetBasicAuth("_token", oauthTok)
+	// 	req.SetBasicAuth("_token", oauthTok)
 
-		resp, err := client.Do(req)
+	// 	resp, err := client.Do(req)
 
-		if err != nil {
-			return nil, err
-		}
+	// 	if err != nil {
+	// 		return nil, err
+	// 	}
 
-		jwtSource := gcrJWT{}
+	// 	jwtSource := gcrJWT{}
 
-		if err := json.NewDecoder(resp.Body).Decode(&jwtSource); err != nil {
-			return nil, fmt.Errorf("Invalid token JSON from metadata: %v", err)
-		}
+	// 	if err := json.NewDecoder(resp.Body).Decode(&jwtSource); err != nil {
+	// 		return nil, fmt.Errorf("Invalid token JSON from metadata: %v", err)
+	// 	}
 
-		_, err = repo.Registry.UpdateRegistryDockerTokenCache(
-			&ints.RegTokenCache{
-				RegistryID: r.ID,
-				Token:      []byte(jwtSource.AccessToken),
-				// subtract some time from expiry for buffer
-				Expiry: time.Now().Add(time.Second*time.Duration(jwtSource.ExpiresInSec) - 5*time.Second),
-			},
-		)
+	// 	_, err = repo.Registry.UpdateRegistryDockerTokenCache(
+	// 		&ints.RegTokenCache{
+	// 			RegistryID: r.ID,
+	// 			Token:      []byte(jwtSource.AccessToken),
+	// 			// subtract some time from expiry for buffer
+	// 			Expiry: time.Now().Add(time.Second*time.Duration(jwtSource.ExpiresInSec) - 5*time.Second),
+	// 		},
+	// 	)
 
-		if err != nil {
-			return nil, err
-		}
+	// 	if err != nil {
+	// 		return nil, err
+	// 	}
 
-		jwtTok = jwtSource.AccessToken
+	// 	jwtTok = jwtSource.AccessToken
+	// }
+
+	gcp, err := repo.GCPIntegration.ReadGCPIntegration(
+		r.GCPIntegrationID,
+	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	// get oauth2 access token
+	oauthTok, err := gcp.GetBearerToken(r.getTokenCache, r.setTokenCacheFunc(repo))
+
+	if err != nil {
+		return nil, err
 	}
 
 	// use JWT token to request catalog
@@ -137,7 +152,9 @@ func (r *Registry) listGCRRepositories(
 		return nil, err
 	}
 
-	req.Header.Add("Authorization", "Bearer "+jwtTok)
+	req.SetBasicAuth("oauth2accesstoken", oauthTok)
+
+	// req.Header.Add("Authorization", "Bearer "+jwtTok)
 
 	resp, err := client.Do(req)
 
@@ -227,6 +244,10 @@ func (r *Registry) ListImages(
 		return r.listECRImages(repoName, repo)
 	}
 
+	if r.GCPIntegrationID != 0 {
+		return r.listGCRImages(repoName, repo)
+	}
+
 	return nil, fmt.Errorf("error listing images")
 }
 
@@ -267,3 +288,62 @@ func (r *Registry) listECRImages(repoName string, repo repository.Repository) ([
 
 	return res, nil
 }
+
+type gcrImageResp struct {
+	Tags []string `json:"tags"`
+}
+
+func (r *Registry) listGCRImages(repoName string, repo repository.Repository) ([]*Image, error) {
+	gcp, err := repo.GCPIntegration.ReadGCPIntegration(
+		r.GCPIntegrationID,
+	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	// get oauth2 access token
+	oauthTok, err := gcp.GetBearerToken(r.getTokenCache, r.setTokenCacheFunc(repo))
+
+	if err != nil {
+		return nil, err
+	}
+
+	// use JWT token to request catalog
+	client := &http.Client{}
+
+	req, err := http.NewRequest(
+		"GET",
+		fmt.Sprintf("https://gcr.io/v2/%s/tags/list", repoName),
+		nil,
+	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	req.SetBasicAuth("oauth2accesstoken", oauthTok)
+
+	resp, err := client.Do(req)
+
+	if err != nil {
+		return nil, err
+	}
+
+	gcrResp := gcrImageResp{}
+
+	if err := json.NewDecoder(resp.Body).Decode(&gcrResp); err != nil {
+		return nil, fmt.Errorf("Could not read GCR repositories: %v", err)
+	}
+
+	res := make([]*Image, 0)
+
+	for _, tag := range gcrResp.Tags {
+		res = append(res, &Image{
+			RepositoryName: repoName,
+			Tag:            tag,
+		})
+	}
+
+	return res, nil
+}

+ 1 - 1
server/api/registry_handler.go

@@ -139,7 +139,7 @@ func (app *App) HandleListImages(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	repoName := chi.URLParam(r, "repo_name")
+	repoName := chi.URLParam(r, "*")
 
 	reg, err := app.repo.Registry.ReadRegistry(uint(regID))
 

+ 4 - 1
server/router/router.go

@@ -217,7 +217,10 @@ func New(
 
 		r.Method(
 			"GET",
-			"/projects/{project_id}/registries/{registry_id}/repositories/{repo_name}",
+			// * is the repo name, which can itself be nested
+			// for example, for GCR this is project-id/repo
+			// need to use wildcard, see https://github.com/go-chi/chi/issues/243
+			"/projects/{project_id}/registries/{registry_id}/repositories/*",
 			auth.DoesUserHaveProjectAccess(
 				auth.DoesUserHaveRegistryAccess(
 					requestlog.NewHandler(a.HandleListImages, l),