Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Commit

Permalink
add: ImageAllowRules Prompt for autoupgrade patterns (#1698) (#1905)
Browse files Browse the repository at this point in the history
  • Loading branch information
iwilltry42 committed Jul 11, 2023
1 parent 4ed75e7 commit 14bbc0d
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 22 deletions.
19 changes: 13 additions & 6 deletions pkg/autoupgrade/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func findLatestTagForImageWithPattern(ctx context.Context, c daemonClient, curre
if newTag == "" {
newTag = invalidTag
}

var notAllowedErr error // denote that we found a tag that is not allowed by IAR rules

newImage := strings.TrimPrefix(ref.Context().Tag(newTag).Name(), defaultNoReg+"/")
for len(tags) > 0 {
nTag, err := FindLatest(newTag, pattern, tags)
Expand All @@ -55,19 +58,23 @@ func findLatestTagForImageWithPattern(ctx context.Context, c daemonClient, curre
break
}
img := strings.TrimPrefix(ref.Context().Tag(nTag).Name(), defaultNoReg+"/")
if err := c.checkImageAllowed(ctx, namespace, img); err != nil {
if notAllowedErr = c.checkImageAllowed(ctx, namespace, img); notAllowedErr != nil {
// remove the tag from the list and try again
tags = slices.Filter(nil, tags, func(tag string) bool { return tag != nTag })
} else {
// found a valid tag that is allowed by all rules, so use it
newTag = nTag
newImage = img
break
continue
}

// found a valid tag that is allowed by all rules, so use it
newTag = nTag
newImage = img
break
}

// no new image needs to be returned since no new tags were found
if newTag == invalidTag {
if notAllowedErr != nil {
return "", false, notAllowedErr
}
return "", false, err
}

Expand Down
17 changes: 17 additions & 0 deletions pkg/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (
cli "github.com/acorn-io/runtime/pkg/cli/builder"
"github.com/acorn-io/runtime/pkg/client"
"github.com/acorn-io/runtime/pkg/dev"
"github.com/acorn-io/runtime/pkg/imageallowrules"
"github.com/acorn-io/runtime/pkg/imagesource"
"github.com/acorn-io/runtime/pkg/rulerequest"
"github.com/acorn-io/runtime/pkg/wait"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
apierror "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -287,6 +289,21 @@ func (s *Run) Run(cmd *cobra.Command, args []string) (err error) {

image, deployArgs, err := imageSource.GetImageAndDeployArgs(cmd.Context(), c)
if err != nil {
if naErr := client.TranslateNotAllowed(err); naErr != nil {
if _, isPattern := autoupgrade.AutoUpgradePattern(image); isPattern {
naErr.(*imageallowrules.ErrImageNotAllowed).Image = image
logrus.Debugf("Valid tags for pattern %s were not allowed to run: %v", image, naErr)
if choice, promptErr := rulerequest.HandleNotAllowed(s.Dangerous, image); promptErr != nil {
return promptErr
} else if choice != "NO" {
iarErr := rulerequest.CreateImageAllowRule(cmd.Context(), c, image, choice)
if iarErr != nil {
return iarErr
}
return s.Run(cmd, args)
}
}
}
return err
}
opts.DeployArgs = deployArgs
Expand Down
4 changes: 2 additions & 2 deletions pkg/client/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,14 @@ func translateErr(err error) error {
return e
}

if e := translateNotAllowed(err); e != nil {
if e := TranslateNotAllowed(err); e != nil {
return e
}

return err
}

func translateNotAllowed(err error) error {
func TranslateNotAllowed(err error) error {
if err == nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package imageallowrules
package util

import (
"fmt"
"strings"

v1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
"github.com/acorn-io/runtime/pkg/autoupgrade"
imagename "github.com/google/go-containerregistry/pkg/name"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand All @@ -19,12 +20,18 @@ const (
)

func GenerateSimpleAllowRule(namespace string, name string, image string, scope string) (*v1.ImageAllowRule, error) {
pattern, isPattern := autoupgrade.AutoUpgradePattern(image)

if isPattern {
image = strings.TrimRight(image, ":"+pattern)
}

ref, err := imagename.ParseReference(image, imagename.WithDefaultTag(""), imagename.WithDefaultRegistry(""))
if err != nil {
return nil, fmt.Errorf("error parsing image: %w", err)
}

is, err := buildImageScope(ref, scope)
is, err := buildImageScope(ref, scope, pattern)
if err != nil {
return nil, err
}
Expand All @@ -38,7 +45,7 @@ func GenerateSimpleAllowRule(namespace string, name string, image string, scope
}, nil
}

func buildImageScope(image imagename.Reference, scope string) (string, error) {
func buildImageScope(image imagename.Reference, scope, tagPattern string) (string, error) {
var is string

switch SimpleImageScope(scope) {
Expand All @@ -48,6 +55,9 @@ func buildImageScope(image imagename.Reference, scope string) (string, error) {
is = fmt.Sprintf("%s/%s:**", image.Context().RegistryStr(), image.Context().RepositoryStr())
case SimpleImageScopeExact:
is = strings.TrimSuffix(image.Name(), ":")
if tagPattern != "" {
is = image.Context().Tag(tagPattern).Name()
}
case SimpleImageScopeAll:
is = "**"
default:
Expand Down
23 changes: 12 additions & 11 deletions pkg/rulerequest/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/acorn-io/runtime/pkg/cli/builder/table"
"github.com/acorn-io/runtime/pkg/client"
"github.com/acorn-io/runtime/pkg/imageallowrules"
iarutil "github.com/acorn-io/runtime/pkg/imageallowrules/util"
"github.com/acorn-io/runtime/pkg/images"
"github.com/acorn-io/runtime/pkg/prompt"
"github.com/acorn-io/runtime/pkg/run"
Expand Down Expand Up @@ -44,10 +45,10 @@ func handleNotAllowedError(ctx context.Context, c client.Client, dangerous bool,
}

// Prompt user to create an simple IAR for this image
if choice, promptErr := handleNotAllowed(dangerous, image); promptErr != nil {
if choice, promptErr := HandleNotAllowed(dangerous, image); promptErr != nil {
return nil, fmt.Errorf("%s: %w", promptErr.Error(), err)
} else if choice != "NO" {
iarErr := createImageAllowRule(ctx, c, image, choice, existingImgName) // existingImgName to ensure that this exact image ID is allowed in addition to whatever pattern we're allowing
iarErr := CreateImageAllowRule(ctx, c, image, choice, existingImgName) // existingImgName to ensure that this exact image ID is allowed in addition to whatever pattern we're allowing
if iarErr != nil {
return nil, iarErr
}
Expand Down Expand Up @@ -133,9 +134,9 @@ application. If you are unsure say no.`)
return prompt.Bool("Do you want to allow this app to have these (POTENTIALLY DANGEROUS) permissions?", false)
}

func handleNotAllowed(dangerous bool, image string) (string, error) {
func HandleNotAllowed(dangerous bool, image string) (string, error) {
if dangerous {
return string(imageallowrules.SimpleImageScopeExact), nil
return string(iarutil.SimpleImageScopeExact), nil
}

pterm.Warning.Printfln(
Expand All @@ -157,7 +158,7 @@ application. If you are unsure say no.`, image)

choiceMap = map[string]string{
choices[0]: "NO",
choices[1]: string(imageallowrules.SimpleImageScopeExact),
choices[1]: string(iarutil.SimpleImageScopeExact),
}
} else {
choices = []string{
Expand All @@ -170,10 +171,10 @@ application. If you are unsure say no.`, image)

choiceMap = map[string]string{
choices[0]: "NO",
choices[1]: string(imageallowrules.SimpleImageScopeExact),
choices[2]: string(imageallowrules.SimpleImageScopeRepository),
choices[3]: string(imageallowrules.SimpleImageScopeRegistry),
choices[4]: string(imageallowrules.SimpleImageScopeAll),
choices[1]: string(iarutil.SimpleImageScopeExact),
choices[2]: string(iarutil.SimpleImageScopeRepository),
choices[3]: string(iarutil.SimpleImageScopeRegistry),
choices[4]: string(iarutil.SimpleImageScopeAll),
}
}

Expand All @@ -182,8 +183,8 @@ application. If you are unsure say no.`, image)
return choiceMap[choice], err
}

func createImageAllowRule(ctx context.Context, c client.Client, image, choice string, extraExactMatches ...string) error {
iar, err := imageallowrules.GenerateSimpleAllowRule(c.GetProject(), run.NameGenerator.Generate(), image, choice)
func CreateImageAllowRule(ctx context.Context, c client.Client, image, choice string, extraExactMatches ...string) error {
iar, err := iarutil.GenerateSimpleAllowRule(c.GetProject(), run.NameGenerator.Generate(), image, choice)
if err != nil {
return fmt.Errorf("error generating ImageAllowRule: %w", err)
}
Expand Down

0 comments on commit 14bbc0d

Please sign in to comment.