From eade10ae0e0d3436b146cc2c942387c26cbbfd5c Mon Sep 17 00:00:00 2001 From: Ashutosh Narkar Date: Wed, 1 Nov 2023 16:32:36 -0700 Subject: [PATCH] build: Remove rootless image variant All published OPA images now run with a non-root uid/gid. The uid:gid is set to 1000:1000 for all images. As a result there is no longer a need for the --rootless image variant hence it will not be published as part of future releases. This change is in line with container security best practices. OPA can still be run with root privileges by explicitly setting the user, either with the --user argument for docker run, or by specifying the securityContext in the Kubernetes Pod specification. Fixes: #4295 Signed-off-by: Ashutosh Narkar --- Dockerfile | 7 - Makefile | 16 --- cmd/commands.go | 13 -- cmd/internal/deprecation/rootless.go | 54 -------- cmd/internal/deprecation/warning.go | 92 ------------- cmd/internal/deprecation/warning_test.go | 163 ----------------------- 6 files changed, 345 deletions(-) delete mode 100644 cmd/internal/deprecation/rootless.go delete mode 100644 cmd/internal/deprecation/warning.go delete mode 100644 cmd/internal/deprecation/warning_test.go diff --git a/Dockerfile b/Dockerfile index 667b7286f2..9a894e85ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,13 +9,6 @@ FROM ${BASE} LABEL org.opencontainers.image.authors="Torin Sandall " LABEL org.opencontainers.image.source="https://github.com/open-policy-agent/opa" - -# Temporarily allow us to identify whether running from within an offical -# Docker image with a "rootless" tag, so that we may print a warning that this image tag -# will not be published after 0.50.0. Remove after 0.50.0 release. -ARG OPA_DOCKER_IMAGE_TAG -ENV OPA_DOCKER_IMAGE_TAG=${OPA_DOCKER_IMAGE_TAG} - # Any non-zero number will do, and unfortunately a named user will not, as k8s # pod securityContext runAsNonRoot can't resolve the user ID: # https://github.com/kubernetes/kubernetes/issues/40958. diff --git a/Makefile b/Makefile index 7c6a891d2d..1d21015dae 100644 --- a/Makefile +++ b/Makefile @@ -341,13 +341,6 @@ ifneq ($(GOARCH),arm64) # build only static images for arm64 --build-arg BIN_DIR=$(RELEASE_DIR) \ --platform linux/$* \ . - $(DOCKER) build \ - -t $(DOCKER_IMAGE):$(VERSION)-rootless \ - --build-arg OPA_DOCKER_IMAGE_TAG=rootless \ - --build-arg BASE=cgr.dev/chainguard/glibc-dynamic:latest \ - --build-arg BIN_DIR=$(RELEASE_DIR) \ - --platform linux/$* \ - . endif $(DOCKER) build \ -t $(DOCKER_IMAGE):$(VERSION)-static \ @@ -384,15 +377,6 @@ push-manifest-list-%: ensure-executable-bin --provenance=false \ --push \ . - $(DOCKER) buildx build \ - --tag $(DOCKER_IMAGE):$*-rootless \ - --build-arg OPA_DOCKER_IMAGE_TAG=rootless \ - --build-arg BASE=cgr.dev/chainguard/glibc-dynamic:latest \ - --build-arg BIN_DIR=$(RELEASE_DIR) \ - --platform $(DOCKER_PLATFORMS) \ - --provenance=false \ - --push \ - . $(DOCKER) buildx build \ --tag $(DOCKER_IMAGE):$*-static \ diff --git a/cmd/commands.go b/cmd/commands.go index 0453ffc04d..31f2204552 100644 --- a/cmd/commands.go +++ b/cmd/commands.go @@ -9,8 +9,6 @@ import ( "path" "github.com/spf13/cobra" - - "github.com/open-policy-agent/opa/cmd/internal/deprecation" ) // RootCommand is the base CLI command that all subcommands are added to. @@ -18,15 +16,4 @@ var RootCommand = &cobra.Command{ Use: path.Base(os.Args[0]), Short: "Open Policy Agent (OPA)", Long: "An open source project to policy-enable your service.", - PersistentPreRun: func(cmd *cobra.Command, args []string) { - - message, fatal := deprecation.CheckWarnings(os.Environ(), cmd.Use) - if message != "" { - cmd.PrintErr(message) - if fatal { - os.Exit(1) - } - } - - }, } diff --git a/cmd/internal/deprecation/rootless.go b/cmd/internal/deprecation/rootless.go deleted file mode 100644 index 0b4311706d..0000000000 --- a/cmd/internal/deprecation/rootless.go +++ /dev/null @@ -1,54 +0,0 @@ -package deprecation - -// TODO: these warnings can be removed when the rootless images are no longer published. - -const rootlessWarningMessage = `OPA appears to be running in a deprecated -rootless image. -Since v0.50.0, the default OPA images have been configured to use a non-root -user. - -This image will soon cease to be updated. The following images should now be -used instead: - -* openpolicyagent/opa:latest and NOT (openpolicyagent/opa:latest-rootless) -* openpolicyagent/opa:edge and NOT (openpolicyagent/opa:edge-rootless) -* openpolicyagent/opa:X.Y.Z and NOT (openpolicyagent/opa:X.Y.Z-rootless) - -You can choose to acknowledge and ignore this message by unsetting: -OPA_DOCKER_IMAGE_TAG=rootless -` - -// warningRootless is a fatal warning is triggered when the user is running OPA -// in a deprecated rootless image. -var warningRootless = warning{ - MatchEnv: func(env []string) bool { - for _, e := range env { - if e == "OPA_DOCKER_IMAGE_TAG=rootless" { - return true - } - } - return false - }, - MatchCommand: func(name string) bool { - return name != "run" - }, - Fatal: true, - Message: rootlessWarningMessage, -} - -// warningRootlessRun is a non-fatal version of the warning reserved for opa run. -// The warning for run is non-fatal to avoid production disruption -var warningRootlessRun = warning{ - MatchEnv: func(env []string) bool { - for _, e := range env { - if e == "OPA_DOCKER_IMAGE_TAG=rootless" { - return true - } - } - return false - }, - MatchCommand: func(name string) bool { - return name == "run" - }, - Fatal: false, - Message: rootlessWarningMessage, -} diff --git a/cmd/internal/deprecation/warning.go b/cmd/internal/deprecation/warning.go deleted file mode 100644 index dbc848dc6d..0000000000 --- a/cmd/internal/deprecation/warning.go +++ /dev/null @@ -1,92 +0,0 @@ -package deprecation - -import ( - "bytes" - "fmt" - "io" - "strings" -) - -const width, border = 80, 3 -const titleChar, dividerChar = "#", "-" - -// warning is a struct which can be used to define deprecation warnings based on -// the environment and command being run. -type warning struct { - MatchEnv func([]string) bool - MatchCommand func(string) bool - Fatal bool - Message string -} - -// CheckWarnings runs messageForWarnings with a default set of real warnings. -func CheckWarnings(env []string, command string) (string, bool) { - warnings := []warning{ - warningRootless, - warningRootlessRun, - } - - return messageForWarnings(warnings, env, command) -} - -// messageForWarnings returns an obnoxious banner with the contents of all firing warnings. -// If no warnings fire, it returns an empty string. -// If any warnings are fatal, it returns true for the second return value. -func messageForWarnings(warnings []warning, env []string, command string) (string, bool) { - var messages []string - var fatal bool - - for _, w := range warnings { - if w.MatchEnv(env) && w.MatchCommand(command) { - messages = append(messages, w.Message) - if w.Fatal { - fatal = true - } - } - } - - buf := bytes.NewBuffer(nil) - - if len(messages) == 0 { - return "", false - } - - title := "Deprecation Warnings" - if fatal { - title = "Fatal Deprecation Warnings" - } - - printFormattedTitle(buf, title) - - for i, msg := range messages { - fmt.Fprintln(buf, strings.TrimSpace(msg)) - if i < len(messages)-1 { - printFormattedDivider(buf) - } - } - - printFormattedTitle(buf, "end "+title) - - return buf.String(), fatal -} - -func printFormattedTitle(out io.Writer, title string) { - padding := (width - len(title) - border*2) / 2 - - fmt.Fprintln(out, strings.Repeat(titleChar, width)) - fmt.Fprintln(out, - strings.Join( - []string{ - strings.Repeat(titleChar, border), - strings.Repeat(" ", padding), strings.ToUpper(title), strings.Repeat(" ", padding), - strings.Repeat(titleChar, border), - }, - "", - ), - ) - fmt.Fprintln(out, strings.Repeat(titleChar, width)) -} - -func printFormattedDivider(out io.Writer) { - fmt.Fprintln(out, strings.Repeat(dividerChar, width)) -} diff --git a/cmd/internal/deprecation/warning_test.go b/cmd/internal/deprecation/warning_test.go deleted file mode 100644 index e9caac41bc..0000000000 --- a/cmd/internal/deprecation/warning_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package deprecation - -import ( - "testing" -) - -func TestMessageForWarnings(t *testing.T) { - testCases := map[string]struct { - Env []string - Command string - Warnings []warning - ExpectedMessage string - ExpectedFatal bool - }{ - "warning that does not fire": { - Env: []string{"OPA_FOOBAR=1"}, - Command: "foobar", - Warnings: []warning{ - { - MatchEnv: func(env []string) bool { - return false - }, - MatchCommand: func(command string) bool { - return false - }, - Fatal: true, - Message: "fatal warning", - }, - }, - ExpectedFatal: false, - ExpectedMessage: "", - }, - "warning that fires": { - Env: []string{"OPA_FOOBAR=1"}, - Command: "foobar", - Warnings: []warning{ - { - MatchEnv: func(env []string) bool { - for _, e := range env { - if e == "OPA_FOOBAR=1" { - return true - } - } - return false - }, - MatchCommand: func(command string) bool { - return command == "foobar" - }, - Fatal: true, - Message: "fatal warning for foobar", - }, - }, - ExpectedMessage: `################################################################################ -### FATAL DEPRECATION WARNINGS ### -################################################################################ -fatal warning for foobar -################################################################################ -### END FATAL DEPRECATION WARNINGS ### -################################################################################ -`, - ExpectedFatal: true, - }, - "two warnings that fire, one fatally": { - Env: []string{"OPA_FOOBAR=1"}, - Command: "foobar", - Warnings: []warning{ - { - MatchEnv: func(env []string) bool { - for _, e := range env { - if e == "OPA_FOOBAR=1" { - return true - } - } - return false - }, - MatchCommand: func(command string) bool { - return command == "foobar" - }, - Fatal: true, - Message: "fatal warning for foobar", - }, - { - MatchEnv: func(env []string) bool { - return true - }, - MatchCommand: func(command string) bool { - return command == "foobar" - }, - Fatal: false, - Message: "non fatal warning for foobar", - }, - }, - ExpectedMessage: `################################################################################ -### FATAL DEPRECATION WARNINGS ### -################################################################################ -fatal warning for foobar --------------------------------------------------------------------------------- -non fatal warning for foobar -################################################################################ -### END FATAL DEPRECATION WARNINGS ### -################################################################################ -`, - ExpectedFatal: true, - }, - "two warnings that fire, neither fatally": { - Env: []string{"OPA_FOOBAR=1"}, - Command: "foobar", - Warnings: []warning{ - { - MatchEnv: func(env []string) bool { - for _, e := range env { - if e == "OPA_FOOBAR=1" { - return true - } - } - return false - }, - MatchCommand: func(command string) bool { - return command == "foobar" - }, - Fatal: false, - Message: "warning for foobar", - }, - { - MatchEnv: func(env []string) bool { - return true - }, - MatchCommand: func(command string) bool { - return command == "foobar" - }, - Fatal: false, - Message: "another warning for foobar", - }, - }, - ExpectedMessage: `################################################################################ -### DEPRECATION WARNINGS ### -################################################################################ -warning for foobar --------------------------------------------------------------------------------- -another warning for foobar -################################################################################ -### END DEPRECATION WARNINGS ### -################################################################################ -`, - ExpectedFatal: false, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - message, fatal := messageForWarnings(tc.Warnings, tc.Env, tc.Command) - - if fatal != tc.ExpectedFatal { - t.Errorf("Expected fatal to be %v but got %v", tc.ExpectedFatal, fatal) - } - - if message != tc.ExpectedMessage { - t.Errorf("Expected message\n%s\nbut got\n%s", tc.ExpectedMessage, message) - } - - }) - } -}