mirror of
https://github.com/imjasonh/terraform-provider-cosign-old
synced 2026-07-19 07:07:57 +00:00
add resource update tests, force-new on sign, use OCI validators
Signed-off-by: Jason Hall <jason@chainguard.dev>
This commit is contained in:
parent
d2ec4379ae
commit
05e2331208
13 changed files with 346 additions and 275 deletions
17
.github/workflows/test.yml
vendored
17
.github/workflows/test.yml
vendored
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.18'
|
||||
go-version: 1.20.x
|
||||
- run: go generate ./...
|
||||
- name: git diff
|
||||
run: |
|
||||
|
|
@ -43,22 +43,11 @@ jobs:
|
|||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: imjasonh/setup-crane@v0.3
|
||||
- uses: chainguard-dev/actions/setup-registry@main
|
||||
with:
|
||||
port: 5000
|
||||
|
||||
go-version: 1.20.x
|
||||
- uses: hashicorp/setup-terraform@v2
|
||||
with:
|
||||
terraform_version: ${{ matrix.terraform }}
|
||||
terraform_wrapper: false
|
||||
|
||||
- run: go mod download
|
||||
- run: go build -v .
|
||||
- run: |
|
||||
crane copy --insecure cgr.dev/chainguard/static:latest-glibc localhost:5000/cosign-testing
|
||||
export TEST_IMAGE=localhost:5000/cosign-testing@$(crane digest --insecure localhost:5000/cosign-testing)
|
||||
|
||||
TF_ACC=1 go test -v -cover ./internal/provider/
|
||||
- run: TF_ACC=1 go test -v -cover ./internal/provider/
|
||||
|
|
|
|||
3
go.mod
3
go.mod
|
|
@ -2,7 +2,10 @@ module github.com/chainguard-dev/terraform-provider-cosign
|
|||
|
||||
go 1.19
|
||||
|
||||
replace github.com/chainguard-dev/terraform-provider-oci => ../terraform-provider-oci
|
||||
|
||||
require (
|
||||
github.com/chainguard-dev/terraform-provider-oci v0.0.0-20230425204147-f48901367805
|
||||
github.com/google/go-containerregistry v0.14.1-0.20230409045903-ed5c185df419
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/hashicorp/terraform-plugin-docs v0.14.1
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccResourceCosignAttest(t *testing.T) {
|
||||
digest := os.Getenv("TEST_IMAGE")
|
||||
|
||||
url := "https://example.com/" + uuid.New().String()
|
||||
|
||||
value := uuid.New().String()
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{{
|
||||
Config: fmt.Sprintf(`
|
||||
resource "cosign_attest" "foo" {
|
||||
image = %q
|
||||
predicate_type = %q
|
||||
predicate = jsonencode({
|
||||
foo = %q
|
||||
})
|
||||
}
|
||||
|
||||
data "cosign_verify" "bar" {
|
||||
image = cosign_attest.foo.attested_ref
|
||||
policy = jsonencode({
|
||||
apiVersion = "policy.sigstore.dev/v1beta1"
|
||||
kind = "ClusterImagePolicy"
|
||||
metadata = {
|
||||
name = "attested-it"
|
||||
}
|
||||
spec = {
|
||||
images = [{
|
||||
glob = %q
|
||||
}]
|
||||
authorities = [{
|
||||
keyless = {
|
||||
url = "https://fulcio.sigstore.dev"
|
||||
identities = [{
|
||||
issuer = "https://token.actions.githubusercontent.com"
|
||||
subject = "https://github.com/imjasonh/terraform-provider-cosign/.github/workflows/test.yml@refs/heads/main"
|
||||
}]
|
||||
}
|
||||
attestations = [{
|
||||
name = "must-have-attestation"
|
||||
predicateType = %q
|
||||
policy = {
|
||||
type = "cue"
|
||||
// When we do things in this style, we can use file("foo.cue") too!
|
||||
data = <<EOF
|
||||
predicateType: %q
|
||||
predicate: {
|
||||
foo: string
|
||||
// Uncommenting this leads to a failure.
|
||||
// foo: "bar"
|
||||
foo: %q
|
||||
}
|
||||
EOF
|
||||
}
|
||||
}]
|
||||
ctlog = {
|
||||
url = "https://rekor.sigstore.dev"
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
`, digest, url, value, digest, url, url, value),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_attest.foo", "image", regexp.MustCompile("^"+digest)),
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_attest.foo", "attested_ref", regexp.MustCompile("^"+digest)),
|
||||
// Check that it got attested!
|
||||
resource.TestMatchResourceAttr(
|
||||
"data.cosign_verify.bar", "verified_ref", regexp.MustCompile("^"+digest)),
|
||||
),
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
type digestValidator struct{}
|
||||
|
||||
var _ validator.String = digestValidator{}
|
||||
|
||||
func (v digestValidator) Description(context.Context) string {
|
||||
return "value must be a valid OCI digest"
|
||||
}
|
||||
func (v digestValidator) MarkdownDescription(ctx context.Context) string { return v.Description(ctx) }
|
||||
|
||||
func (v digestValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||
return
|
||||
}
|
||||
val := req.ConfigValue.ValueString()
|
||||
if _, err := name.NewDigest(val); err != nil {
|
||||
resp.Diagnostics.AddError("Invalid OCI digest", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
type jsonValidator struct{}
|
||||
|
||||
var _ validator.String = jsonValidator{}
|
||||
|
||||
func (v jsonValidator) Description(context.Context) string { return "value must be valid json" }
|
||||
func (v jsonValidator) MarkdownDescription(ctx context.Context) string { return v.Description(ctx) }
|
||||
|
||||
func (v jsonValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||
return
|
||||
}
|
||||
val := req.ConfigValue.ValueString()
|
||||
|
||||
var untyped interface{}
|
||||
if err := json.Unmarshal([]byte(val), &untyped); err != nil {
|
||||
resp.Diagnostics.AddError("Invalid json", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
type refValidator struct{}
|
||||
|
||||
var _ validator.String = refValidator{}
|
||||
|
||||
func (v refValidator) Description(context.Context) string { return "value must be a valid OCI ref" }
|
||||
func (v refValidator) MarkdownDescription(ctx context.Context) string { return v.Description(ctx) }
|
||||
|
||||
func (v refValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||
return
|
||||
}
|
||||
val := req.ConfigValue.ValueString()
|
||||
if _, err := name.ParseReference(val); err != nil {
|
||||
resp.Diagnostics.AddError("Invalid image reference", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/chainguard-dev/terraform-provider-oci/pkg/validators"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
|
|
@ -57,19 +58,19 @@ func (r *AttestResource) Schema(ctx context.Context, req resource.SchemaRequest,
|
|||
MarkdownDescription: "The digest of the container image to attest.",
|
||||
Optional: false,
|
||||
Required: true,
|
||||
Validators: []validator.String{digestValidator{}},
|
||||
Validators: []validator.String{validators.DigestValidator{}},
|
||||
},
|
||||
"predicate_type": schema.StringAttribute{
|
||||
MarkdownDescription: "The in-toto predicate type of the claim being attested.",
|
||||
Optional: false,
|
||||
Required: true,
|
||||
Validators: []validator.String{urlValidator{}},
|
||||
Validators: []validator.String{validators.URLValidator{}},
|
||||
},
|
||||
"predicate": schema.StringAttribute{
|
||||
MarkdownDescription: "The JSON body of the in-toto predicate's claim.",
|
||||
Optional: false,
|
||||
Required: true,
|
||||
Validators: []validator.String{jsonValidator{}},
|
||||
Validators: []validator.String{validators.JSONValidator{}},
|
||||
},
|
||||
"attested_ref": schema.StringAttribute{
|
||||
MarkdownDescription: "This always matches the input digest, but is a convenience for composition.",
|
||||
187
internal/provider/resource_attest_test.go
Normal file
187
internal/provider/resource_attest_test.go
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
ocitesting "github.com/chainguard-dev/terraform-provider-oci/testing"
|
||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccResourceCosignAttest(t *testing.T) {
|
||||
repo, cleanup := ocitesting.SetupRepository(t, "test")
|
||||
defer cleanup()
|
||||
|
||||
// Push two images by digest.
|
||||
img1, err := random.Image(1024, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dig1, err := img1.Digest()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := remote.Write(repo.Digest(dig1.String()), img1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
img2, err := random.Image(1024, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dig2, err := img2.Digest()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := remote.Write(repo.Digest(dig2.String()), img2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
url := "https://example.com/" + uuid.New().String()
|
||||
|
||||
value := uuid.New().String()
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{
|
||||
// Attest and verify the first image.
|
||||
{
|
||||
Config: fmt.Sprintf(`
|
||||
resource "cosign_attest" "foo" {
|
||||
image = %q
|
||||
predicate_type = %q
|
||||
predicate = jsonencode({
|
||||
foo = %q
|
||||
})
|
||||
}
|
||||
|
||||
data "cosign_verify" "bar" {
|
||||
image = cosign_attest.foo.attested_ref
|
||||
policy = jsonencode({
|
||||
apiVersion = "policy.sigstore.dev/v1beta1"
|
||||
kind = "ClusterImagePolicy"
|
||||
metadata = {
|
||||
name = "attested-it"
|
||||
}
|
||||
spec = {
|
||||
images = [{
|
||||
glob = %q
|
||||
}]
|
||||
authorities = [{
|
||||
keyless = {
|
||||
url = "https://fulcio.sigstore.dev"
|
||||
identities = [{
|
||||
issuer = "https://token.actions.githubusercontent.com"
|
||||
subject = "https://github.com/imjasonh/terraform-provider-cosign/.github/workflows/test.yml@refs/heads/main"
|
||||
}]
|
||||
}
|
||||
attestations = [{
|
||||
name = "must-have-attestation"
|
||||
predicateType = %q
|
||||
policy = {
|
||||
type = "cue"
|
||||
// When we do things in this style, we can use file("foo.cue") too!
|
||||
data = <<EOF
|
||||
predicateType: %q
|
||||
predicate: {
|
||||
foo: string
|
||||
// Uncommenting this leads to a failure.
|
||||
// foo: "bar"
|
||||
foo: %q
|
||||
}
|
||||
EOF
|
||||
}
|
||||
}]
|
||||
ctlog = {
|
||||
url = "https://rekor.sigstore.dev"
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
`, dig1, url, value, dig1, url, url, value),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_attest.foo", "image", regexp.MustCompile("^"+dig1.String())),
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_attest.foo", "attested_ref", regexp.MustCompile("^"+dig1.String())),
|
||||
// Check that it got attested!
|
||||
resource.TestMatchResourceAttr(
|
||||
"data.cosign_verify.bar", "verified_ref", regexp.MustCompile("^"+dig1.String())),
|
||||
),
|
||||
},
|
||||
|
||||
// Update the resource to attest the second image, and verify it.
|
||||
{
|
||||
Config: fmt.Sprintf(`
|
||||
resource "cosign_attest" "foo" {
|
||||
image = %q
|
||||
predicate_type = %q
|
||||
predicate = jsonencode({
|
||||
foo = %q
|
||||
})
|
||||
}
|
||||
|
||||
data "cosign_verify" "bar" {
|
||||
image = cosign_attest.foo.attested_ref
|
||||
policy = jsonencode({
|
||||
apiVersion = "policy.sigstore.dev/v1beta1"
|
||||
kind = "ClusterImagePolicy"
|
||||
metadata = {
|
||||
name = "attested-it"
|
||||
}
|
||||
spec = {
|
||||
images = [{
|
||||
glob = %q
|
||||
}]
|
||||
authorities = [{
|
||||
keyless = {
|
||||
url = "https://fulcio.sigstore.dev"
|
||||
identities = [{
|
||||
issuer = "https://token.actions.githubusercontent.com"
|
||||
subject = "https://github.com/imjasonh/terraform-provider-cosign/.github/workflows/test.yml@refs/heads/main"
|
||||
}]
|
||||
}
|
||||
attestations = [{
|
||||
name = "must-have-attestation"
|
||||
predicateType = %q
|
||||
policy = {
|
||||
type = "cue"
|
||||
// When we do things in this style, we can use file("foo.cue") too!
|
||||
data = <<EOF
|
||||
predicateType: %q
|
||||
predicate: {
|
||||
foo: string
|
||||
// Uncommenting this leads to a failure.
|
||||
// foo: "bar"
|
||||
foo: %q
|
||||
}
|
||||
EOF
|
||||
}
|
||||
}]
|
||||
ctlog = {
|
||||
url = "https://rekor.sigstore.dev"
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
`, dig2, url, value, dig2, url, url, value),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_attest.foo", "image", regexp.MustCompile("^"+dig2.String())),
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_attest.foo", "attested_ref", regexp.MustCompile("^"+dig2.String())),
|
||||
// Check that it got attested!
|
||||
resource.TestMatchResourceAttr(
|
||||
"data.cosign_verify.bar", "verified_ref", regexp.MustCompile("^"+dig2.String())),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/chainguard-dev/terraform-provider-oci/pkg/validators"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
|
|
@ -54,7 +55,10 @@ func (r *SignResource) Schema(ctx context.Context, req resource.SchemaRequest, r
|
|||
MarkdownDescription: "The digest of the container image to sign.",
|
||||
Optional: false,
|
||||
Required: true,
|
||||
Validators: []validator.String{digestValidator{}},
|
||||
Validators: []validator.String{validators.DigestValidator{}},
|
||||
PlanModifiers: []planmodifier.String{
|
||||
stringplanmodifier.RequiresReplace(),
|
||||
},
|
||||
},
|
||||
"signed_ref": schema.StringAttribute{
|
||||
MarkdownDescription: "This always matches the input digest, but is a convenience for composition.",
|
||||
142
internal/provider/resource_sign_test.go
Normal file
142
internal/provider/resource_sign_test.go
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
ocitesting "github.com/chainguard-dev/terraform-provider-oci/testing"
|
||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccResourceCosignSign(t *testing.T) {
|
||||
repo, cleanup := ocitesting.SetupRepository(t, "test")
|
||||
defer cleanup()
|
||||
|
||||
// Push two images by digest.
|
||||
img1, err := random.Image(1024, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dig1, err := img1.Digest()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ref1 := repo.Digest(dig1.String())
|
||||
if err := remote.Write(ref1, img1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
img2, err := random.Image(1024, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dig2, err := img2.Digest()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ref2 := repo.Digest(dig2.String())
|
||||
if err := remote.Write(ref2, img2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{
|
||||
// Sign and verify the first image.
|
||||
{
|
||||
Config: fmt.Sprintf(`
|
||||
resource "cosign_sign" "foo" {
|
||||
image = %q
|
||||
}
|
||||
|
||||
data "cosign_verify" "bar" {
|
||||
image = cosign_sign.foo.signed_ref
|
||||
policy = jsonencode({
|
||||
apiVersion = "policy.sigstore.dev/v1beta1"
|
||||
kind = "ClusterImagePolicy"
|
||||
metadata = {
|
||||
name = "signed-it"
|
||||
}
|
||||
spec = {
|
||||
images = [{
|
||||
glob = %q
|
||||
}]
|
||||
authorities = [{
|
||||
keyless = {
|
||||
url = "https://fulcio.sigstore.dev"
|
||||
identities = [{
|
||||
issuer = "https://token.actions.githubusercontent.com"
|
||||
subject = "https://github.com/imjasonh/terraform-provider-cosign/.github/workflows/test.yml@refs/heads/main"
|
||||
}]
|
||||
}
|
||||
ctlog = {
|
||||
url = "https://rekor.sigstore.dev"
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
`, ref1, ref1),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_sign.foo", "image", regexp.MustCompile("^"+ref1.String())),
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_sign.foo", "signed_ref", regexp.MustCompile("^"+ref1.String())),
|
||||
// Check that it got signed!
|
||||
resource.TestMatchResourceAttr(
|
||||
"data.cosign_verify.bar", "verified_ref", regexp.MustCompile("^"+ref1.String())),
|
||||
),
|
||||
},
|
||||
|
||||
// Update the sign resource to sign the second image, and verify that.
|
||||
{
|
||||
Config: fmt.Sprintf(`
|
||||
resource "cosign_sign" "foo" {
|
||||
image = %q
|
||||
}
|
||||
|
||||
data "cosign_verify" "bar" {
|
||||
image = cosign_sign.foo.signed_ref
|
||||
policy = jsonencode({
|
||||
apiVersion = "policy.sigstore.dev/v1beta1"
|
||||
kind = "ClusterImagePolicy"
|
||||
metadata = {
|
||||
name = "signed-it"
|
||||
}
|
||||
spec = {
|
||||
images = [{
|
||||
glob = %q
|
||||
}]
|
||||
authorities = [{
|
||||
keyless = {
|
||||
url = "https://fulcio.sigstore.dev"
|
||||
identities = [{
|
||||
issuer = "https://token.actions.githubusercontent.com"
|
||||
subject = "https://github.com/imjasonh/terraform-provider-cosign/.github/workflows/test.yml@refs/heads/main"
|
||||
}]
|
||||
}
|
||||
ctlog = {
|
||||
url = "https://rekor.sigstore.dev"
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
`, ref2, ref2),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_sign.foo", "image", regexp.MustCompile("^"+ref2.String())),
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_sign.foo", "signed_ref", regexp.MustCompile("^"+ref2.String())),
|
||||
// Check that it got signed!
|
||||
resource.TestMatchResourceAttr(
|
||||
"data.cosign_verify.bar", "verified_ref", regexp.MustCompile("^"+ref2.String())),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccResourceCosignSign(t *testing.T) {
|
||||
digest := os.Getenv("TEST_IMAGE")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{{
|
||||
Config: fmt.Sprintf(`
|
||||
resource "cosign_sign" "foo" {
|
||||
image = %q
|
||||
}
|
||||
|
||||
data "cosign_verify" "bar" {
|
||||
image = cosign_sign.foo.signed_ref
|
||||
policy = jsonencode({
|
||||
apiVersion = "policy.sigstore.dev/v1beta1"
|
||||
kind = "ClusterImagePolicy"
|
||||
metadata = {
|
||||
name = "signed-it"
|
||||
}
|
||||
spec = {
|
||||
images = [{
|
||||
glob = %q
|
||||
}]
|
||||
authorities = [{
|
||||
keyless = {
|
||||
url = "https://fulcio.sigstore.dev"
|
||||
identities = [{
|
||||
issuer = "https://token.actions.githubusercontent.com"
|
||||
subject = "https://github.com/imjasonh/terraform-provider-cosign/.github/workflows/test.yml@refs/heads/main"
|
||||
}]
|
||||
}
|
||||
ctlog = {
|
||||
url = "https://rekor.sigstore.dev"
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
`, digest, digest),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_sign.foo", "image", regexp.MustCompile("^"+digest)),
|
||||
resource.TestMatchResourceAttr(
|
||||
"cosign_sign.foo", "signed_ref", regexp.MustCompile("^"+digest)),
|
||||
// Check that it got signed!
|
||||
resource.TestMatchResourceAttr(
|
||||
"data.cosign_verify.bar", "verified_ref", regexp.MustCompile("^"+digest)),
|
||||
),
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
type urlValidator struct{}
|
||||
|
||||
var _ validator.String = urlValidator{}
|
||||
|
||||
func (v urlValidator) Description(context.Context) string { return "value must be a valid URL" }
|
||||
func (v urlValidator) MarkdownDescription(ctx context.Context) string { return v.Description(ctx) }
|
||||
|
||||
func (v urlValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||
return
|
||||
}
|
||||
val := req.ConfigValue.ValueString()
|
||||
if _, err := url.Parse(val); err != nil {
|
||||
resp.Diagnostics.AddError("Invalid url", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package provider
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chainguard-dev/terraform-provider-oci/pkg/validators"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
|
|
@ -43,7 +44,7 @@ func (d *VerifyDataSource) Schema(ctx context.Context, req datasource.SchemaRequ
|
|||
"image": schema.StringAttribute{
|
||||
MarkdownDescription: "The image tag or digest of the container image to verify.",
|
||||
Required: true,
|
||||
Validators: []validator.String{refValidator{}},
|
||||
Validators: []validator.String{validators.RefValidator{}},
|
||||
},
|
||||
"policy": schema.StringAttribute{
|
||||
MarkdownDescription: "The sigstore policy-controller policy to verify the image against.",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue