Skip to content

Commit

Permalink
Verify images built for upstream projects
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandr Demicev <[email protected]>
  • Loading branch information
alexander-demicev committed Dec 6, 2024
1 parent 6c0550e commit 2114b22
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 16 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ The cosign verification of Rancher Prime images can be done with:
slsactl verify <prime_image>:<tag>
```

Images built for upstream projects can be verified with(currently only Cluster API):

```bash
slsactl verify upstream --certIdentityWorkflow=<workflow_name> <prime_image>:<tag>
```

See Rancher Turtles docs for workflow names for respective projects.

## License
Copyright (c) 2014-2024 [Rancher Labs, Inc.](http://rancher.com)

Expand Down
12 changes: 11 additions & 1 deletion actions/verify/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# - uses: rancherlabs/slsactl/actions/verify@main
# with:
# image: <registry>/<image>:<tag>
# certIdentityWorkflow: <workflow-name>

name: verify

Expand All @@ -20,6 +21,10 @@ inputs:
<registry>/<repo>/<image>:<tag>.
required: true
type: string
certIdentityWorkflow:
description: |
The workflow name to run for cert identity verification(only for images built for upstream projects).
default: ""

runs:
using: composite
Expand All @@ -37,6 +42,11 @@ runs:
- name: Verify image
shell: bash
run: |
slsactl verify ${{ env.IMAGE }}
if [[ -n "${{ env.CERT_IDENTITY_WORKFLOW }}" ]]; then
slsactl verify upstream --certIdentityWorkflow="${{ env.CERT_IDENTITY_WORKFLOW }}" ${{ env.IMAGE }}
else
slsactl verify ${{ env.IMAGE }}
fi
env:
IMAGE: ${{ inputs.image }}
CERT_IDENTITY_WORKFLOW: ${{ inputs.certIdentityWorkflow }}
31 changes: 27 additions & 4 deletions cmd/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,41 @@ const verifyf = `usage:
%[1]s verify <IMAGE>
`

var (
certIdentityWorkflow string
upstreamImageType string
)

func verifyCmd(args []string) error {
f := flag.NewFlagSet("", flag.ContinueOnError)
err := f.Parse(args)
if err != nil {

if err := f.Parse(args); err != nil {
return err
}

if len(f.Args()) != 1 {
if len(f.Args()) == 0 || len(f.Args()) > 3 {
showVerifyUsage()
}

err = verify.Verify(f.Arg(0))
switch f.Arg(0) {
case "upstream":
f.StringVar(&certIdentityWorkflow, "certIdentityWorkflow", "",
"The workflow used to generate the certificate identity, see relevant Rancher documentation for more information.")

f.StringVar(&upstreamImageType, "upstreamImageType", "cluster-api",
"The type of upstream image to verify, currently only 'cluster-api' is supported.")

if err := f.Parse(args[1:]); err != nil {
return err
}

if certIdentityWorkflow == "" {
fmt.Println("certIdentityWorkflow is required")
showVerifyUsage()
}
}

err := verify.Verify(f.Arg(0), upstreamImageType, certIdentityWorkflow)
if err != nil {
fmt.Printf("cannot validate image %s: ensure you are using an image from the Prime registry\n", f.Arg(0))
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/verify/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ var imageRepo = map[string]string{
"rancher/nginx-ingress-controller": "rancher/ingress-nginx",
"rancher/rancher": "rancher/rancher-prime",
}

var upstreamImagesRepos = map[string]string{
"cluster-api": "rancher/clusterapi-forks",
}
19 changes: 12 additions & 7 deletions pkg/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ var archSuffixes = []string{
//
// Upstream documentation:
// https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md
func Verify(imageName string) error {
func Verify(imageName, upstreamImageType, workflowName string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

certIdentity, err := certIdentity(imageName)
certIdentity, err := certIdentity(imageName, upstreamImageType, workflowName)
if err != nil {
return err
}
Expand All @@ -58,7 +58,7 @@ func Verify(imageName string) error {
return v.Exec(ctx, []string{imageName})
}

func certIdentity(imageName string) (string, error) {
func certIdentity(imageName, upstreamImageType, workflowName string) (string, error) {
if len(imageName) < 5 {
return "", fmt.Errorf("invalid image name: %q", imageName)
}
Expand Down Expand Up @@ -92,12 +92,17 @@ func certIdentity(imageName string) (string, error) {
}
}

repo = overrideRepo(repo)
identity := ""

indentity := fmt.Sprintf(
"https://github.com/%s/.github/workflows/release.yml@refs/tags/%s", repo, ref)
if upstreamImageRepo, ok := upstreamImagesRepos[upstreamImageType]; ok {
identity = fmt.Sprintf(
"https://github.com/%s/.github/workflows/%s.yaml@refs/heads/main", upstreamImageRepo, workflowName)
} else {
identity = fmt.Sprintf(
"https://github.com/%s/.github/workflows/release.yml@refs/tags/%s", overrideRepo(repo), ref)
}

return indentity, nil
return identity, nil
}

func overrideRepo(repo string) string {
Expand Down
16 changes: 12 additions & 4 deletions pkg/verify/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ func TestCertificateIdentity(t *testing.T) {
t.Parallel()

tests := []struct {
image string
want string
wantErr string
image string
upstreamImageType string
workflowName string
want string
wantErr string
}{
{
image: "foo/bar:v0.0.7",
Expand Down Expand Up @@ -90,14 +92,20 @@ func TestCertificateIdentity(t *testing.T) {
image: "rocker.local/foo/bar:v0.0.7-build12345",
want: "https://github.com/foo/bar/.github/workflows/release.yml@refs/tags/v0.0.7-build12345",
},
{
image: "foo/bar:v0.0.7",
upstreamImageType: "cluster-api",
workflowName: "bar",
want: "https://github.com/rancher/clusterapi-forks/.github/workflows/bar.yaml@refs/heads/main",
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.image, func(t *testing.T) {
t.Parallel()

got, err := certIdentity(tc.image)
got, err := certIdentity(tc.image, tc.upstreamImageType, tc.workflowName)

assert.Equal(t, tc.want, got)

Expand Down

0 comments on commit 2114b22

Please sign in to comment.