Skip to content

Commit b74cacb

Browse files
committed
refactor: mirror-resources
Signed-off-by: Philip Laine <[email protected]>
1 parent 5e0a331 commit b74cacb

File tree

9 files changed

+702
-32
lines changed

9 files changed

+702
-32
lines changed

src/cmd/package.go

+29-16
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,27 @@ import (
1111
"os"
1212
"path/filepath"
1313
"regexp"
14+
"runtime"
1415
"strings"
1516

17+
"github.com/AlecAivazis/survey/v2"
18+
"github.com/defenseunicorns/pkg/helpers/v2"
19+
"github.com/spf13/cobra"
20+
"github.com/spf13/viper"
21+
"oras.land/oras-go/v2/registry"
22+
1623
"github.com/zarf-dev/zarf/src/cmd/common"
24+
"github.com/zarf-dev/zarf/src/config"
1725
"github.com/zarf-dev/zarf/src/config/lang"
26+
"github.com/zarf-dev/zarf/src/internal/dns"
1827
"github.com/zarf-dev/zarf/src/internal/packager2"
28+
"github.com/zarf-dev/zarf/src/pkg/cluster"
1929
"github.com/zarf-dev/zarf/src/pkg/lint"
2030
"github.com/zarf-dev/zarf/src/pkg/message"
31+
"github.com/zarf-dev/zarf/src/pkg/packager"
2132
"github.com/zarf-dev/zarf/src/pkg/packager/filters"
2233
"github.com/zarf-dev/zarf/src/pkg/packager/sources"
2334
"github.com/zarf-dev/zarf/src/types"
24-
25-
"oras.land/oras-go/v2/registry"
26-
27-
"github.com/AlecAivazis/survey/v2"
28-
"github.com/defenseunicorns/pkg/helpers/v2"
29-
"github.com/spf13/cobra"
30-
"github.com/spf13/viper"
31-
"github.com/zarf-dev/zarf/src/config"
32-
"github.com/zarf-dev/zarf/src/pkg/cluster"
33-
"github.com/zarf-dev/zarf/src/pkg/packager"
3435
)
3536

