Skip to content

Commit

Permalink
Added function to check if imageRepo is public
Browse files Browse the repository at this point in the history
  • Loading branch information
tisutisu committed Aug 16, 2023
1 parent a5bd04a commit 76e8b17
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
50 changes: 50 additions & 0 deletions pkg/quay/quay.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,56 @@ func (c *QuayClient) DoesRepositoryExist(organization, imageRepository string) (
return false, errors.New(data.ErrorMessage)
}

// IsRepositoryPublic checks if the specified image repository has visibility public in quay.
func (c *QuayClient) IsRepositoryPublic(organization, imageRepository string) (bool, error) {
url := fmt.Sprintf("%s/repository/%s/%s", c.url, organization, imageRepository)

req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return false, fmt.Errorf("failed to create request: %w", err)
}

Check warning on line 149 in pkg/quay/quay.go

View check run for this annotation

Codecov / codecov/patch

pkg/quay/quay.go#L148-L149

Added lines #L148 - L149 were not covered by tests
req.Header.Add("Authorization", fmt.Sprintf("%s %s", "Bearer", c.AuthToken))
req.Header.Add("Content-Type", "application/json")

res, err := c.httpClient.Do(req)
if err != nil {
return false, fmt.Errorf("failed to Do request: %w", err)
}

Check warning on line 156 in pkg/quay/quay.go

View check run for this annotation

Codecov / codecov/patch

pkg/quay/quay.go#L155-L156

Added lines #L155 - L156 were not covered by tests
defer res.Body.Close()

if res.StatusCode == 404 {
return false, fmt.Errorf("repository %s does not exist in %s organization", imageRepository, organization)
}

if res.StatusCode == 200 {
body, _ := io.ReadAll(res.Body)
repo := &Repository{}
err := json.Unmarshal(body, repo)
if err != nil {
return false, fmt.Errorf("failed to unmarshal response body: %w", err)
}

Check warning on line 169 in pkg/quay/quay.go

View check run for this annotation

Codecov / codecov/patch

pkg/quay/quay.go#L168-L169

Added lines #L168 - L169 were not covered by tests
if repo.IsPublic {
return true, nil
} else {
return false, nil
}
}

body, err := io.ReadAll(res.Body)
if err != nil {
return false, fmt.Errorf("failed to read response body: %w", err)
}
data := &QuayError{}
err = json.Unmarshal(body, data)
if err != nil {
return false, fmt.Errorf("failed to unmarshal response body: %w", err)
}
if data.Error != "" {
return false, errors.New(data.Error)
}
return false, errors.New(data.ErrorMessage)

Check warning on line 189 in pkg/quay/quay.go

View check run for this annotation

Codecov / codecov/patch

pkg/quay/quay.go#L177-L189

Added lines #L177 - L189 were not covered by tests
}

// DeleteRepository deletes specified image repository.
func (c *QuayClient) DeleteRepository(organization, imageRepository string) (bool, error) {
url := fmt.Sprintf("%s/repository/%s/%s", c.url, organization, imageRepository)
Expand Down
15 changes: 15 additions & 0 deletions pkg/quay/quay_debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ func TestDeleteRepository(t *testing.T) {
}
}

func TestIsRepositoryPublic(t *testing.T) {
if quayToken == "" {
return
}
quayClient := NewQuayClient(&http.Client{Transport: &http.Transport{}}, quayToken, quayApiUrl)
isPublic, err := quayClient.IsRepositoryPublic(quayOrgName, quayImageRepoName)
if isPublic && err == nil {
t.Log("Repository is public")
} else if isPublic == false && err == nil {
t.Log("Repository is private")
} else {
t.Fatalf("Unexpected error: %s\n", err.Error())
}
}

func TestChangeRepositoryVisibility(t *testing.T) {
if quayToken == "" {
return
Expand Down
59 changes: 59 additions & 0 deletions pkg/quay/quay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,65 @@ func TestQuayClient_DoesRepositoryExist(t *testing.T) {
}
}

func TestQuayClient_IsRepositoryPublic(t *testing.T) {
defer gock.Off()

client := &http.Client{Transport: &http.Transport{}}
gock.InterceptClient(client)

quayClient := NewQuayClient(client, "authtoken", "https://quay.io/api/v1")

testCases := []struct {
name string
isPublic bool
err error
statusCode int
response []byte
}{
{
name: "Repository is public",
isPublic: true,
err: nil,
statusCode: 200,
response: []byte(`{"namespace": "test_org", "name": "test_repo", "kind": "image", "description": "Test repository", "is_public": true, "is_organization": true, "is_starred": false, "status_token": "", "trust_enabled": false, "tag_expiration_s": 1209600, "is_free_account": false, "state": "NORMAL", "tags": {}, "can_write": true, "can_admin": true}`),
},
{
name: "Repository is private",
isPublic: false,
err: nil,
statusCode: 200,
response: []byte(`{"namespace": "test_org", "name": "test_repo", "kind": "image", "description": "Test repository", "is_public": false, "is_organization": true, "is_starred": false, "status_token": "", "trust_enabled": false, "tag_expiration_s": 1209600, "is_free_account": false, "state": "NORMAL", "tags": {}, "can_write": true, "can_admin": true}`),
},
{
name: "Repository does not exist",
isPublic: false,
err: fmt.Errorf("repository %s does not exist in %s organization", repo, org),
statusCode: 404,
response: []byte(`{"detail": "Not Found", "error_message": "Not Found", "error_type": "not_found", "title": "not_found", "type": "https://quay.io/api/v1/error/not_found", "status": 404}`),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
gock.New("https://quay.io/api/v1").
MatchHeader("Content-Type", "application/json").
MatchHeader("Authorization", "Bearer authtoken").
Get(fmt.Sprintf("repository/%s/%s", org, repo)).
Reply(tc.statusCode).
JSON(tc.response)

isPublic, err := quayClient.IsRepositoryPublic(org, repo)
if isPublic != tc.isPublic {
t.Errorf("expected result to be `%t`, got `%t`", tc.isPublic, isPublic)
}
if (tc.err != nil && err == nil) || (tc.err == nil && err != nil) {
t.Errorf("expected error to be `%v`, got `%v`", tc.err, err)
}

})
}
}

func TestQuayClient_DeleteRepository(t *testing.T) {
defer gock.Off()

Expand Down

0 comments on commit 76e8b17

Please sign in to comment.