Skip to content

Commit

Permalink
refactor: mirror-resources
Browse files Browse the repository at this point in the history
Signed-off-by: Philip Laine <philip.laine@gmail.com>
  • Loading branch information
phillebaba committed Sep 11, 2024
1 parent efa306f commit 94e3aea
Show file tree
Hide file tree
Showing 8 changed files with 802 additions and 16 deletions.
46 changes: 31 additions & 15 deletions src/cmd/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,30 @@ import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"

"github.com/zarf-dev/zarf/src/cmd/common"
"github.com/zarf-dev/zarf/src/config/lang"
"github.com/zarf-dev/zarf/src/pkg/lint"
"github.com/zarf-dev/zarf/src/pkg/message"
"github.com/zarf-dev/zarf/src/pkg/packager/sources"
"github.com/zarf-dev/zarf/src/types"

"oras.land/oras-go/v2/registry"

"github.com/AlecAivazis/survey/v2"
"github.com/defenseunicorns/pkg/helpers/v2"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/zarf-dev/zarf/src/config"
"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/packager"
"oras.land/oras-go/v2/registry"

"github.com/zarf-dev/zarf/src/cmd/common"
"github.com/zarf-dev/zarf/src/config/lang"
"github.com/zarf-dev/zarf/src/internal/dns"
"github.com/zarf-dev/zarf/src/internal/packager2"
"github.com/zarf-dev/zarf/src/pkg/lint"
"github.com/zarf-dev/zarf/src/pkg/message"
"github.com/zarf-dev/zarf/src/pkg/packager/filters"
"github.com/zarf-dev/zarf/src/pkg/packager/sources"
"github.com/zarf-dev/zarf/src/types"
)

var packageCmd = &cobra.Command{
Expand Down Expand Up @@ -113,18 +117,30 @@ var packageMirrorCmd = &cobra.Command{
Example: lang.CmdPackageMirrorExample,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
packageSource, err := choosePackage(args)
var c *cluster.Cluster
if dns.IsServiceURL(pkgConfig.InitOpts.RegistryInfo.Address) || dns.IsServiceURL(pkgConfig.InitOpts.GitServer.Address) {
var err error
c, err = cluster.NewCluster()
if err != nil {
return err
}
}
src, err := choosePackage(args)
if err != nil {
return err
}
pkgConfig.PkgOpts.PackageSource = packageSource
pkgClient, err := packager.New(&pkgConfig)
filter := filters.Combine(
filters.ByLocalOS(runtime.GOOS),
filters.BySelectState(pkgConfig.PkgOpts.OptionalComponents),
)
pkgPaths, err := packager2.LoadPackageFromSource(cmd.Context(), src, pkgConfig.PkgOpts.Shasum, pkgConfig.PkgOpts.PublicKeyPath, filter)
if err != nil {
return err
}
defer pkgClient.ClearTempPaths()
if err := pkgClient.Mirror(cmd.Context()); err != nil {
return fmt.Errorf("failed to mirror package: %w", err)
defer os.Remove(pkgPaths.Base)
err = packager2.Mirror(cmd.Context(), c, *pkgPaths, pkgConfig.InitOpts.RegistryInfo, pkgConfig.InitOpts.GitServer, pkgConfig.MirrorOpts.NoImgChecksum, pkgConfig.PkgOpts.Retries)
if err != nil {
return err
}
return nil
},
Expand Down
45 changes: 45 additions & 0 deletions src/internal/dns/dns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors

// Package dns contains DNS related functionality.
package dns

import (
"errors"
"fmt"
"net/url"
"regexp"
"strconv"
)

var (
// localClusterServiceRegex is used to match the local cluster service format:
localClusterServiceRegex = regexp.MustCompile(`^(?P<name>[^\.]+)\.(?P<namespace>[^\.]+)\.svc\.cluster\.local$`)
)

// IsServiceURL returns true if the give url complies with the service url format.
func IsServiceURL(serviceURL string) bool {
_, _, _, err := ParseServiceURL(serviceURL)
return err == nil
}

// ParseServiceURL takes a serviceURL and parses it to find the service info for connecting to the cluster. The string is expected to follow the following format:
// Example serviceURL: http://{SERVICE_NAME}.{NAMESPACE}.svc.cluster.local:{PORT}.
func ParseServiceURL(serviceURL string) (string, string, int, error) {
parsedURL, err := url.Parse(serviceURL)
if err != nil {
return "", "", 0, err
}
if parsedURL.Port() == "" {
return "", "", 0, errors.New("service url does not have a port")
}
remotePort, err := strconv.Atoi(parsedURL.Port())
if err != nil {
return "", "", 0, err
}
matches := localClusterServiceRegex.FindStringSubmatch(parsedURL.Hostname())
if len(matches) != 3 {
return "", "", 0, fmt.Errorf("invalid service url %s", serviceURL)
}
return matches[2], matches[1], remotePort, nil
}
84 changes: 84 additions & 0 deletions src/internal/dns/dns_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors

package dns

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestIsServiceURL(t *testing.T) {
t.Parallel()

tests := []struct {
name string
serviceURL string
expected bool
}{
{
name: "is service url",
serviceURL: "http://registry.zarf.svc.cluster.local:1",
expected: true,
},
{
name: "is not service url",
serviceURL: "https://zarf.dev",
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

result := IsServiceURL(tt.serviceURL)
require.Equal(t, tt.expected, result)
})
}
}

func TestParseServiceURL(t *testing.T) {
t.Parallel()

tests := []struct {
name string
serviceURL string
expectedErr string
expectedNamespace string
expectedName string
expectedPort int
}{
{
name: "correct service url",
serviceURL: "http://foo.bar.svc.cluster.local:5000",
expectedNamespace: "bar",
expectedName: "foo",
expectedPort: 5000,
},
{
name: "invalid service url without port",
serviceURL: "http://google.com",
expectedErr: "service url does not have a port",
},
{
name: "invalid service url with port",
serviceURL: "http://google.com:3000",
expectedErr: "invalid service url http://google.com:3000",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

namespace, name, port, err := ParseServiceURL(tt.serviceURL)
if tt.expectedErr != "" {
require.EqualError(t, err, tt.expectedErr)
return
}
require.Equal(t, tt.expectedNamespace, namespace)
require.Equal(t, tt.expectedName, name)
require.Equal(t, tt.expectedPort, port)
})
}
}
Loading

0 comments on commit 94e3aea

Please sign in to comment.