3637
var packageCmd = &cobra.Command{
@@ -128,18 +129,30 @@ var packageMirrorCmd = &cobra.Command{
128129
}
129130
},
130131
RunE: func(cmd *cobra.Command, args []string) error {
131-
packageSource, err := choosePackage(args)
132+
var c *cluster.Cluster
133+
if dns.IsServiceURL(pkgConfig.InitOpts.RegistryInfo.Address) || dns.IsServiceURL(pkgConfig.InitOpts.GitServer.Address) {
134+
var err error
135+
c, err = cluster.NewCluster()
136+
if err != nil {
137+
return err
138+
}
139+
}
140+
src, err := choosePackage(args)
132141
if err != nil {
133142
return err
134143
}
135-
pkgConfig.PkgOpts.PackageSource = packageSource
136-
pkgClient, err := packager.New(&pkgConfig)
144+
filter := filters.Combine(
145+
filters.ByLocalOS(runtime.GOOS),
146+
filters.BySelectState(pkgConfig.PkgOpts.OptionalComponents),
147+
)
148+
pkgPaths, err := packager2.LoadPackage(cmd.Context(), src, pkgConfig.PkgOpts.Shasum, pkgConfig.PkgOpts.PublicKeyPath, pkgConfig.PkgOpts.SkipSignatureValidation, filter)
137149
if err != nil {
138150
return err
139151
}
140-
defer pkgClient.ClearTempPaths()
141-
if err := pkgClient.Mirror(cmd.Context()); err != nil {
142-
return fmt.Errorf("failed to mirror package: %w", err)
152+
defer os.Remove(pkgPaths.Base)
153+
err = packager2.Mirror(cmd.Context(), c, *pkgPaths, filter, pkgConfig.InitOpts.RegistryInfo, pkgConfig.InitOpts.GitServer, pkgConfig.MirrorOpts.NoImgChecksum, pkgConfig.PkgOpts.Retries)
154+
if err != nil {
155+
return err
143156
}
144157
return nil
145158
},

src/internal/dns/dns.go

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors
3+
4+
// Package dns contains DNS related functionality.
5+
package dns
6+
7+
import (
8+
"errors"
9+
"fmt"
10+
"net/url"
11+
"regexp"
12+
"strconv"
13+
)
14+
15+
var (
16+
// localClusterServiceRegex is used to match the local cluster service format:
17+
localClusterServiceRegex = regexp.MustCompile(`^(?P<name>[^\.]+)\.(?P<namespace>[^\.]+)\.svc\.cluster\.local$`)
18+
)
19+
20+
// IsServiceURL returns true if the give url complies with the service url format.
21+
func IsServiceURL(serviceURL string) bool {
22+
_, _, _, err := ParseServiceURL(serviceURL)
23+
return err == nil
24+
}
25+
26+
// 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:
27+
// Example serviceURL: http://{SERVICE_NAME}.{NAMESPACE}.svc.cluster.local:{PORT}.
28+
func ParseServiceURL(serviceURL string) (string, string, int, error) {
29+
parsedURL, err := url.Parse(serviceURL)
30+
if err != nil {
31+
return "", "", 0, err
32+
}
33+
if parsedURL.Port() == "" {
34+
return "", "", 0, errors.New("service url does not have a port")
35+
}
36+
remotePort, err := strconv.Atoi(parsedURL.Port())
37+
if err != nil {
38+
return "", "", 0, err
39+
}
40+
matches := localClusterServiceRegex.FindStringSubmatch(parsedURL.Hostname())
41+
if len(matches) != 3 {
42+
return "", "", 0, fmt.Errorf("invalid service url %s", serviceURL)
43+
}
44+
return matches[2], matches[1], remotePort, nil
45+
}

src/internal/dns/dns_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors
3+
4+
package dns
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestIsServiceURL(t *testing.T) {
13+
t.Parallel()
14+
15+
tests := []struct {
16+
name string
17+
serviceURL string
18+
expected bool
19+
}{
20+
{
21+
name: "is service url",
22+
serviceURL: "http://registry.zarf.svc.cluster.local:1",
23+
expected: true,
24+
},
25+
{
26+
name: "is not service url",
27+
serviceURL: "https://zarf.dev",
28+
expected: false,
29+
},
30+
}
31+
for _, tt := range tests {
32+
t.Run(tt.name, func(t *testing.T) {
33+
t.Parallel()
34+
35+
result := IsServiceURL(tt.serviceURL)
36+
require.Equal(t, tt.expected, result)
37+
})
38+
}
39+
}
40+
41+
func TestParseServiceURL(t *testing.T) {
42+
t.Parallel()
43+
44+
tests := []struct {
45+
name string
46+
serviceURL string
47+
expectedErr string
48+
expectedNamespace string
49+
expectedName string
50+
expectedPort int
51+
}{
52+
{
53+
name: "correct service url",
54+
serviceURL: "http://foo.bar.svc.cluster.local:5000",
55+
expectedNamespace: "bar",
56+
expectedName: "foo",
57+
expectedPort: 5000,
58+
},
59+
{
60+
name: "invalid service url without port",
61+
serviceURL: "http://google.com",
62+
expectedErr: "service url does not have a port",
63+
},
64+
{
65+
name: "invalid service url with port",
66+
serviceURL: "http://google.com:3000",
67+
expectedErr: "invalid service url http://google.com:3000",
68+
},
69+
}
70+
for _, tt := range tests {
71+
t.Run(tt.name, func(t *testing.T) {
72+
t.Parallel()
73+
74+
namespace, name, port, err := ParseServiceURL(tt.serviceURL)
75+
if tt.expectedErr != "" {
76+
require.EqualError(t, err, tt.expectedErr)
77+
return
78+
}
79+
require.Equal(t, tt.expectedNamespace, namespace)
80+
require.Equal(t, tt.expectedName, name)
81+
require.Equal(t, tt.expectedPort, port)
82+
})
83+
}
84+
}

0 commit comments

Comments
 (0)