mirror of
https://github.com/containers/podman.git
synced 2025-09-25 07:44:24 +08:00
Merge pull request #13247 from rhatdan/trust
Cleanup display of trust with transports
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
@ -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)**
|
||||
|
@ -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{}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
}},
|
||||
}))
|
||||
|
46
test/system/750-trust.bats
Normal file
46
test/system/750-trust.bats
Normal 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
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"default": [
|
||||
{
|
||||
"type": "insecureAcceptAnything"
|
||||
}
|
||||
],
|
||||
"transports": null
|
||||
}
|
Reference in New Issue
Block a user