Skip to content

Commit

Permalink
Merge pull request #35 from stacklok/k8s-and-compose
Browse files Browse the repository at this point in the history
Add `kubernetes` and `docker-compose` sub-commands
  • Loading branch information
JAORMX committed Dec 12, 2023
2 parents 52c1435 + 72dfb94 commit 1cefc1e
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 35 deletions.
36 changes: 6 additions & 30 deletions cmd/containerimage/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (

"github.com/spf13/cobra"

intcmd "github.com/stacklok/frizbee/internal/cmd"
"github.com/stacklok/frizbee/pkg/config"
cliutils "github.com/stacklok/frizbee/pkg/utils/cli"
)

// CmdYAML represents the yaml sub-command
Expand All @@ -41,28 +41,14 @@ Example:
}

// flags
cmd.Flags().StringP("dir", "d", ".", "workflows directory")
cmd.Flags().StringP("image-regex", "i", "image", "regex to match container image references")

cliutils.DeclareReplacerFlags(cmd)
intcmd.DeclareYAMLReplacerFlags(cmd)

return cmd
}

func replaceYAML(cmd *cobra.Command, _ []string) error {
dir := cmd.Flag("dir").Value.String()
dryRun, err := cmd.Flags().GetBool("dry-run")
if err != nil {
return fmt.Errorf("failed to get dry-run flag: %w", err)
}
errOnModified, err := cmd.Flags().GetBool("error")
if err != nil {
return fmt.Errorf("failed to get error flag: %w", err)
}
quiet, err := cmd.Flags().GetBool("quiet")
if err != nil {
return fmt.Errorf("failed to get quiet flag: %w", err)
}
cfg, err := config.FromContext(cmd.Context())
if err != nil {
return fmt.Errorf("failed to get config from context: %w", err)
Expand All @@ -72,20 +58,10 @@ func replaceYAML(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("failed to get image-regex flag: %w", err)
}

dir = cliutils.ProcessDirNameForBillyFS(dir)

ctx := cmd.Context()

replacer := &yamlReplacer{
Replacer: cliutils.Replacer{
Dir: dir,
DryRun: dryRun,
Quiet: quiet,
ErrOnModified: errOnModified,
Cmd: cmd,
},
imageRegex: ir,
replacer, err := intcmd.NewYAMLReplacer(cmd, intcmd.WithImageRegex(ir))
if err != nil {
return err
}

return replacer.do(ctx, cfg)
return replacer.Do(cmd.Context(), cfg)
}
62 changes: 62 additions & 0 deletions cmd/dockercompose/dockercompose.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2023 Stacklok, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package dockercompose provides command-line utilities to work with container images.
package dockercompose

import (
"fmt"

"github.com/spf13/cobra"

intcmd "github.com/stacklok/frizbee/internal/cmd"
"github.com/stacklok/frizbee/pkg/config"
)

// CmdCompose represents the compose yaml sub-command
func CmdCompose() *cobra.Command {
cmd := &cobra.Command{
Use: "docker-compose",
Aliases: []string{"dockercompose", "compose"},
Short: "Replace container image references with checksums in docker-compose YAML files",
Long: `This utility replaces a tag or branch reference in a container image references
with the digest hash of the referenced tag in docker-compose YAML files.
Example:
$ frizbee docker-compose --dir . --dry-run --quiet --error
`,
RunE: replaceYAML,
SilenceUsage: true,
}

// flags
intcmd.DeclareYAMLReplacerFlags(cmd)

return cmd
}

func replaceYAML(cmd *cobra.Command, _ []string) error {
cfg, err := config.FromContext(cmd.Context())
if err != nil {
return fmt.Errorf("failed to get config from context: %w", err)
}

replacer, err := intcmd.NewYAMLReplacer(cmd)
if err != nil {
return err
}

return replacer.Do(cmd.Context(), cfg)
}
68 changes: 68 additions & 0 deletions cmd/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2023 Stacklok, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package kubernetes provides command-line utilities to work with kubernetes manifests.
package kubernetes

import (
"fmt"

"github.com/spf13/cobra"

intcmd "github.com/stacklok/frizbee/internal/cmd"
"github.com/stacklok/frizbee/pkg/config"
)

// CmdK8s represents the k8s yaml sub-command
func CmdK8s() *cobra.Command {
cmd := &cobra.Command{
Use: "kubernetes",
Aliases: []string{"k8s"},
Short: "Replace container image references with checksums in kubernetes YAML files",
Long: `This utility replaces a tag or branch reference in a container image references
with the digest hash of the referenced tag in YAML files.
Example:
$ frizbee kubernetes --dir . --dry-run --quiet --error
`,
RunE: replaceYAML,
SilenceUsage: true,
}

// flags
cmd.Flags().StringP("image-regex", "i", "image", "regex to match container image references")

intcmd.DeclareYAMLReplacerFlags(cmd)

return cmd
}

func replaceYAML(cmd *cobra.Command, _ []string) error {
cfg, err := config.FromContext(cmd.Context())
if err != nil {
return fmt.Errorf("failed to get config from context: %w", err)
}
ir, err := cmd.Flags().GetString("image-regex")
if err != nil {
return fmt.Errorf("failed to get image-regex flag: %w", err)
}

replacer, err := intcmd.NewYAMLReplacer(cmd, intcmd.WithImageRegex(ir))
if err != nil {
return err
}

return replacer.Do(cmd.Context(), cfg)
}
4 changes: 4 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import (
"github.com/spf13/cobra"

"github.com/stacklok/frizbee/cmd/containerimage"
"github.com/stacklok/frizbee/cmd/dockercompose"
"github.com/stacklok/frizbee/cmd/ghactions"
"github.com/stacklok/frizbee/cmd/kubernetes"
"github.com/stacklok/frizbee/pkg/config"
)

Expand All @@ -40,6 +42,8 @@ func Execute() {

rootCmd.AddCommand(ghactions.CmdGHActions())
rootCmd.AddCommand(containerimage.CmdContainerImage())
rootCmd.AddCommand(dockercompose.CmdCompose())
rootCmd.AddCommand(kubernetes.CmdK8s())

if err := rootCmd.ExecuteContext(context.Background()); err != nil {
os.Exit(1)
Expand Down
17 changes: 17 additions & 0 deletions internal/cmd/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Copyright 2023 Stacklok, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package cmd provide common implementations for commands
package cmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package containerimage
package cmd

import (
"bytes"
Expand All @@ -24,6 +24,7 @@ import (
"sync/atomic"

"github.com/go-git/go-billy/v5/osfs"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"

"github.com/stacklok/frizbee/pkg/config"
Expand All @@ -32,12 +33,64 @@ import (
cliutils "github.com/stacklok/frizbee/pkg/utils/cli"
)

type yamlReplacer struct {
// DeclareYAMLReplacerFlags declares the flags for the YAML replacer
func DeclareYAMLReplacerFlags(cli *cobra.Command) {
cli.Flags().StringP("dir", "d", ".", "manifests file or directory")

cliutils.DeclareReplacerFlags(cli)
}

// YAMLReplacer replaces container image references in YAML files
type YAMLReplacer struct {
cliutils.Replacer
imageRegex string
ImageRegex string
}

// WithImageRegex sets the image regex
func WithImageRegex(regex string) func(*YAMLReplacer) {
return func(r *YAMLReplacer) {
r.ImageRegex = regex
}
}

// NewYAMLReplacer creates a new YAMLReplacer from the given
// command-line arguments and options
func NewYAMLReplacer(cli *cobra.Command, opts ...func(*YAMLReplacer)) (*YAMLReplacer, error) {
dir := cli.Flag("dir").Value.String()
dryRun, err := cli.Flags().GetBool("dry-run")
if err != nil {
return nil, fmt.Errorf("failed to get dry-run flag: %w", err)
}
errOnModified, err := cli.Flags().GetBool("error")
if err != nil {
return nil, fmt.Errorf("failed to get error flag: %w", err)
}
quiet, err := cli.Flags().GetBool("quiet")
if err != nil {
return nil, fmt.Errorf("failed to get quiet flag: %w", err)
}

dir = cliutils.ProcessDirNameForBillyFS(dir)

r := &YAMLReplacer{
Replacer: cliutils.Replacer{
Dir: dir,
DryRun: dryRun,
Quiet: quiet,
ErrOnModified: errOnModified,
Cmd: cli,
},
ImageRegex: "image",
}
for _, opt := range opts {
opt(r)
}

return r, nil
}

func (r *yamlReplacer) do(ctx context.Context, _ *config.Config) error {
// Do runs the YAMLReplacer
func (r *YAMLReplacer) Do(ctx context.Context, _ *config.Config) error {
basedir := filepath.Dir(r.Dir)
base := filepath.Base(r.Dir)
// NOTE: For some reason using boundfs causes a panic when trying to open a file.
Expand Down Expand Up @@ -69,7 +122,7 @@ func (r *yamlReplacer) do(ctx context.Context, _ *config.Config) error {
r.Logf("Processing %s\n", path)

buf := bytes.Buffer{}
m, err := containers.ReplaceReferenceFromYAMLWithCache(ctx, r.imageRegex, f, &buf, cache)
m, err := containers.ReplaceReferenceFromYAMLWithCache(ctx, r.ImageRegex, f, &buf, cache)
if err != nil {
return fmt.Errorf("failed to process YAML file %s: %w", path, err)
}
Expand Down

0 comments on commit 1cefc1e

Please sign in to comment.