Merge pull request #13247 from rhatdan/trust

Cleanup display of trust with transports
This commit is contained in:
OpenShift Merge Robot
2022-02-23 00:46:51 -05:00
committed by GitHub
8 changed files with 197 additions and 44 deletions

View File

@ -12,6 +12,7 @@ import (
) )
var ( var (
noHeading bool
showTrustDescription = "Display trust policy for the system" showTrustDescription = "Display trust policy for the system"
showTrustCommand = &cobra.Command{ showTrustCommand = &cobra.Command{
Annotations: map[string]string{registry.EngineMode: registry.ABIMode}, 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.BoolVar(&showTrustOptions.Raw, "raw", false, "Output raw policy file")
_ = showFlags.MarkHidden("policypath") _ = showFlags.MarkHidden("policypath")
showFlags.StringVar(&showTrustOptions.RegistryPath, "registrypath", "", "") showFlags.StringVar(&showTrustOptions.RegistryPath, "registrypath", "", "")
showFlags.BoolVarP(&noHeading, "noheading", "n", false, "Do not print column headings")
_ = showFlags.MarkHidden("registrypath") _ = showFlags.MarkHidden("registrypath")
} }
@ -64,10 +66,22 @@ func showTrust(cmd *cobra.Command, args []string) error {
rpt := report.New(os.Stdout, cmd.Name()) rpt := report.New(os.Stdout, cmd.Name())
defer rpt.Flush() 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, 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 { if err != nil {
return err return err
} }
if !noHeading {
if err := rpt.Execute(hdrs); err != nil {
return err
}
}
return rpt.Execute(trust.Policies) return rpt.Execute(trust.Policies)
} }

View File

@ -40,6 +40,8 @@ Trust may be updated using the command **podman image trust set** for an existin
#### **--help**, **-h** #### **--help**, **-h**
Print usage statement. Print usage statement.
### set OPTIONS
#### **--pubkeysfile**=*KEY1*, **-f** #### **--pubkeysfile**=*KEY1*, **-f**
A path to an exported public key on the local system. Key paths 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 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 registry scope
**reject**: do not accept images for this registry scope **reject**: do not accept images for this registry scope
## show OPTIONS ### show OPTIONS
#### **--raw**
Output trust policy file as raw JSON
#### **--json**, **-j** #### **--json**, **-j**
Output trust as JSON for machine parsing 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 ## EXAMPLES
Accept all unsigned images from a registry Accept all unsigned images from a registry
@ -74,15 +79,110 @@ Modify default trust policy
Display system 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 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 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 ## SEE ALSO
**[containers-policy.json(5)](https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md)** **[containers-policy.json(5)](https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md)**

View File

@ -122,18 +122,24 @@ func getPolicyShowOutput(policyContentStruct trust.PolicyContent, systemRegistri
if len(policyContentStruct.Default) > 0 { if len(policyContentStruct.Default) > 0 {
defaultPolicyStruct := trust.Policy{ defaultPolicyStruct := trust.Policy{
Name: "* (default)", Transport: "all",
RepoName: "default", Name: "* (default)",
Type: trustTypeDescription(policyContentStruct.Default[0].Type), RepoName: "default",
Type: trustTypeDescription(policyContentStruct.Default[0].Type),
} }
output = append(output, &defaultPolicyStruct) 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 { for repo, repoval := range transval {
tempTrustShowOutput := trust.Policy{ tempTrustShowOutput := trust.Policy{
Name: repo, Name: repo,
RepoName: repo, RepoName: repo,
Type: repoval[0].Type, 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 // TODO - keyarr is not used and I don't know its intent; commenting out for now for someone to fix later
//keyarr := []string{} //keyarr := []string{}

View File

@ -2,11 +2,11 @@ package trust
// Policy describes a basic trust policy configuration // Policy describes a basic trust policy configuration
type Policy struct { type Policy struct {
Name string `json:"name"` Transport string `json:"transport"`
Name string `json:"name,omitempty"`
RepoName string `json:"repo_name,omitempty"` RepoName string `json:"repo_name,omitempty"`
Keys []string `json:"keys,omitempty"` Keys []string `json:"keys,omitempty"`
SignatureStore string `json:"sigstore"` SignatureStore string `json:"sigstore,omitempty"`
Transport string `json:"transport"`
Type string `json:"type"` Type string `json:"type"`
GPGId string `json:"gpg_id,omitempty"` GPGId string `json:"gpg_id,omitempty"`
} }

View File

@ -21,7 +21,7 @@ import (
// PolicyContent struct for policy.json file // PolicyContent struct for policy.json file
type PolicyContent struct { type PolicyContent struct {
Default []RepoContent `json:"default"` Default []RepoContent `json:"default"`
Transports TransportsContent `json:"transports"` Transports TransportsContent `json:"transports,omitempty"`
} }
// RepoContent struct used under each repo // RepoContent struct used under each repo

View File

@ -39,7 +39,7 @@ var _ = Describe("Podman trust", func() {
}) })
It("podman image trust show", 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() session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0)) Expect(session).Should(Exit(0))
outArray := session.OutputToStringArray() outArray := session.OutputToStringArray()
@ -47,21 +47,18 @@ var _ = Describe("Podman trust", func() {
// Repository order is not guaranteed. So, check that // 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. // 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)^all\s+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)^repository\s+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)^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() { It("podman image trust set", func() {
path, err := os.Getwd() policyJSON := filepath.Join(podmanTest.TempDir, "trust_set_test.json")
if err != nil { session := podmanTest.Podman([]string{"image", "trust", "set", "--policypath", policyJSON, "-t", "accept", "default"})
os.Exit(1)
}
session := podmanTest.Podman([]string{"image", "trust", "set", "--policypath", filepath.Join(filepath.Dir(path), "trust_set_test.json"), "-t", "accept", "default"})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0)) Expect(session).Should(Exit(0))
var teststruct map[string][]map[string]string 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 { if err != nil {
os.Exit(1) os.Exit(1)
} }
@ -88,25 +85,23 @@ var _ = Describe("Podman trust", func() {
} }
Expect(repoMap).To(Equal(map[string][]map[string]string{ Expect(repoMap).To(Equal(map[string][]map[string]string{
"* (default)": {{ "* (default)": {{
"type": "accept",
"transport": "all",
"name": "* (default)", "name": "* (default)",
"repo_name": "default", "repo_name": "default",
"sigstore": "",
"transport": "",
"type": "accept",
}}, }},
"docker.io/library/hello-world": {{ "docker.io/library/hello-world": {{
"transport": "repository",
"name": "docker.io/library/hello-world", "name": "docker.io/library/hello-world",
"repo_name": "docker.io/library/hello-world", "repo_name": "docker.io/library/hello-world",
"sigstore": "",
"transport": "",
"type": "reject", "type": "reject",
}}, }},
"registry.access.redhat.com": {{ "registry.access.redhat.com": {{
"transport": "repository",
"name": "registry.access.redhat.com", "name": "registry.access.redhat.com",
"repo_name": "registry.access.redhat.com", "repo_name": "registry.access.redhat.com",
"sigstore": "https://access.redhat.com/webassets/docker/content/sigstore", "sigstore": "https://access.redhat.com/webassets/docker/content/sigstore",
"transport": "", "type": "signed",
"type": "signedBy",
"gpg_id": "security@redhat.com, security@redhat.com", "gpg_id": "security@redhat.com, security@redhat.com",
}}, }},
})) }))

View File

@ -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

View File

@ -1,8 +0,0 @@
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports": null
}