Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions cmd/compare/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"

"github.com/conforma/cli/internal/policy"
"github.com/conforma/cli/internal/policy/equivalence"
)

var (
effectiveTime string
imageDigest string
imageRef string
imageURL string
outputFormat string
effectiveTime string
allowPastEffectiveTime bool
imageDigest string
imageRef string
imageURL string
outputFormat string
)

var CompareCmd *cobra.Command
Expand Down Expand Up @@ -73,7 +75,8 @@ Examples:
RunE: runCompare,
}

Comment thread
cuipinghuo marked this conversation as resolved.
compareCmd.Flags().StringVar(&effectiveTime, "effective-time", "now", "Effective time for policy evaluation (RFC3339 format, 'now')")
compareCmd.Flags().StringVar(&effectiveTime, "effective-time", "now", "Effective time for policy evaluation ('now', 'attestation', or RFC3339 format, e.g. 2022-11-18T00:00:00Z)")
compareCmd.Flags().BoolVar(&allowPastEffectiveTime, "allow-past-effective-time", false, "Allow setting --effective-time to a date in the past. By default, dates more than 5 minutes in the past are rejected.")
compareCmd.Flags().StringVar(&imageDigest, "image-digest", "", "Image digest for volatile config matching")
compareCmd.Flags().StringVar(&imageRef, "image-ref", "", "Image reference for volatile config matching")
compareCmd.Flags().StringVar(&imageURL, "image-url", "", "Image URL for volatile config matching")
Expand All @@ -84,20 +87,12 @@ Examples:

