Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beskar-yum: Add a sync handler that accepts a URL with credentials #29

Merged
merged 2 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build/mage/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ func getChartsSource(client *dagger.Client) *dagger.Directory {
func goCache(client *dagger.Client) func(dc *dagger.Container) *dagger.Container {
return func(dc *dagger.Container) *dagger.Container {
return dc.
WithMountedCache("/go", client.CacheVolume("go-mod-cache"), dagger.ContainerWithMountedCacheOpts{Sharing: dagger.Shared}).
WithMountedCache("/root/.cache", client.CacheVolume("go-build-cache"), dagger.ContainerWithMountedCacheOpts{Sharing: dagger.Shared})
WithMountedCache("/go", client.CacheVolume("go-mod-cache"), dagger.ContainerWithMountedCacheOpts{Sharing: dagger.Locked}).
WithMountedCache("/root/.cache", client.CacheVolume("go-build-cache"), dagger.ContainerWithMountedCacheOpts{Sharing: dagger.Locked})
}
}

Expand Down
16 changes: 16 additions & 0 deletions integration/beskar_yum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,22 @@ var _ = Describe("Beskar YUM Plugin", func() {
Expect(status.EndTime).ToNot(BeEmpty())
})

It("Sync Repository With URL", func() {
err := beskarYUMClient().SyncRepositoryWithURL(context.Background(), repositoryAPIName, repo.AuthMirrorURL, true)
Expect(err).To(BeNil())
})

It("Sync Status", func() {
status, err := beskarYUMClient().GetRepositorySyncStatus(context.Background(), repositoryAPIName)
Expect(err).To(BeNil())
Expect(status.Syncing).To(BeFalse())
Expect(status.SyncError).To(BeEmpty())
Expect(status.SyncedPackages).To(Equal(len(repo.Files)))
Expect(status.TotalPackages).To(Equal(len(repo.Files)))
Expect(status.StartTime).ToNot(BeEmpty())
Expect(status.EndTime).ToNot(BeEmpty())
})

It("Access Repository Artifacts", func() {
for filename := range repo.Files {
info, ok := repo.Files[filename]
Expand Down
25 changes: 25 additions & 0 deletions integration/main_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
_ "embed"
"fmt"
"net/http"
"net/url"
"os"
"os/exec"
"syscall"
Expand Down Expand Up @@ -38,6 +39,17 @@ func TestSubstrateIntegration(t *testing.T) {
RunSpecs(t, "Beskar Integration Test Suite")
}

func auth(username, password string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, p, ok := r.BasicAuth()
if !ok || username != u || password != p {
http.Error(w, "401 unauthorized", http.StatusUnauthorized)
}

h.ServeHTTP(w, r)
})
}

var _ = SynchronizedBeforeSuite(
// NOTE: This runs *only* on process #1 when run in parallel
func() []byte {
Expand All @@ -61,6 +73,19 @@ var _ = SynchronizedBeforeSuite(
fs := http.FileServer(http.Dir(repo.LocalPath))
pathPrefix := fmt.Sprintf("/%s/", name)
mux.Handle(pathPrefix, http.StripPrefix(pathPrefix, fs))

if repo.AuthMirrorURL != "" {
u, err := url.Parse(repo.AuthMirrorURL)
if err != nil {
continue
}

username := u.User.Username()
password, _ := u.User.Password()

pathPrefix := fmt.Sprintf("/auth/%s/", name)
mux.Handle(pathPrefix, auth(username, password, http.StripPrefix(pathPrefix, fs)))
}
}
}

Expand Down
11 changes: 6 additions & 5 deletions integration/pkg/repoconfig/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ type File struct {
}

type Repository struct {
URL string `yaml:"url"`
LocalPath string `yaml:"local-path"`
MirrorURL string `yaml:"mirror-url"`
GPGKey string `yaml:"gpgkey"`
Files map[string]File `yaml:"files"`
URL string `yaml:"url"`
LocalPath string `yaml:"local-path"`
MirrorURL string `yaml:"mirror-url"`
AuthMirrorURL string `yaml:"auth-mirror-url"`
GPGKey string `yaml:"gpgkey"`
Files map[string]File `yaml:"files"`
}

type Repositories map[string]Repository
Expand Down
1 change: 1 addition & 0 deletions integration/testdata/repoconfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ vault-rocky-8.3-ha-debug:
local-path: testdata/vault-rocky-8.3-ha-debug
url: http://127.0.0.1:8080/vault-rocky-8.3-ha-debug/Packages
mirror-url: http://127.0.0.1:8080/vault-rocky-8.3-ha-debug
auth-mirror-url: http://test:[email protected]:8080/auth/vault-rocky-8.3-ha-debug
gpgkey: |
-----BEGIN PGP PUBLIC KEY BLOCK-----

Expand Down
7 changes: 7 additions & 0 deletions internal/plugins/yum/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ func (p *Plugin) SyncRepository(ctx context.Context, repository string, wait boo
return p.repositoryManager.Get(ctx, repository).SyncRepository(ctx, wait)
}

func (p *Plugin) SyncRepositoryWithURL(ctx context.Context, repository, url string, wait bool) (err error) {
if err := checkRepository(repository); err != nil {
return err
}
return p.repositoryManager.Get(ctx, repository).SyncRepositoryWithURL(ctx, url, wait)
}

func (p *Plugin) GetRepositorySyncStatus(ctx context.Context, repository string) (syncStatus *apiv1.SyncStatus, err error) {
if err := checkRepository(repository); err != nil {
return nil, err
Expand Down
33 changes: 33 additions & 0 deletions internal/plugins/yum/pkg/yumrepository/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,39 @@ func (h *Handler) SyncRepository(_ context.Context, wait bool) (err error) {
return nil
}

func (h *Handler) SyncRepositoryWithURL(_ context.Context, url string, wait bool) (err error) {
if !h.Started() {
return werror.Wrap(gcode.ErrUnavailable, err)
} else if !h.getMirror() {
return werror.Wrap(gcode.ErrFailedPrecondition, errors.New("repository not setup as a mirror"))
} else if err := h.setMirrorURLs([]string{url}); err != nil {
return werror.Wrap(gcode.ErrInternal, err)
} else if h.delete.Load() {
return werror.Wrap(gcode.ErrAlreadyExists, fmt.Errorf("repository %s is being deleted", h.Repository))
} else if h.syncing.Swap(true) {
return werror.Wrap(gcode.ErrAlreadyExists, errors.New("a repository sync is already running"))
}

var waitErrCh chan error

if wait {
waitErrCh = make(chan error, 1)
}

select {
case h.syncCh <- waitErrCh:
if waitErrCh != nil {
if err := <-waitErrCh; err != nil {
return werror.Wrap(gcode.ErrInternal, fmt.Errorf("synchronization failed: %w", err))
}
}
default:
return werror.Wrap(gcode.ErrUnavailable, errors.New("something goes wrong"))
}

return nil
}

func (h *Handler) GetRepositorySyncStatus(context.Context) (syncStatus *apiv1.SyncStatus, err error) {
reposync := h.getReposync()
return &apiv1.SyncStatus{
Expand Down
5 changes: 5 additions & 0 deletions pkg/plugins/yum/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ type YUM interface { //nolint:interfacebloat
//kun:success statusCode=200
SyncRepository(ctx context.Context, repository string, wait bool) (err error)

// Sync YUM repository with an upstream repository using a specified URL.
//kun:op GET /repository/sync:url
//kun:success statusCode=200
SyncRepositoryWithURL(ctx context.Context, repository, mirrorURL string, wait bool) (err error)

// Get YUM repository sync status.
//kun:op GET /repository/sync:status
//kun:success statusCode=200
Expand Down
39 changes: 39 additions & 0 deletions pkg/plugins/yum/api/v1/endpoint.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions pkg/plugins/yum/api/v1/http.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions pkg/plugins/yum/api/v1/http_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions pkg/plugins/yum/api/v1/oas2.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.