Skip to content

Commit f0d65cc

Browse files
author
David Collom
committed
Adding support for GHCR custom domains for using Github Enterprise
1 parent c803505 commit f0d65cc

File tree

12 files changed

+96
-29
lines changed

12 files changed

+96
-29
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bin
2+
coverage.out
3+
*.md
4+
.git

cmd/app/options.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
envGCRAccessToken = "GCR_TOKEN"
3838

3939
envGHCRAccessToken = "GHCR_TOKEN"
40+
envGHCRHostname = "GHCR_HOSTNAME"
4041

4142
envQuayToken = "QUAY_TOKEN"
4243

@@ -207,6 +208,12 @@ func (o *Options) addAuthFlags(fs *pflag.FlagSet) {
207208
"Personal Access token for read access to GHCR releases (%s_%s).",
208209
envPrefix, envGHCRAccessToken,
209210
))
211+
fs.StringVar(&o.Client.GHCR.Hostname,
212+
"gchr-hostname", "",
213+
fmt.Sprintf(
214+
"Override hostname for Github Enterprise instances (%s_%s).",
215+
envPrefix, envGHCRHostname,
216+
))
210217
///
211218

212219
/// Quay
@@ -291,6 +298,7 @@ func (o *Options) complete() {
291298
{envGCRAccessToken, &o.Client.GCR.Token},
292299

293300
{envGHCRAccessToken, &o.Client.GHCR.Token},
301+
{envGHCRHostname, &o.Client.GHCR.Hostname},
294302

295303
{envQuayToken, &o.Client.Quay.Token},
296304
} {

deploy/charts/version-checker/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ A Helm chart for version-checker
3434
| extraVolumeMounts | list | `[]` | Allow for extra Volume Mounts to version-checkers container |
3535
| extraVolumes | list | `[]` | Allow for extra Volumes to be associated to the pod |
3636
| gcr.token | string | `nil` | Access token for read access to private GCR registries |
37+
| ghcr.hostname | string | `nil` | Hostname for Github Enterprise to override the default ghcr domains. |
3738
| ghcr.token | string | `nil` | Personal Access token for read access to GHCR releases |
3839
| image.imagePullSecret | string | `nil` | Pull secrects - name of existing secret |
3940
| image.pullPolicy | string | `"IfNotPresent"` | Set the Image Pull Policy |

deploy/charts/version-checker/templates/secret.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
{{- if or .Values.acr.refreshToken .Values.acr.username .Values.acr.password .Values.docker.token .Values.ecr.accessKeyID .Values.ecr.secretAccessKey .Values.ecr.sessionToken .Values.docker.username .Values.docker.password .Values.gcr.token .Values.ghcr.token .Values.quay.token (not (eq (len .Values.selfhosted) 0)) }}
1+
{{- if or .Values.acr.refreshToken .Values.acr.username .Values.acr.password .Values.docker.token .Values.ecr.accessKeyID .Values.ecr.secretAccessKey .Values.ecr.sessionToken .Values.docker.username .Values.docker.password .Values.gcr.token .Values.ghcr.token .Values.ghcr.hostname .Values.quay.token (not (eq (len .Values.selfhosted) 0)) }}
2+
---
23
apiVersion: v1
34
data:
45
# ACR
@@ -43,6 +44,9 @@ data:
4344
{{- if .Values.ghcr.token }}
4445
ghcr.token: {{ .Values.ghcr.token | b64enc }}
4546
{{- end}}
47+
{{- if .Values.ghcr.hostname }}
48+
ghcr.hostname: {{ .Values.ghcr.hostname | b64enc }}
49+
{{- end}}
4650

4751
# Quay
4852
{{- if .Values.quay.token }}

deploy/charts/version-checker/values.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ gcr:
8888
ghcr:
8989
# -- (string) Personal Access token for read access to GHCR releases
9090
token:
91+
# -- (string) Hostname for Github Enterprise to override the default ghcr domains.
92+
hostname:
9193

9294
# Quay.io Registry Credentials Configuration
9395
quay:

pkg/client/docker/docker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func (c *Client) doRequest(ctx context.Context, url string) (*TagResponse, error
138138

139139
resp, err := c.Do(req)
140140
if err != nil {
141-
return nil, fmt.Errorf("failed to get docker image: %s", err)
141+
return nil, fmt.Errorf("failed to get %q image: %s", c.Name(), err)
142142
}
143143
defer resp.Body.Close()
144144

pkg/client/gcr/gcr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func (c *Client) Tags(ctx context.Context, host, repo, image string) ([]api.Imag
5858

5959
resp, err := c.Do(req)
6060
if err != nil {
61-
return nil, fmt.Errorf("failed to get docker image: %w", err)
61+
return nil, fmt.Errorf("failed to get %q image: %w", c.Name(), err)
6262
}
6363
defer resp.Body.Close()
6464

pkg/client/ghcr/ghcr.go

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import (
66
"net/url"
77
"strings"
88

9-
"github.com/gofri/go-github-ratelimit/github_ratelimit"
10-
"github.com/google/go-github/v62/github"
119
"github.com/jetstack/version-checker/pkg/api"
10+
11+
"github.com/gofri/go-github-ratelimit/github_ratelimit"
12+
"github.com/google/go-github/v70/github"
1213
)
1314

1415
type Options struct {
15-
Token string
16+
Token string
17+
Hostname string
1618
}
1719

1820
type Client struct {
@@ -32,6 +34,12 @@ func New(opts Options) *Client {
3234
panic(err)
3335
}
3436
client := github.NewClient(ghRateLimiter).WithAuthToken(opts.Token)
37+
if opts.Hostname != "" {
38+
client, err = client.WithEnterpriseURLs(fmt.Sprintf("https://%s/", opts.Hostname), fmt.Sprintf("https://%s/api/uploads/", opts.Hostname))
39+
if err != nil {
40+
panic(fmt.Errorf("setting enterprise URLs: %w", err))
41+
}
42+
}
3543

3644
return &Client{
3745
client: client,
@@ -87,8 +95,8 @@ func (c *Client) determineGetAllVersionsFunc(ctx context.Context, owner, repo st
8795

8896
func (c *Client) buildPackageListOptions() *github.PackageListOptions {
8997
return &github.PackageListOptions{
90-
PackageType: github.String("container"),
91-
State: github.String("active"),
98+
PackageType: github.Ptr("container"),
99+
State: github.Ptr("active"),
92100
ListOptions: github.ListOptions{
93101
PerPage: 100,
94102
},
@@ -98,25 +106,28 @@ func (c *Client) buildPackageListOptions() *github.PackageListOptions {
98106
func (c *Client) extractImageTags(versions []*github.PackageVersion) []api.ImageTag {
99107
var tags []api.ImageTag
100108
for _, ver := range versions {
101-
if len(ver.Metadata.Container.Tags) == 0 {
102-
continue
103-
}
109+
if meta, ok := ver.GetMetadata(); ok {
104110

105-
sha := ""
106-
if strings.HasPrefix(*ver.Name, "sha") {
107-
sha = *ver.Name
108-
}
109-
110-
for _, tag := range ver.Metadata.Container.Tags {
111-
if c.shouldSkipTag(tag) {
111+
if len(meta.Container.Tags) == 0 {
112112
continue
113113
}
114114

115-
tags = append(tags, api.ImageTag{
116-
Tag: tag,
117-
SHA: sha,
118-
Timestamp: ver.CreatedAt.Time,
119-
})
115+
sha := ""
116+
if strings.HasPrefix(*ver.Name, "sha") {
117+
sha = *ver.Name
118+
}
119+
120+
for _, tag := range meta.Container.Tags {
121+
if c.shouldSkipTag(tag) {
122+
continue
123+
}
124+
125+
tags = append(tags, api.ImageTag{
126+
Tag: tag,
127+
SHA: sha,
128+
Timestamp: ver.CreatedAt.Time,
129+
})
130+
}
120131
}
121132
}
122133
return tags

pkg/client/ghcr/ghcr_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"net/http"
66
"testing"
77

8-
"github.com/google/go-github/v62/github"
8+
"github.com/google/go-github/v70/github"
99
"github.com/jarcoal/httpmock"
1010
"github.com/stretchr/testify/assert"
1111
)

pkg/client/ghcr/path.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
package ghcr
22

33
import (
4+
"regexp"
45
"strings"
56
)
67

8+
const (
9+
HostRegTempl = `^(containers\.[a-zA-Z0-9-]+\.ghe\.com|ghcr\.io)$`
10+
)
11+
12+
var HostReg = regexp.MustCompile(HostRegTempl)
13+
714
func (c *Client) IsHost(host string) bool {
815
// Package API requires Authentication
916
// This forces the Client to use the fallback method
1017
if c.opts.Token == "" {
1118
return false
1219
}
13-
return host == "ghcr.io"
20+
// If we're using a custom hostname.
21+
if c.opts.Hostname != "" && c.opts.Hostname == host {
22+
return true
23+
}
24+
return HostReg.MatchString(host)
1425
}
1526

1627
func (c *Client) RepoImageFromPath(path string) (string, string) {

0 commit comments

Comments
 (0)