diff options
-rw-r--r-- | cmd/podman/images/trust_show.go | 16 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-trust.1.md | 114 | ||||
-rw-r--r-- | pkg/domain/infra/abi/trust.go | 20 | ||||
-rw-r--r-- | pkg/trust/config.go | 6 | ||||
-rw-r--r-- | pkg/trust/trust.go | 2 | ||||
-rw-r--r-- | test/e2e/trust_test.go | 29 | ||||
-rw-r--r-- | test/system/750-trust.bats | 46 | ||||
-rw-r--r-- | test/trust_set_test.json | 8 |
8 files changed, 197 insertions, 44 deletions
diff --git a/cmd/podman/images/trust_show.go b/cmd/podman/images/trust_show.go index bcb60e2b3..40c077d67 100644 --- a/cmd/podman/images/trust_show.go +++ b/cmd/podman/images/trust_show.go @@ -12,6 +12,7 @@ import ( ) var ( + noHeading bool showTrustDescription = "Display trust policy for the system" showTrustCommand = &cobra.Command{ Annotations: map[string]string{registry.EngineMode: registry.ABIMode}, @@ -40,6 +41,7 @@ func init() { showFlags.BoolVar(&showTrustOptions.Raw, "raw", false, "Output raw policy file") _ = showFlags.MarkHidden("policypath") showFlags.StringVar(&showTrustOptions.RegistryPath, "registrypath", "", "") + showFlags.BoolVarP(&noHeading, "noheading", "n", false, "Do not print column headings") _ = showFlags.MarkHidden("registrypath") } @@ -64,10 +66,22 @@ func showTrust(cmd *cobra.Command, args []string) error { rpt := report.New(os.Stdout, cmd.Name()) defer rpt.Flush() + hdrs := report.Headers(imageReporter{}, map[string]string{ + "Transport": "Transport", + "RepoName": "Name", + "Type": "Type", + "GPGId": "Id", + "SignatureStore": "Store", + }) rpt, err = rpt.Parse(report.OriginPodman, - "{{range . }}{{.RepoName}}\t{{.Type}}\t{{.GPGId}}\t{{.SignatureStore}}\n{{end -}}") + "{{range . }}{{.Transport}}\t{{.RepoName}}\t{{.Type}}\t{{.GPGId}}\t{{.SignatureStore}}\n{{end -}}") if err != nil { return err } + if !noHeading { + if err := rpt.Execute(hdrs); err != nil { + return err + } + } return rpt.Execute(trust.Policies) } diff --git a/docs/source/markdown/podman-image-trust.1.md b/docs/source/markdown/podman-image-trust.1.md index ba8d7fc2f..66d492922 100644 --- a/docs/source/markdown/podman-image-trust.1.md +++ b/docs/source/markdown/podman-image-trust.1.md @@ -40,6 +40,8 @@ Trust may be updated using the command **podman image trust set** for an existin #### **--help**, **-h** Print usage statement. +### set OPTIONS + #### **--pubkeysfile**=*KEY1*, **-f** A path to an exported public key on the local system. Key paths will be referenced in policy.json. Any path to a file may be used but locating the file in **/etc/pki/containers** is recommended. Options may be used multiple times to @@ -54,14 +56,17 @@ Trust may be updated using the command **podman image trust set** for an existin registry scope **reject**: do not accept images for this registry scope -## show OPTIONS - -#### **--raw** - Output trust policy file as raw JSON +### show OPTIONS #### **--json**, **-j** Output trust as JSON for machine parsing +#### **--noheading**, **-n** + Omit the table headings from the trust listings + +#### **--raw** + Output trust policy file as raw JSON + ## EXAMPLES Accept all unsigned images from a registry @@ -74,15 +79,110 @@ Modify default trust policy Display system trust policy - sudo podman image trust show + podman image trust show +``` +TRANSPORT NAME TYPE ID STORE +all default reject +repository docker.io/library accept +repository registry.access.redhat.com signed security@redhat.com https://access.redhat.com/webassets/docker/content/sigstore +repository registry.redhat.io signed security@redhat.com https://registry.redhat.io/containers/sigstore +repository docker.io reject +docker-daemon accept +``` Display trust policy file - sudo podman image trust show --raw + podman image trust show --raw +``` +{ + "default": [ + { + "type": "reject" + } + ], + "transports": { + "docker": { + "docker.io": [ + { + "type": "reject" + } + ], + "docker.io/library": [ + { + "type": "insecureAcceptAnything" + } + ], + "registry.access.redhat.com": [ + { + "type": "signedBy", + "keyType": "GPGKeys", + "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" + } + ], + "registry.redhat.io": [ + { + "type": "signedBy", + "keyType": "GPGKeys", + "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" + } + ] + }, + "docker-daemon": { + "": [ + { + "type": "insecureAcceptAnything" + } + ] + } + } +} +``` Display trust as JSON - sudo podman image trust show --json + podman image trust show --json +``` +[ + { + "transport": "all", + "name": "* (default)", + "repo_name": "default", + "type": "reject" + }, + { + "transport": "repository", + "name": "docker.io", + "repo_name": "docker.io", + "type": "reject" + }, + { + "transport": "repository", + "name": "docker.io/library", + "repo_name": "docker.io/library", + "type": "accept" + }, + { + "transport": "repository", + "name": "registry.access.redhat.com", + "repo_name": "registry.access.redhat.com", + "sigstore": "https://access.redhat.com/webassets/docker/content/sigstore", + "type": "signed", + "gpg_id": "security@redhat.com" + }, + { + "transport": "repository", + "name": "registry.redhat.io", + "repo_name": "registry.redhat.io", + "sigstore": "https://registry.redhat.io/containers/sigstore", + "type": "signed", + "gpg_id": "security@redhat.com" + }, + { + "transport": "docker-daemon", + "type": "accept" + } +] +``` ## SEE ALSO **[containers-policy.json(5)](https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md)** diff --git a/pkg/domain/infra/abi/trust.go b/pkg/domain/infra/abi/trust.go index 3777c1d3b..df4081349 100644 --- a/pkg/domain/infra/abi/trust.go +++ b/pkg/domain/infra/abi/trust.go @@ -122,18 +122,24 @@ func getPolicyShowOutput(policyContentStruct trust.PolicyContent, systemRegistri if len(policyContentStruct.Default) > 0 { defaultPolicyStruct := trust.Policy{ - Name: "* (default)", - RepoName: "default", - Type: trustTypeDescription(policyContentStruct.Default[0].Type), + Transport: "all", + Name: "* (default)", + RepoName: "default", + Type: trustTypeDescription(policyContentStruct.Default[0].Type), } output = append(output, &defaultPolicyStruct) } - for _, transval := range policyContentStruct.Transports { + for transport, transval := range policyContentStruct.Transports { + if transport == "docker" { + transport = "repository" + } + for repo, repoval := range transval { tempTrustShowOutput := trust.Policy{ - Name: repo, - RepoName: repo, - Type: repoval[0].Type, + Name: repo, + RepoName: repo, + Transport: transport, + Type: trustTypeDescription(repoval[0].Type), } // TODO - keyarr is not used and I don't know its intent; commenting out for now for someone to fix later //keyarr := []string{} diff --git a/pkg/trust/config.go b/pkg/trust/config.go index 164df2a90..6186d4cbd 100644 --- a/pkg/trust/config.go +++ b/pkg/trust/config.go @@ -2,11 +2,11 @@ package trust // Policy describes a basic trust policy configuration type Policy struct { - Name string `json:"name"` + Transport string `json:"transport"` + Name string `json:"name,omitempty"` RepoName string `json:"repo_name,omitempty"` Keys []string `json:"keys,omitempty"` - SignatureStore string `json:"sigstore"` - Transport string `json:"transport"` + SignatureStore string `json:"sigstore,omitempty"` Type string `json:"type"` GPGId string `json:"gpg_id,omitempty"` } diff --git a/pkg/trust/trust.go b/pkg/trust/trust.go index 584d1fa02..1d0cc61ba 100644 --- a/pkg/trust/trust.go +++ b/pkg/trust/trust.go @@ -21,7 +21,7 @@ import ( // PolicyContent struct for policy.json file type PolicyContent struct { Default []RepoContent `json:"default"` - Transports TransportsContent `json:"transports"` + Transports TransportsContent `json:"transports,omitempty"` } // RepoContent struct used under each repo diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go index 251fdbf77..d17e34e9c 100644 --- a/test/e2e/trust_test.go +++ b/test/e2e/trust_test.go @@ -39,7 +39,7 @@ var _ = Describe("Podman trust", func() { }) It("podman image trust show", func() { - session := podmanTest.Podman([]string{"image", "trust", "show", "--registrypath", filepath.Join(INTEGRATION_ROOT, "test"), "--policypath", filepath.Join(INTEGRATION_ROOT, "test/policy.json")}) + session := podmanTest.Podman([]string{"image", "trust", "show", "-n", "--registrypath", filepath.Join(INTEGRATION_ROOT, "test"), "--policypath", filepath.Join(INTEGRATION_ROOT, "test/policy.json")}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) outArray := session.OutputToStringArray() @@ -47,21 +47,18 @@ var _ = Describe("Podman trust", func() { // Repository order is not guaranteed. So, check that // all expected lines appear in output; we also check total number of lines, so that handles all of them. - Expect(string(session.Out.Contents())).To(MatchRegexp(`(?m)^default\s+accept\s*$`)) - Expect(string(session.Out.Contents())).To(MatchRegexp(`(?m)^docker.io/library/hello-world\s+reject\s*$`)) - Expect(string(session.Out.Contents())).To(MatchRegexp(`(?m)^registry.access.redhat.com\s+signedBy\s+security@redhat.com, security@redhat.com\s+https://access.redhat.com/webassets/docker/content/sigstore\s*$`)) + Expect(string(session.Out.Contents())).To(MatchRegexp(`(?m)^all\s+default\s+accept\s*$`)) + Expect(string(session.Out.Contents())).To(MatchRegexp(`(?m)^repository\s+docker.io/library/hello-world\s+reject\s*$`)) + Expect(string(session.Out.Contents())).To(MatchRegexp(`(?m)^repository\s+registry.access.redhat.com\s+signed\s+security@redhat.com, security@redhat.com\s+https://access.redhat.com/webassets/docker/content/sigstore\s*$`)) }) It("podman image trust set", func() { - path, err := os.Getwd() - if err != nil { - os.Exit(1) - } - session := podmanTest.Podman([]string{"image", "trust", "set", "--policypath", filepath.Join(filepath.Dir(path), "trust_set_test.json"), "-t", "accept", "default"}) + policyJSON := filepath.Join(podmanTest.TempDir, "trust_set_test.json") + session := podmanTest.Podman([]string{"image", "trust", "set", "--policypath", policyJSON, "-t", "accept", "default"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) var teststruct map[string][]map[string]string - policyContent, err := ioutil.ReadFile(filepath.Join(filepath.Dir(path), "trust_set_test.json")) + policyContent, err := ioutil.ReadFile(policyJSON) if err != nil { os.Exit(1) } @@ -88,25 +85,23 @@ var _ = Describe("Podman trust", func() { } Expect(repoMap).To(Equal(map[string][]map[string]string{ "* (default)": {{ + "type": "accept", + "transport": "all", "name": "* (default)", "repo_name": "default", - "sigstore": "", - "transport": "", - "type": "accept", }}, "docker.io/library/hello-world": {{ + "transport": "repository", "name": "docker.io/library/hello-world", "repo_name": "docker.io/library/hello-world", - "sigstore": "", - "transport": "", "type": "reject", }}, "registry.access.redhat.com": {{ + "transport": "repository", "name": "registry.access.redhat.com", "repo_name": "registry.access.redhat.com", "sigstore": "https://access.redhat.com/webassets/docker/content/sigstore", - "transport": "", - "type": "signedBy", + "type": "signed", "gpg_id": "security@redhat.com, security@redhat.com", }}, })) diff --git a/test/system/750-trust.bats b/test/system/750-trust.bats new file mode 100644 index 000000000..f06df35e7 --- /dev/null +++ b/test/system/750-trust.bats @@ -0,0 +1,46 @@ +#!/usr/bin/env bats -*- bats -*- +# +# tests for podman image trust +# + +load helpers + +@test "podman image trust set" { + skip_if_remote "trust only works locally" + policypath=$PODMAN_TMPDIR/policy.json + run_podman 125 image trust set --policypath=$policypath --type=bogus default + is "$output" "Error: invalid choice: bogus.*" "error from --type=bogus" + + run_podman image trust set --policypath=$policypath --type=accept default + run_podman image trust show --policypath=$policypath + is "$output" ".*all *default *accept" "default policy should be accept" + + run_podman image trust set --policypath=$policypath --type=reject default + run_podman image trust show --policypath=$policypath + is "$output" ".*all *default *reject" "default policy should be reject" + + run_podman image trust set --policypath=$policypath --type=reject docker.io + run_podman image trust show --policypath=$policypath + is "$output" ".*all *default *reject" "default policy should still be reject" + is "$output" ".*repository *docker.io *reject" "docker.io should also be reject" + + run_podman image trust show --policypath=$policypath --json + subset=$(jq -r '.[0] | .repo_name, .type' <<<"$output" | fmt) + is "$subset" "default reject" "--json also shows default" + subset=$(jq -r '.[1] | .repo_name, .type' <<<"$output" | fmt) + is "$subset" "docker.io reject" "--json also shows docker.io" + + run_podman image trust set --policypath=$policypath --type=accept docker.io + run_podman image trust show --policypath=$policypath --json + subset=$(jq -r '.[0] | .repo_name, .type' <<<"$output" | fmt) + is "$subset" "default reject" "--json, default is still reject" + subset=$(jq -r '.[1] | .repo_name, .type' <<<"$output" | fmt) + is "$subset" "docker.io accept" "--json, docker.io should now be accept" + + run cat $policypath + policy=$output + run_podman image trust show --policypath=$policypath --raw + is "$output" "$policy" "output should show match content of policy.json" +} + +# vim: filetype=sh diff --git a/test/trust_set_test.json b/test/trust_set_test.json deleted file mode 100644 index f1fdf779c..000000000 --- a/test/trust_set_test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "default": [ - { - "type": "insecureAcceptAnything" - } - ], - "transports": null -} |