func runCompare(cmd *cobra.Command, args []string) error {

Comment thread
cuipinghuo marked this conversation as resolved.
// Parse effective time
var effectiveTimeValue time.Time
switch effectiveTime {
case "now":
effectiveTimeValue = time.Now().UTC()
case "attestation":
// For now, use current time as default for attestation time
effectiveTimeValue, err := policy.ParseEffectiveTime(effectiveTime, allowPastEffectiveTime)
if err != nil {
return err
Comment thread
cuipinghuo marked this conversation as resolved.
}
if effectiveTimeValue.IsZero() {
effectiveTimeValue = time.Now().UTC()
default:
var err error
effectiveTimeValue, err = time.Parse(time.RFC3339, effectiveTime)
if err != nil {
return fmt.Errorf("invalid effective time format: %w", err)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] edge-case

When --effective-time=attestation is used with compare, ParseEffectiveTime returns a zero time.Time and the IsZero() check falls back to time.Now().UTC(). Pre-existing behavior preserved by this PR.


// Create image info if provided
Expand Down
9 changes: 8 additions & 1 deletion cmd/validate/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func validateImageCmd(validate imageValidationFunc) *cobra.Command {
data.policyConfiguration = policyConfiguration

policyOptions := policy.Options{
EffectiveTime: data.effectiveTime,
EffectiveTime: data.effectiveTime,
AllowPastEffectiveTime: data.allowPastEffectiveTime,
Identity: cosign.Identity{
Issuer: data.certificateOIDCIssuer,
IssuerRegExp: data.certificateOIDCIssuerRegExp,
Expand Down Expand Up @@ -547,6 +548,11 @@ func validateImageCmd(validate imageValidationFunc) *cobra.Command {
a RFC3339 formatted value, e.g. 2022-11-18T00:00:00Z.
`))

cmd.Flags().BoolVar(&data.allowPastEffectiveTime, "allow-past-effective-time", false, hd.Doc(`
Allow setting --effective-time to a date in the past. By default, dates
more than 5 minutes in the past are rejected.
`))

cmd.Flags().StringSliceVar(&data.extraRuleData, "extra-rule-data", data.extraRuleData, hd.Doc(`
Extra data to be provided to the Rego policy evaluator. Use format 'key=value'. May be used multiple times.
`))
Expand Down Expand Up @@ -628,6 +634,7 @@ func validateAttestationOutputPath(path string) (string, error) {

// imageData is the struct that holds all image validation command data
type imageData struct {
allowPastEffectiveTime bool
certificateIdentity string
certificateIdentityRegExp string
certificateOIDCIssuer string
Comment thread
cuipinghuo marked this conversation as resolved.
Expand Down
1 change: 1 addition & 0 deletions cmd/validate/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ spec:
"/policy.yaml",
"--effective-time",
"1970-01-01",
"--allow-past-effective-time",
}...)
cmd.SetArgs(args)

Expand Down
35 changes: 20 additions & 15 deletions cmd/validate/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,21 @@ type InputValidationFunc func(context.Context, string, policy.Policy, bool) (*ou

func validateInputCmd(validate InputValidationFunc) *cobra.Command {
data := struct {
effectiveTime string
filePaths []string
forceColor bool
info bool
namespaces []string
noColor bool
output []string
policy policy.Policy
policyConfiguration string
strict bool
workers int
serverMode bool
serverAddress string
serverPort int
effectiveTime string
allowPastEffectiveTime bool
filePaths []string

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] code-organization

allowPastEffectiveTime field placement differs between input.go (grouped with effectiveTime) and image.go (alphabetical). Inconsistent ordering convention.

forceColor bool
info bool
namespaces []string
noColor bool
output []string
policy policy.Policy
policyConfiguration string
strict bool
workers int
serverMode bool
serverAddress string
serverPort int
}{
strict: true,
workers: 5,
Expand Down Expand Up @@ -168,7 +169,7 @@ func validateInputCmd(validate InputValidationFunc) *cobra.Command {
}
data.policyConfiguration = policyConfiguration

if p, err := policy.NewInputPolicy(cmd.Context(), data.policyConfiguration, data.effectiveTime); err != nil {
if p, err := policy.NewInputPolicy(cmd.Context(), data.policyConfiguration, data.effectiveTime, data.allowPastEffectiveTime); err != nil {
allErrors = errors.Join(allErrors, err)
} else {
data.policy = p
Expand Down Expand Up @@ -349,6 +350,10 @@ func validateInputCmd(validate InputValidationFunc) *cobra.Command {
effective dates in the future. The value can be "now" (default) - for
current time, or a RFC3339 formatted value, e.g. 2022-11-18T00:00:00Z.`))

cmd.Flags().BoolVar(&data.allowPastEffectiveTime, "allow-past-effective-time", false, hd.Doc(`
Allow setting --effective-time to a date in the past. By default, dates
more than 5 minutes in the past are rejected.`))

cmd.Flags().BoolVar(&data.info, "info", data.info, hd.Doc(`
Include additional information on the failures. For instance for policy
violations, include the title and the description of the failed policy
Expand Down
3 changes: 2 additions & 1 deletion docs/modules/ROOT/pages/ec_compare.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ ec compare <policy1> <policy2> [flags]
----
== Options

--effective-time:: Effective time for policy evaluation (RFC3339 format, 'now') (Default: now)
--allow-past-effective-time:: Allow setting --effective-time to a date in the past. By default, dates more than 5 minutes in the past are rejected. (Default: false)
--effective-time:: Effective time for policy evaluation ('now', 'attestation', or RFC3339 format, e.g. 2022-11-18T00:00:00Z) (Default: now)
-h, --help:: help for compare (Default: false)
--image-digest:: Image digest for volatile config matching
--image-ref:: Image reference for volatile config matching
Expand Down
3 changes: 3 additions & 0 deletions docs/modules/ROOT/pages/ec_validate_image.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ Use a regular expression to match certificate attributes.

== Options

--allow-past-effective-time:: Allow setting --effective-time to a date in the past. By default, dates
more than 5 minutes in the past are rejected.
(Default: false)
--attestation-format:: Attestation output format: dsse (signed envelope), predicate (raw JSON) (Default: dsse)
--attestation-output-dir:: Directory for attestation output files. Defaults to a temp directory under /tmp. Must be under /tmp or the current working directory.
--certificate-identity:: URL of the certificate identity for keyless verification
Expand Down
2 changes: 2 additions & 0 deletions docs/modules/ROOT/pages/ec_validate_input.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ Start the server on a custom port:

== Options

--allow-past-effective-time:: Allow setting --effective-time to a date in the past. By default, dates
more than 5 minutes in the past are rejected. (Default: false)
--color:: Enable color when using text output even when the current terminal does not support it (Default: false)
--effective-time:: Run policy checks with the provided time. Useful for testing rules with
effective dates in the future. The value can be "now" (default) - for
Expand Down
3 changes: 3 additions & 0 deletions docs/modules/ROOT/pages/verify-conforma-konflux-ta.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ paths can be provided by using the `:` separator.
*EFFECTIVE_TIME* (`string`):: Run policy checks with the provided time.
+
*Default*: `now`
*ALLOW_PAST_EFFECTIVE_TIME* (`string`):: Allow setting EFFECTIVE_TIME to a date in the past.
+
*Default*: `false`
*EXTRA_RULE_DATA* (`string`):: Merge additional Rego variables into the policy data. Use syntax "key=value,key2=value2..."
*POLICY_BUNDLE_DIGEST* (`string`):: Optional OCI digest to pin the release policy bundle. When provided, the policy configuration is resolved and the reference oci::quay.io/conforma/release-policy:konflux is replaced with oci::quay.io/conforma/release-policy@<digest>. Accepts a full digest (sha256:abc123...) or just the hex hash (abc123...).
+
Expand Down
3 changes: 3 additions & 0 deletions docs/modules/ROOT/pages/verify-enterprise-contract.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ paths can be provided by using the `:` separator.
*EFFECTIVE_TIME* (`string`):: Run policy checks with the provided time.
+
*Default*: `now`
*ALLOW_PAST_EFFECTIVE_TIME* (`string`):: Allow setting EFFECTIVE_TIME to a date in the past.
+
*Default*: `false`
*EXTRA_RULE_DATA* (`string`):: Merge additional Rego variables into the policy data. Use syntax "key=value,key2=value2..."
*POLICY_BUNDLE_DIGEST* (`string`):: Optional OCI digest to pin the release policy bundle. When provided, the policy configuration is resolved and the reference oci::quay.io/conforma/release-policy:konflux is replaced with oci::quay.io/conforma/release-policy@<digest>. Accepts a full digest (sha256:abc123...) or just the hex hash (abc123...).
+
Expand Down
9 changes: 5 additions & 4 deletions features/task_validate_image.feature
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,11 @@ Feature: Verify Enterprise Contract Tekton Tasks
{"publicKey": ${known_PUBLIC_KEY}}
```
When version 0.1 of the task named "verify-enterprise-contract" is run with parameters:
| IMAGES | {"components": [{"containerImage": "${REGISTRY}/acceptance/effective-time"}]} |
| POLICY_CONFIGURATION | ${NAMESPACE}/${POLICY_NAME} |
| IGNORE_REKOR | true |
| EFFECTIVE_TIME | 2020-01-01T00:00:00Z |
| IMAGES | {"components": [{"containerImage": "${REGISTRY}/acceptance/effective-time"}]} |
| POLICY_CONFIGURATION | ${NAMESPACE}/${POLICY_NAME} |
| IGNORE_REKOR | true |
| EFFECTIVE_TIME | 2020-01-01T00:00:00Z |
| ALLOW_PAST_EFFECTIVE_TIME | true |
Then the task should succeed
And the task logs for step "show-config" should contain `"effective-time": "2020-01-01T00:00:00Z"`

Expand Down
2 changes: 1 addition & 1 deletion features/validate_image.feature
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ Feature: evaluate enterprise contract
]
}
"""
When ec command is run with "validate image --image ${REGISTRY}/acceptance/image --policy acceptance/ec-policy --rekor-url ${REKOR} --public-key ${known_PUBLIC_KEY} --output=json --effective-time 2014-05-31 --show-successes"
When ec command is run with "validate image --image ${REGISTRY}/acceptance/image --policy acceptance/ec-policy --rekor-url ${REKOR} --public-key ${known_PUBLIC_KEY} --output=json --effective-time 2014-05-31 --allow-past-effective-time --show-successes"
Then the exit status should be 0
And the output should match the snapshot

Expand Down
2 changes: 1 addition & 1 deletion internal/input/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ sources:
exclude:
[]
`
p, err := policy.NewInputPolicy(ctx, policyConfiguration, "now")
p, err := policy.NewInputPolicy(ctx, policyConfiguration, "now", false)
assert.NoError(t, err)
return p
}
2 changes: 1 addition & 1 deletion internal/input/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func Test_ValidatePipeline(t *testing.T) {
errFile := afero.WriteFile(appFS, validFile, []byte("data"), 0o777)
assert.NoError(t, errFile)
ctx := utils.WithFS(context.Background(), appFS)
policy, err := policy.NewInputPolicy(ctx, "", "2023-01-01T00:00:00.00Z")
policy, err := policy.NewInputPolicy(ctx, "", "2023-01-01T00:00:00.00Z", true)
assert.NoError(t, err)

for _, tt := range tests {
Expand Down
Loading
Loading