From b8b795b4520a2590d9996cfb4dfc6a6ebc186305 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 24 Mar 2025 11:19:59 +0800 Subject: [PATCH 01/25] initial commit Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 110 ++++++++++++++++++++++++++++++ cmd/notation/cert/cleanup_test.go | 47 +++++++++++++ cmd/notation/cert/cmd.go | 1 + specs/cmd/certificate.md | 20 ++---- test/e2e/suite/command/cert.go | 43 ++++++++++++ 5 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 cmd/notation/cert/cleanupTest.go create mode 100644 cmd/notation/cert/cleanup_test.go diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go new file mode 100644 index 000000000..636da731e --- /dev/null +++ b/cmd/notation/cert/cleanupTest.go @@ -0,0 +1,110 @@ +// Copyright The Notary Project Authors. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cert + +import ( + "errors" + "fmt" + "os" + "path/filepath" + + "github.com/notaryproject/notation-go/config" + "github.com/notaryproject/notation-go/dir" + "github.com/notaryproject/notation/v2/cmd/notation/internal/display" + "github.com/notaryproject/notation/v2/cmd/notation/internal/truststore" + "github.com/spf13/cobra" +) + +type certCleanupTestOpts struct { + name string + confirmed bool +} + +func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { + if opts == nil { + opts = &certCleanupTestOpts{} + } + command := &cobra.Command{ + Use: "cleanup-test [flags] ", + Short: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command.`, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return errors.New("missing certificate common_name") + } + opts.name = args[0] + return nil + }, + Long: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command. +Example - Clean up a test key and corresponding certificate named "wabbit-networks.io": + notation cert cleanup-test "wabbit-networks.io" +`, + RunE: func(cmd *cobra.Command, args []string) error { + return cleanupTestCert(opts) + }, + } + command.Flags().BoolVarP(&opts.confirmed, "yes", "y", false, "do not prompt for confirmation") + return command +} + +func cleanupTestCert(opts *certCleanupTestOpts) error { + name := opts.name + if !truststore.IsValidFileName(name) { + return errors.New("name needs to follow [a-zA-Z0-9_.-]+ format") + } + prompt := fmt.Sprintf("Are you sure you want to clean up test key %q and its certificate?", name) + confirmed, err := display.AskForConfirmation(os.Stdin, prompt, opts.confirmed) + if err != nil { + return err + } + if !confirmed { + return nil + } + + // 1. remove from trust store + localKeyPath, localCertPath := dir.LocalKeyPath(name) + configFS := dir.ConfigFS() + certPath, err := configFS.SysPath(localCertPath) + if err != nil { + return err + } + if err := truststore.DeleteCert("ca", name, filepath.Base(certPath), true); err != nil { + return err + } + + // 2. remove key and certificate files from LocalKeyPath + keyPath, err := configFS.SysPath(localKeyPath) + if err != nil { + return err + } + + if err := os.Remove(keyPath); err != nil { + return err + } + if err := os.Remove(certPath); err != nil { + return err + } + fmt.Printf("Successfully deleted %s and %s\n", filepath.Base(keyPath), filepath.Base(certPath)) + + // 3. remove from signingkeys.json config + exec := func(s *config.SigningKeys) error { + _, err := s.Remove(name) + return err + } + if err := config.LoadExecSaveSigningKeys(exec); err != nil { + return err + } + fmt.Printf("Successfully removed %q from signingkeys.json\n", name) + + return nil +} diff --git a/cmd/notation/cert/cleanup_test.go b/cmd/notation/cert/cleanup_test.go new file mode 100644 index 000000000..69394ccd8 --- /dev/null +++ b/cmd/notation/cert/cleanup_test.go @@ -0,0 +1,47 @@ +// Copyright The Notary Project Authors. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cert + +import ( + "reflect" + "testing" +) + +func TestCertCleanupCommand(t *testing.T) { + opts := &certCleanupTestOpts{} + cmd := certCleanupTestCommand(opts) + expected := &certCleanupTestOpts{ + name: "name", + } + if err := cmd.ParseFlags([]string{ + "name"}); err != nil { + t.Fatalf("Parse Flag failed: %v", err) + } + if err := cmd.Args(cmd, cmd.Flags().Args()); err != nil { + t.Fatalf("Parse Args failed: %v", err) + } + if !reflect.DeepEqual(*expected, *opts) { + t.Fatalf("Expect cert generate-test opts: %v, got: %v", expected, opts) + } +} + +func TestCertCleanupTestCommand_MissingArgs(t *testing.T) { + cmd := certCleanupTestCommand(nil) + if err := cmd.ParseFlags(nil); err != nil { + t.Fatalf("Parse Flag failed: %v", err) + } + if err := cmd.Args(cmd, cmd.Flags().Args()); err == nil { + t.Fatal("Parse Args expected error, but ok") + } +} diff --git a/cmd/notation/cert/cmd.go b/cmd/notation/cert/cmd.go index 8fe3d6f0e..2167ef349 100644 --- a/cmd/notation/cert/cmd.go +++ b/cmd/notation/cert/cmd.go @@ -29,6 +29,7 @@ func Cmd() *cobra.Command { certShowCommand(nil), certDeleteCommand(nil), certGenerateTestCommand(nil), + certCleanupTestCommand(nil), ) return command diff --git a/specs/cmd/certificate.md b/specs/cmd/certificate.md index 54b3e318b..216a7f552 100644 --- a/specs/cmd/certificate.md +++ b/specs/cmd/certificate.md @@ -169,10 +169,10 @@ Upon successful listing, all the certificate files in the trust store are printe An example of the output: ``` -STORE TYPE STORE NAME CERTIFICATE -ca myStore1 cert1.pem -ca myStore2 cert2.crt -signingAuthority myStore1 cert3.crt +STORE TYPE STORE NAME CERTIFICATE +ca myStore1 cert1.pem +ca myStore2 cert2.crt +signingAuthority myStore1 cert3.crt signingAuthority myStore2 cert4.pem ``` ### List all certificate files of a certain named store @@ -233,7 +233,7 @@ notation certificate delete --type --store A prompt is displayed, asking the user to confirm the deletion. Upon successful deletion, the specific certificate is deleted from the trust store named `` of type ``. The output message is printed out as following: ```text -Successfully deleted from the trust store. +Successfully deleted from the trust store. ``` If users execute the deletion without specifying required flags using `notation cert delete `, the deletion fails and the error output message is printed out as follows: @@ -258,16 +258,10 @@ Use the following command to clean up a test RSA key and its corresponding certi notation certificate cleanup-test "wabbit-networks.io" ``` -A prompt will be displayed, asking the user to confirm the cleanup. +A prompt will be displayed, asking the user to confirm the cleanup. ```text -The test key and its corresponding certificate will be cleaned up with the following changes: -- Delete certificate .crt from store (type ca). -- Remove key from the key list. -- Delete key file: {NOTATION_CONFIG}/localkeys/.key. -- Delete certificate file: {NOTATION_CONFIG}/localkeys/.crt. - -Are you sure you want to continue? [y/N] +Are you sure you want to clean up test key and its certificate? [y/N] ``` To suppress the prompt, use the `--yes` or `-y` flag. If the user chooses `y`, the following steps will be executed by the `cleanup-test` command: diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 418a8a6ca..436d4c921 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -105,4 +105,47 @@ var _ = Describe("notation cert", func() { ) }) }) + + It("cleanup test", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test", "--default"). + MatchKeyWords( + "generating RSA Key with 2048 bits", + "generated certificate expiring on", + "wrote key:", "e2e-test.key", + "wrote certificate:", "e2e-test.crt", + "Successfully added e2e-test.crt to named store e2e-test of type ca", + "e2e-test: added to the key list", + ) + + notation.Exec("cert", "cleanup-test", "e2e-test"). + MatchKeyWords( + "Successfully deleted e2e-test.key and e2e-test.crt", + "Successfully removed \"e2e-test\" from signingkeys.json", + "Successfully deleted e2e-test.crt", + ) + }) + }) + + It("cleanup test set as default", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test", "--default"). + MatchKeyWords( + "generating RSA Key with 2048 bits", + "generated certificate expiring on", + "wrote key:", "e2e-test.key", + "wrote certificate:", "e2e-test.crt", + "Successfully added e2e-test.crt to named store e2e-test of type ca", + "e2e-test: added to the key list", + "e2e-test: mark as default signing key", + ) + + notation.Exec("cert", "cleanup-test", "e2e-test"). + MatchKeyWords( + "Successfully deleted e2e-test.key and e2e-test.crt", + "Successfully removed \"e2e-test\" from signingkeys.json", + "Successfully deleted e2e-test.crt", + ) + }) + }) }) From 230c50eb74044737c57707a0151e18bb83a0ff3e Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 24 Mar 2025 15:14:47 +0800 Subject: [PATCH 02/25] initial commit Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 70 ++++++++++++------- .../internal/truststore/truststore.go | 2 +- go.mod | 2 +- go.sum | 4 +- specs/cmd/certificate.md | 10 +-- 5 files changed, 54 insertions(+), 34 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 636da731e..072628c2d 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -16,6 +16,7 @@ package cert import ( "errors" "fmt" + "io/fs" "os" "path/filepath" @@ -40,7 +41,10 @@ func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { Short: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - return errors.New("missing certificate common_name") + return errors.New("missing key name") + } + if args[0] == "" { + return errors.New("key name cannot be empty") } opts.name = args[0] return nil @@ -72,39 +76,55 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { } // 1. remove from trust store - localKeyPath, localCertPath := dir.LocalKeyPath(name) + relativeKeyPath, relativeCertPath := dir.LocalKeyPath(name) configFS := dir.ConfigFS() - certPath, err := configFS.SysPath(localCertPath) - if err != nil { - return err - } - if err := truststore.DeleteCert("ca", name, filepath.Base(certPath), true); err != nil { - return err - } - - // 2. remove key and certificate files from LocalKeyPath - keyPath, err := configFS.SysPath(localKeyPath) + certPath, _ := configFS.SysPath(relativeCertPath) // err is always nil + certFileName := filepath.Base(certPath) + err = truststore.DeleteCert("ca", name, certFileName, true) if err != nil { - return err + var pathError *fs.PathError + if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { + fmt.Printf("Certificate %s does not exist in trust store %s of type ca.", certFileName, name) + } else { + return err + } } - if err := os.Remove(keyPath); err != nil { - return err - } - if err := os.Remove(certPath); err != nil { - return err - } - fmt.Printf("Successfully deleted %s and %s\n", filepath.Base(keyPath), filepath.Base(certPath)) - - // 3. remove from signingkeys.json config + // 2. remove key from signingkeys.json config exec := func(s *config.SigningKeys) error { _, err := s.Remove(name) return err } - if err := config.LoadExecSaveSigningKeys(exec); err != nil { - return err + err = config.LoadExecSaveSigningKeys(exec) + if err != nil { + if errors.Is(err, config.KeyNotFoundError{KeyName: name}) { + fmt.Printf("Key %s does not exist in signingkeys.json.", name) + } else { + return err + } } - fmt.Printf("Successfully removed %q from signingkeys.json\n", name) + fmt.Printf("Successfully removed key %s from signingkeys.json\n", name) + // 3. remove key and certificate files from LocalKeyPath + keyPath, _ := configFS.SysPath(relativeKeyPath) // err is always nil + err = os.Remove(keyPath) + if err != nil { + var pathError *fs.PathError + if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { + fmt.Printf("The key file %s does not exist.", keyPath) + } else { + return err + } + } + err = os.Remove(certPath) + if err != nil { + var pathError *fs.PathError + if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { + fmt.Printf("The certificate file %s does not exist.", certPath) + } else { + return err + } + } + fmt.Println("Cleanup completed successfully.") return nil } diff --git a/cmd/notation/internal/truststore/truststore.go b/cmd/notation/internal/truststore/truststore.go index 2d4e07323..73452d702 100644 --- a/cmd/notation/internal/truststore/truststore.go +++ b/cmd/notation/internal/truststore/truststore.go @@ -190,7 +190,7 @@ func DeleteCert(storeType, namedStore, cert string, confirmed bool) error { return err } // write out on success - fmt.Printf("Successfully deleted %s\n", cert) + fmt.Printf("Successfully deleted %s from trust store %s of type %s\n", cert, namedStore, storeType) return nil } diff --git a/go.mod b/go.mod index 0c768b075..5538db470 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.24.0 require ( github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a - github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604 + github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892 github.com/notaryproject/tspclient-go v1.0.1-0.20250306063739-4f55b14d9f01 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 diff --git a/go.sum b/go.sum index 0a13702e2..b609251c2 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a h1:xagHqXDQKyG4hYCzf2yrMxNGdUf1FELEYojY7dZEgP0= github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a/go.mod h1:26/FuY/XSwyGiafPFDOeUJBz+sPsWDpK+Ei4TWtcmTc= -github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604 h1:uw65pHgN+NXAqHssmlRJUkcl515AQgMIOdC6tbBHHXE= -github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604/go.mod h1:NXYZyzIawUSyv+C0Gs8bBYJ1q8a1gy78GEss8fPNZmY= +github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892 h1:2bD9p585QwuFQry03o19yHZzeBJOCSuol6LR64KIfto= +github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892/go.mod h1:NXYZyzIawUSyv+C0Gs8bBYJ1q8a1gy78GEss8fPNZmY= github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4= github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics= github.com/notaryproject/tspclient-go v1.0.1-0.20250306063739-4f55b14d9f01 h1:Ay72jBeHKqBFk6TbJWywfwzefN3Ei7Py2OzCiWU/7nk= diff --git a/specs/cmd/certificate.md b/specs/cmd/certificate.md index 216a7f552..6819ffa54 100644 --- a/specs/cmd/certificate.md +++ b/specs/cmd/certificate.md @@ -276,8 +276,8 @@ If any step encounters non-existent conditions, the entire process will not be t A sample output for a successful execution: ```text -Successfully deleted certificate .crt from store (type ca). -Successfully removed key from the key list. +Successfully deleted certificate .crt from trust store of type ca. +Successfully removed key from signingkeys.json. Successfully deleted key file: {NOTATION_CONFIG}/localkeys/.key. Successfully deleted certificate file: {NOTATION_CONFIG}/localkeys/.crt. Cleanup completed successfully. @@ -286,9 +286,9 @@ Cleanup completed successfully. A sample output for non-existent conditions: ```text -The certificate .crt does not exist in the store (type ca). -The key does not exist in the key list. -The key file does not exist: {NOTATION_CONFIG}/localkeys/.key. +Certificate .crt does not exist in trust store of type ca. +Key does not exist in signingkeys.json. +Key file {NOTATION_CONFIG}/localkeys/.key does not exist. Successfully deleted certificate file: {NOTATION_CONFIG}/localkeys/.crt. Cleanup completed successfully. ``` From 4ada92284548164707530cd57b21dac96db46e83 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 08:45:01 +0800 Subject: [PATCH 03/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/generateTest.go | 4 ++-- specs/cmd/certificate.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/notation/cert/generateTest.go b/cmd/notation/cert/generateTest.go index 45b320548..75df8d839 100644 --- a/cmd/notation/cert/generateTest.go +++ b/cmd/notation/cert/generateTest.go @@ -52,11 +52,11 @@ func certGenerateTestCommand(opts *certGenerateTestOpts) *cobra.Command { opts = &certGenerateTestOpts{} } command := &cobra.Command{ - Use: "generate-test [flags] ", + Use: "generate-test [flags] ", Short: "Generate a test RSA key and a corresponding self-signed certificate.", Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - return errors.New("missing certificate common_name") + return errors.New("missing certificate key_name") } opts.name = args[0] return nil diff --git a/specs/cmd/certificate.md b/specs/cmd/certificate.md index 6819ffa54..d22eb1c92 100644 --- a/specs/cmd/certificate.md +++ b/specs/cmd/certificate.md @@ -126,7 +126,7 @@ Flags: Generate a test RSA key and a corresponding self-signed certificate. Usage: - notation certificate generate-test [flags] + notation certificate generate-test [flags] Flags: -b, --bits int RSA key bits (default 2048) From 97ed01f5ce30781052aaba2506606ecce02a1f86 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 08:56:13 +0800 Subject: [PATCH 04/25] fix unit test Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 2 +- cmd/notation/internal/sign/sign_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 072628c2d..367ed6a90 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -51,7 +51,7 @@ func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { }, Long: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command. Example - Clean up a test key and corresponding certificate named "wabbit-networks.io": - notation cert cleanup-test "wabbit-networks.io" + notation cert cleanup-test wabbit-networks.io `, RunE: func(cmd *cobra.Command, args []string) error { return cleanupTestCert(opts) diff --git a/cmd/notation/internal/sign/sign_test.go b/cmd/notation/internal/sign/sign_test.go index 24a2a45c1..1f4bb3809 100644 --- a/cmd/notation/internal/sign/sign_test.go +++ b/cmd/notation/internal/sign/sign_test.go @@ -177,7 +177,7 @@ func TestGetSignerFailed(t *testing.T) { t.Run("key not found", func(t *testing.T) { dir.UserConfigDir = "./testdata/valid_signingkeys" - expectedErrMsg := `signing key not found` + expectedErrMsg := `signing key test2 not found` opts := &flag.SignerFlagOpts{ Key: "test2", } From fd4bbda99d066d749d45f2729fd7ddea7cf5d16d Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 10:34:19 +0800 Subject: [PATCH 05/25] e2e test Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 14 ++++++++------ test/e2e/suite/command/cert.go | 22 +++++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 367ed6a90..de1938ba6 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -84,7 +84,7 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { if err != nil { var pathError *fs.PathError if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { - fmt.Printf("Certificate %s does not exist in trust store %s of type ca.", certFileName, name) + fmt.Printf("Certificate %s does not exist in trust store %s of type ca\n", certFileName, name) } else { return err } @@ -98,33 +98,35 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { err = config.LoadExecSaveSigningKeys(exec) if err != nil { if errors.Is(err, config.KeyNotFoundError{KeyName: name}) { - fmt.Printf("Key %s does not exist in signingkeys.json.", name) + fmt.Printf("Key %s does not exist in signingkeys.json\n", name) } else { return err } } fmt.Printf("Successfully removed key %s from signingkeys.json\n", name) - // 3. remove key and certificate files from LocalKeyPath + // 3. delete key and certificate files from LocalKeyPath keyPath, _ := configFS.SysPath(relativeKeyPath) // err is always nil err = os.Remove(keyPath) if err != nil { var pathError *fs.PathError if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { - fmt.Printf("The key file %s does not exist.", keyPath) + fmt.Printf("Key file %s does not exist\n", keyPath) } else { return err } } + fmt.Printf("Successfully deleted key file: %s\n", keyPath) err = os.Remove(certPath) if err != nil { var pathError *fs.PathError if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { - fmt.Printf("The certificate file %s does not exist.", certPath) + fmt.Printf("Certificate file %s does not exist.", certPath) } else { return err } } - fmt.Println("Cleanup completed successfully.") + fmt.Printf("Successfully deleted certificate file: %s\n", certPath) + fmt.Printf("Cleanup completed successfully") return nil } diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 436d4c921..5d6aa81da 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -108,7 +108,7 @@ var _ = Describe("notation cert", func() { It("cleanup test", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { - notation.Exec("cert", "generate-test", "e2e-test", "--default"). + notation.Exec("cert", "generate-test", "e2e-test"). MatchKeyWords( "generating RSA Key with 2048 bits", "generated certificate expiring on", @@ -118,16 +118,18 @@ var _ = Describe("notation cert", func() { "e2e-test: added to the key list", ) - notation.Exec("cert", "cleanup-test", "e2e-test"). + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( - "Successfully deleted e2e-test.key and e2e-test.crt", - "Successfully removed \"e2e-test\" from signingkeys.json", - "Successfully deleted e2e-test.crt", + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + `Successfully removed key e2e-test from signingkeys.json`, + `Successfully deleted key file:`, + `Successfully deleted certificate file:`, + "Cleanup completed successfully", ) }) }) - It("cleanup test set as default", func() { + It("cleanup test with key set as default", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "generate-test", "e2e-test", "--default"). MatchKeyWords( @@ -142,9 +144,11 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test"). MatchKeyWords( - "Successfully deleted e2e-test.key and e2e-test.crt", - "Successfully removed \"e2e-test\" from signingkeys.json", - "Successfully deleted e2e-test.crt", + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + `Successfully removed key e2e-test from signingkeys.json`, + `Successfully deleted key file:`, + `Successfully deleted certificate file:`, + "Cleanup completed successfully", ) }) }) From d9f97cbf3714a1bf63b5ba9817d9c1be885e557d Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 10:43:37 +0800 Subject: [PATCH 06/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 5d6aa81da..2ed8ffcf3 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -14,10 +14,12 @@ package command import ( + "fmt" + "path/filepath" + . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" - // . "github.com/notaryproject/notation/test/e2e/suite/common" . "github.com/onsi/ginkgo/v2" ) @@ -118,12 +120,14 @@ var _ = Describe("notation cert", func() { "e2e-test: added to the key list", ) + localKeyPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.key") + localCertPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.crt") notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", `Successfully removed key e2e-test from signingkeys.json`, - `Successfully deleted key file:`, - `Successfully deleted certificate file:`, + fmt.Sprintf(`Successfully deleted key file: %s`, localKeyPath), + fmt.Sprintf(`Successfully deleted certificate file: %s`, localCertPath), "Cleanup completed successfully", ) }) @@ -142,12 +146,14 @@ var _ = Describe("notation cert", func() { "e2e-test: mark as default signing key", ) - notation.Exec("cert", "cleanup-test", "e2e-test"). + localKeyPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.key") + localCertPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.crt") + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", `Successfully removed key e2e-test from signingkeys.json`, - `Successfully deleted key file:`, - `Successfully deleted certificate file:`, + fmt.Sprintf(`Successfully deleted key file: %s`, localKeyPath), + fmt.Sprintf(`Successfully deleted certificate file: %s`, localCertPath), "Cleanup completed successfully", ) }) From f697214cbcb65b42e46d30d08323e125e0d996b5 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 10:49:39 +0800 Subject: [PATCH 07/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 2ed8ffcf3..4c066b998 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -15,8 +15,8 @@ package command import ( "fmt" - "path/filepath" + "github.com/notaryproject/notation-go/dir" . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" @@ -120,8 +120,9 @@ var _ = Describe("notation cert", func() { "e2e-test: added to the key list", ) - localKeyPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.key") - localCertPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.crt") + relativeKeyPath, relativeCertPath := dir.LocalKeyPath("e2e-test") + localKeyPath, _ := dir.ConfigFS().SysPath(relativeKeyPath) + localCertPath, _ := dir.ConfigFS().SysPath(relativeCertPath) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", @@ -145,9 +146,9 @@ var _ = Describe("notation cert", func() { "e2e-test: added to the key list", "e2e-test: mark as default signing key", ) - - localKeyPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.key") - localCertPath := filepath.Join(NotationE2ELocalKeysDir, "e2e-test.crt") + relativeKeyPath, relativeCertPath := dir.LocalKeyPath("e2e-test") + localKeyPath, _ := dir.ConfigFS().SysPath(relativeKeyPath) + localCertPath, _ := dir.ConfigFS().SysPath(relativeCertPath) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", From 19aeda7f505d7fd2331fa0a3df2e31635b4e2074 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 10:55:10 +0800 Subject: [PATCH 08/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 4c066b998..8ed75bf9d 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -14,9 +14,6 @@ package command import ( - "fmt" - - "github.com/notaryproject/notation-go/dir" . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" @@ -120,15 +117,12 @@ var _ = Describe("notation cert", func() { "e2e-test: added to the key list", ) - relativeKeyPath, relativeCertPath := dir.LocalKeyPath("e2e-test") - localKeyPath, _ := dir.ConfigFS().SysPath(relativeKeyPath) - localCertPath, _ := dir.ConfigFS().SysPath(relativeCertPath) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", `Successfully removed key e2e-test from signingkeys.json`, - fmt.Sprintf(`Successfully deleted key file: %s`, localKeyPath), - fmt.Sprintf(`Successfully deleted certificate file: %s`, localCertPath), + `Successfully deleted key file:`, "e2e-test.key", + `Successfully deleted certificate file:`, "e2e-test.crt", "Cleanup completed successfully", ) }) @@ -146,15 +140,13 @@ var _ = Describe("notation cert", func() { "e2e-test: added to the key list", "e2e-test: mark as default signing key", ) - relativeKeyPath, relativeCertPath := dir.LocalKeyPath("e2e-test") - localKeyPath, _ := dir.ConfigFS().SysPath(relativeKeyPath) - localCertPath, _ := dir.ConfigFS().SysPath(relativeCertPath) + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", `Successfully removed key e2e-test from signingkeys.json`, - fmt.Sprintf(`Successfully deleted key file: %s`, localKeyPath), - fmt.Sprintf(`Successfully deleted certificate file: %s`, localCertPath), + `Successfully deleted key file:`, "e2e-test.key", + `Successfully deleted certificate file:`, "e2e-test.crt", "Cleanup completed successfully", ) }) From 60697ea3e2ea4bac73a482c0e48c022918b978f3 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 10:58:33 +0800 Subject: [PATCH 09/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/blob/sign.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/suite/command/blob/sign.go b/test/e2e/suite/command/blob/sign.go index 19cd74bd0..a1efc4f0b 100644 --- a/test/e2e/suite/command/blob/sign.go +++ b/test/e2e/suite/command/blob/sign.go @@ -120,7 +120,7 @@ var _ = Describe("notation blob sign", func() { It("with invalid key", func() { HostWithBlob(BaseOptions(), func(notation *utils.ExecOpts, blobPath string, vhost *utils.VirtualHost) { notation.ExpectFailure().Exec("blob", "sign", "--key", "invalid", blobPath). - MatchErrKeyWords("signing key not found") + MatchErrKeyWords("signing key invalid not found") }) }) From 21f306a149ee7b1159252b2784d588b6febbbc7a Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 15:51:15 +0800 Subject: [PATCH 10/25] e2e tests Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 13 ++-- test/e2e/go.mod | 4 +- test/e2e/go.sum | 8 +- test/e2e/plugin/go.mod | 2 +- test/e2e/plugin/go.sum | 4 +- test/e2e/suite/command/cert.go | 129 +++++++++++++++++++++++++++++-- 6 files changed, 139 insertions(+), 21 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index de1938ba6..4e601f1ea 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -43,8 +43,8 @@ func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { if len(args) == 0 { return errors.New("missing key name") } - if args[0] == "" { - return errors.New("key name cannot be empty") + if !truststore.IsValidFileName(args[0]) { + return errors.New("key name must follow [a-zA-Z0-9_.-]+ format") } opts.name = args[0] return nil @@ -63,9 +63,6 @@ Example - Clean up a test key and corresponding certificate named "wabbit-networ func cleanupTestCert(opts *certCleanupTestOpts) error { name := opts.name - if !truststore.IsValidFileName(name) { - return errors.New("name needs to follow [a-zA-Z0-9_.-]+ format") - } prompt := fmt.Sprintf("Are you sure you want to clean up test key %q and its certificate?", name) confirmed, err := display.AskForConfirmation(os.Stdin, prompt, opts.confirmed) if err != nil { @@ -86,7 +83,7 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { fmt.Printf("Certificate %s does not exist in trust store %s of type ca\n", certFileName, name) } else { - return err + return fmt.Errorf("failed to delete certificate %s from trust store %s of type ca: %w", certFileName, name, err) } } @@ -121,12 +118,12 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { if err != nil { var pathError *fs.PathError if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { - fmt.Printf("Certificate file %s does not exist.", certPath) + fmt.Printf("Certificate file %s does not exist\n", certPath) } else { return err } } fmt.Printf("Successfully deleted certificate file: %s\n", certPath) - fmt.Printf("Cleanup completed successfully") + fmt.Println("Cleanup completed successfully") return nil } diff --git a/test/e2e/go.mod b/test/e2e/go.mod index 584f4ac3a..6791a35f7 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -4,7 +4,7 @@ go 1.24.0 require ( github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a - github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604 + github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892 github.com/onsi/ginkgo/v2 v2.23.3 github.com/onsi/gomega v1.36.3 github.com/opencontainers/image-spec v1.1.1 @@ -17,11 +17,13 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect + github.com/notaryproject/notation-plugin-framework-go v1.0.0 // indirect github.com/notaryproject/tspclient-go v1.0.1-0.20250306063739-4f55b14d9f01 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/veraison/go-cose v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect golang.org/x/crypto v0.36.0 // indirect + golang.org/x/mod v0.23.0 // indirect golang.org/x/net v0.37.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.31.0 // indirect diff --git a/test/e2e/go.sum b/test/e2e/go.sum index 2082429f8..c9c1c2221 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -12,8 +12,10 @@ github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/Z github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a h1:xagHqXDQKyG4hYCzf2yrMxNGdUf1FELEYojY7dZEgP0= github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a/go.mod h1:26/FuY/XSwyGiafPFDOeUJBz+sPsWDpK+Ei4TWtcmTc= -github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604 h1:uw65pHgN+NXAqHssmlRJUkcl515AQgMIOdC6tbBHHXE= -github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604/go.mod h1:NXYZyzIawUSyv+C0Gs8bBYJ1q8a1gy78GEss8fPNZmY= +github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892 h1:2bD9p585QwuFQry03o19yHZzeBJOCSuol6LR64KIfto= +github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892/go.mod h1:NXYZyzIawUSyv+C0Gs8bBYJ1q8a1gy78GEss8fPNZmY= +github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4= +github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics= github.com/notaryproject/tspclient-go v1.0.1-0.20250306063739-4f55b14d9f01 h1:Ay72jBeHKqBFk6TbJWywfwzefN3Ei7Py2OzCiWU/7nk= github.com/notaryproject/tspclient-go v1.0.1-0.20250306063739-4f55b14d9f01/go.mod h1:3ZJPmpmdwufY23BkS+JPNktOVb5DXJ8Ik5zxvN7h670= github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= @@ -34,6 +36,8 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= diff --git a/test/e2e/plugin/go.mod b/test/e2e/plugin/go.mod index 9114003e0..ac052eb71 100644 --- a/test/e2e/plugin/go.mod +++ b/test/e2e/plugin/go.mod @@ -5,7 +5,7 @@ go 1.24.0 require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a - github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604 + github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892 github.com/notaryproject/notation-plugin-framework-go v1.0.0 github.com/spf13/cobra v1.9.1 ) diff --git a/test/e2e/plugin/go.sum b/test/e2e/plugin/go.sum index 5e158f990..902107360 100644 --- a/test/e2e/plugin/go.sum +++ b/test/e2e/plugin/go.sum @@ -40,8 +40,8 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a h1:xagHqXDQKyG4hYCzf2yrMxNGdUf1FELEYojY7dZEgP0= github.com/notaryproject/notation-core-go v1.2.1-0.20250304022306-ea37e4e6c39a/go.mod h1:26/FuY/XSwyGiafPFDOeUJBz+sPsWDpK+Ei4TWtcmTc= -github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604 h1:uw65pHgN+NXAqHssmlRJUkcl515AQgMIOdC6tbBHHXE= -github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250310060348-fdcf9cc47604/go.mod h1:NXYZyzIawUSyv+C0Gs8bBYJ1q8a1gy78GEss8fPNZmY= +github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892 h1:2bD9p585QwuFQry03o19yHZzeBJOCSuol6LR64KIfto= +github.com/notaryproject/notation-go v1.2.0-beta.1.0.20250324062555-fcc1ce32f892/go.mod h1:NXYZyzIawUSyv+C0Gs8bBYJ1q8a1gy78GEss8fPNZmY= github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4= github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics= github.com/notaryproject/tspclient-go v1.0.1-0.20250306063739-4f55b14d9f01 h1:Ay72jBeHKqBFk6TbJWywfwzefN3Ei7Py2OzCiWU/7nk= diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 8ed75bf9d..1d88225e7 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -14,6 +14,9 @@ package command import ( + "os" + + "github.com/notaryproject/notation-go/config" . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" @@ -43,7 +46,7 @@ var _ = Describe("notation cert", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "delete", "--type", "ca", "--store", "e2e", "e2e.crt", "-y"). MatchKeyWords( - "Successfully deleted e2e.crt", + "Successfully deleted e2e.crt from trust store e2e of type ca", ) }) }) @@ -120,9 +123,9 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - `Successfully removed key e2e-test from signingkeys.json`, - `Successfully deleted key file:`, "e2e-test.key", - `Successfully deleted certificate file:`, "e2e-test.crt", + "Successfully removed key e2e-test from signingkeys.json", + "Successfully deleted key file:", "e2e-test.key", + "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", ) }) @@ -144,11 +147,123 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - `Successfully removed key e2e-test from signingkeys.json`, - `Successfully deleted key file:`, "e2e-test.key", - `Successfully deleted certificate file:`, "e2e-test.crt", + "Successfully removed key e2e-test from signingkeys.json", + "Successfully deleted key file:", "e2e-test.key", + "Successfully deleted certificate file:", "e2e-test.crt", + "Cleanup completed successfully", + ) + }) + }) + + It("cleanup test with certificate not in trust store", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + notation.Exec("cert", "delete", "--type", "ca", "--store", "e2e-test", "e2e-test.crt", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + ) + + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchKeyWords( + "Certificate e2e-test.crt does not exist in trust store e2e-test of type ca", + "Successfully removed key e2e-test from signingkeys.json", + "Successfully deleted key file:", "e2e-test.key", + "Successfully deleted certificate file:", "e2e-test.crt", + "Cleanup completed successfully", + ) + }) + }) + + It("cleanup test with key not in signingkeys.json", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + exec := func(s *config.SigningKeys) error { + _, err := s.Remove("e2e-test") + return err + } + if err := config.LoadExecSaveSigningKeys(exec); err != nil { + Fail(err.Error()) + } + + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + "Key e2e-test does not exist in signingkeys.json", + "Successfully deleted key file:", "e2e-test.key", + "Successfully deleted certificate file:", "e2e-test.crt", + "Cleanup completed successfully", + ) + }) + }) + + It("cleanup test without local key file", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + localKeyPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.key") + if err := os.Remove(localKeyPath); err != nil { + Fail(err.Error()) + } + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + "Successfully removed key e2e-test from signingkeys.json", + "Key file e2e-test.key does not exist", + "Successfully deleted certificate file:", "e2e-test.crt", + "Cleanup completed successfully", + ) + }) + }) + + It("cleanup test without local certificate file", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + localCertPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.crt") + if err := os.Remove(localCertPath); err != nil { + Fail(err.Error()) + } + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + "Successfully removed key e2e-test from signingkeys.json", + "Successfully deleted key file: e2e-test.key", + "Certificate file e2e-test.crt does not exist", "Cleanup completed successfully", ) }) }) + + It("cleanup test missing key name", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.ExpectFailure().Exec("cert", "cleanup-test"). + MatchErrKeyWords( + "missing key name", + ) + }) + }) + + It("cleanup test with empty key name", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.ExpectFailure().Exec("cert", "cleanup-test", ""). + MatchErrKeyWords( + "key name must follow [a-zA-Z0-9_.-]+ format", + ) + }) + }) + + It("cleanup test failed at deleting certificate from trust store", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") + os.Chmod(certPath, 0200) + notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchErrKeyWords( + "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca: permission denied", + ) + }) + }) }) From cad8120a9deffdac0b0c4ee7a4d877924c325377 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 16:28:00 +0800 Subject: [PATCH 11/25] e2e tests Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 9 ++++-- test/e2e/suite/command/cert.go | 49 +++++++++++++++----------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 4e601f1ea..726d6a2c6 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -99,8 +99,9 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { } else { return err } + } else { + fmt.Printf("Successfully removed key %s from signingkeys.json\n", name) } - fmt.Printf("Successfully removed key %s from signingkeys.json\n", name) // 3. delete key and certificate files from LocalKeyPath keyPath, _ := configFS.SysPath(relativeKeyPath) // err is always nil @@ -112,8 +113,9 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { } else { return err } + } else { + fmt.Printf("Successfully deleted key file: %s\n", keyPath) } - fmt.Printf("Successfully deleted key file: %s\n", keyPath) err = os.Remove(certPath) if err != nil { var pathError *fs.PathError @@ -122,8 +124,9 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { } else { return err } + } else { + fmt.Printf("Successfully deleted certificate file: %s\n", certPath) } - fmt.Printf("Successfully deleted certificate file: %s\n", certPath) fmt.Println("Cleanup completed successfully") return nil } diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 1d88225e7..2bbccafc2 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -14,9 +14,10 @@ package command import ( + "fmt" "os" - "github.com/notaryproject/notation-go/config" + "github.com/notaryproject/notation-go/dir" . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" @@ -155,42 +156,34 @@ var _ = Describe("notation cert", func() { }) }) - It("cleanup test with certificate not in trust store", func() { + It("cleanup test with key never generated", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { - notation.Exec("cert", "generate-test", "e2e-test") - - notation.Exec("cert", "delete", "--type", "ca", "--store", "e2e-test", "e2e-test.crt", "-y"). - MatchKeyWords( - "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - ) - + localKeyPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.key") + localCertPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.crt") notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Certificate e2e-test.crt does not exist in trust store e2e-test of type ca", - "Successfully removed key e2e-test from signingkeys.json", - "Successfully deleted key file:", "e2e-test.key", - "Successfully deleted certificate file:", "e2e-test.crt", + "Key e2e-test does not exist in signingkeys.json", + fmt.Sprintf("Key file %s does not exist", localKeyPath), + fmt.Sprintf("Certificate file %s does not exist", localCertPath), "Cleanup completed successfully", ) }) }) - It("cleanup test with key not in signingkeys.json", func() { + It("cleanup test with certificate not in trust store", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "generate-test", "e2e-test") - exec := func(s *config.SigningKeys) error { - _, err := s.Remove("e2e-test") - return err - } - if err := config.LoadExecSaveSigningKeys(exec); err != nil { - Fail(err.Error()) - } + notation.Exec("cert", "delete", "--type", "ca", "--store", "e2e-test", "e2e-test.crt", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + ) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( - "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - "Key e2e-test does not exist in signingkeys.json", + "Certificate e2e-test.crt does not exist in trust store e2e-test of type ca", + "Successfully removed key e2e-test from signingkeys.json", "Successfully deleted key file:", "e2e-test.key", "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", @@ -210,7 +203,7 @@ var _ = Describe("notation cert", func() { MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", "Successfully removed key e2e-test from signingkeys.json", - "Key file e2e-test.key does not exist", + fmt.Sprintf("Key file %s does not exist", localKeyPath), "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", ) @@ -229,8 +222,8 @@ var _ = Describe("notation cert", func() { MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", "Successfully removed key e2e-test from signingkeys.json", - "Successfully deleted key file: e2e-test.key", - "Certificate file e2e-test.crt does not exist", + "Successfully deleted key file:", "e2e-test.key", + fmt.Sprintf("Certificate file %s does not exist", localCertPath), "Cleanup completed successfully", ) }) @@ -258,12 +251,16 @@ var _ = Describe("notation cert", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "generate-test", "e2e-test") - certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") + certPath, err := dir.ConfigFS().SysPath(TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") + if err != nil { + Fail(err.Error()) + } os.Chmod(certPath, 0200) notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca: permission denied", ) + os.Chmod(certPath, 0600) }) }) }) From 99e680415a71b57dac3e40bf3994720dc0bedc33 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 16:32:30 +0800 Subject: [PATCH 12/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 2bbccafc2..42fd76461 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -255,7 +255,7 @@ var _ = Describe("notation cert", func() { if err != nil { Fail(err.Error()) } - os.Chmod(certPath, 0200) + os.Chmod(certPath, 0400) notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca: permission denied", From 15c6bf110a51b964c03955233832b270569bf609 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 16:41:23 +0800 Subject: [PATCH 13/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 42fd76461..7f3e381cf 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -17,7 +17,6 @@ import ( "fmt" "os" - "github.com/notaryproject/notation-go/dir" . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" @@ -251,10 +250,7 @@ var _ = Describe("notation cert", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "generate-test", "e2e-test") - certPath, err := dir.ConfigFS().SysPath(TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") - if err != nil { - Fail(err.Error()) - } + certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") os.Chmod(certPath, 0400) notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( From 283359f5ef24ac5f25e6d540992070d3b3a1f5c7 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 16:53:06 +0800 Subject: [PATCH 14/25] e2e tests Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 6 +++--- test/e2e/suite/command/cert.go | 25 ++++++++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 726d6a2c6..7d3a4a322 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -97,7 +97,7 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { if errors.Is(err, config.KeyNotFoundError{KeyName: name}) { fmt.Printf("Key %s does not exist in signingkeys.json\n", name) } else { - return err + return fmt.Errorf("failed to remove key %s from signingkeys.json: %w", name, err) } } else { fmt.Printf("Successfully removed key %s from signingkeys.json\n", name) @@ -111,7 +111,7 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { fmt.Printf("Key file %s does not exist\n", keyPath) } else { - return err + return fmt.Errorf("failed to delete key file %s: %w", keyPath, err) } } else { fmt.Printf("Successfully deleted key file: %s\n", keyPath) @@ -122,7 +122,7 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { fmt.Printf("Certificate file %s does not exist\n", certPath) } else { - return err + return fmt.Errorf("failed to delete certificate file %s: %w", certPath, err) } } else { fmt.Printf("Successfully deleted certificate file: %s\n", certPath) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 7f3e381cf..4a54305b0 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -246,17 +246,32 @@ var _ = Describe("notation cert", func() { }) }) - It("cleanup test failed at deleting certificate from trust store", func() { + // It("cleanup test failed at deleting certificate from trust store", func() { + // Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + // notation.Exec("cert", "generate-test", "e2e-test") + + // certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") + // os.Chmod(certPath, 0400) + // notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). + // MatchErrKeyWords( + // "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca: permission denied", + // ) + // os.Chmod(certPath, 0600) + // }) + // }) + + It("cleanup test failed at deleting local key file", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "generate-test", "e2e-test") - certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") - os.Chmod(certPath, 0400) + localKeyPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.key") + os.Chmod(localKeyPath, 0400) + defer os.Chmod(localKeyPath, 0600) + notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( - "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca: permission denied", + fmt.Sprintf("failed to delete key file %s: permission denied", localKeyPath), ) - os.Chmod(certPath, 0600) }) }) }) From c5367b7bfcc4dd68e081498b224c6256ea919fb1 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 16:57:46 +0800 Subject: [PATCH 15/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 4a54305b0..31ca3f3ff 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -265,7 +265,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "generate-test", "e2e-test") localKeyPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.key") - os.Chmod(localKeyPath, 0400) + os.Chmod(localKeyPath, 0000) defer os.Chmod(localKeyPath, 0600) notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). From a6a224d480a5a81da34106283bf0dc347f5d69b7 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 17:03:46 +0800 Subject: [PATCH 16/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 31ca3f3ff..32b405a5d 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -16,6 +16,7 @@ package command import ( "fmt" "os" + "path/filepath" . "github.com/notaryproject/notation/test/e2e/internal/notation" "github.com/notaryproject/notation/test/e2e/internal/utils" @@ -264,13 +265,13 @@ var _ = Describe("notation cert", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.Exec("cert", "generate-test", "e2e-test") - localKeyPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.key") - os.Chmod(localKeyPath, 0000) - defer os.Chmod(localKeyPath, 0600) + localKeysDir := vhost.AbsolutePath(NotationDirName, LocalKeysDirName) + os.Chmod(localKeysDir, 0000) + defer os.Chmod(localKeysDir, 0755) notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( - fmt.Sprintf("failed to delete key file %s: permission denied", localKeyPath), + fmt.Sprintf("failed to delete key file %s: permission denied", filepath.Join(localKeysDir, "e2e-test.key")), ) }) }) From 5680f1819f82962eb7b2811735db75ebfedb16f7 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 17:12:12 +0800 Subject: [PATCH 17/25] e2e tests Signed-off-by: Patrick Zheng --- test/e2e/suite/command/cert.go | 47 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 32b405a5d..643962cf8 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -247,19 +247,37 @@ var _ = Describe("notation cert", func() { }) }) - // It("cleanup test failed at deleting certificate from trust store", func() { - // Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { - // notation.Exec("cert", "generate-test", "e2e-test") - - // certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test", "e2e-test.crt") - // os.Chmod(certPath, 0400) - // notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). - // MatchErrKeyWords( - // "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca: permission denied", - // ) - // os.Chmod(certPath, 0600) - // }) - // }) + It("cleanup test failed at deleting certificate from trust store", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + certPath := vhost.AbsolutePath(NotationDirName, TrustStoreDirName, "x509", TrustStoreTypeCA, "e2e-test") + os.Chmod(certPath, 0000) + defer os.Chmod(certPath, 0755) + + notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchErrKeyWords( + "failed to delete certificate e2e-test.crt from trust store e2e-test of type ca", + "permission denied", + ) + }) + }) + + It("cleanup test failed at removing key from signingkeys.json", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test") + + signingKeyPath := vhost.AbsolutePath(NotationDirName, SigningKeysFileName) + os.Chmod(signingKeyPath, 0000) + defer os.Chmod(signingKeyPath, 0600) + + notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchErrKeyWords( + "failed to remove key e2e-test from signingkeys.json", + "permission denied", + ) + }) + }) It("cleanup test failed at deleting local key file", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { @@ -271,7 +289,8 @@ var _ = Describe("notation cert", func() { notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( - fmt.Sprintf("failed to delete key file %s: permission denied", filepath.Join(localKeysDir, "e2e-test.key")), + fmt.Sprintf("failed to delete key file %s", filepath.Join(localKeysDir, "e2e-test.key")), + "permission denied", ) }) }) From 0e4270a13d3ceb04fcfeb469075ebabeda555e11 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 17:35:22 +0800 Subject: [PATCH 18/25] clean up Signed-off-by: Patrick Zheng --- cmd/notation/cert/generateTest.go | 4 ++-- specs/cmd/certificate.md | 4 ++-- test/e2e/suite/command/cert.go | 6 +++--- test/e2e/suite/scenario/blob.go | 2 +- test/e2e/suite/scenario/quickstart.go | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/notation/cert/generateTest.go b/cmd/notation/cert/generateTest.go index 75df8d839..9addec76d 100644 --- a/cmd/notation/cert/generateTest.go +++ b/cmd/notation/cert/generateTest.go @@ -136,9 +136,9 @@ func generateTestCert(opts *certGenerateTestOpts) error { } // write out - fmt.Printf("%s: added to the key list\n", name) + fmt.Printf("%s: added to signingkeys.json\n", name) if opts.isDefault { - fmt.Printf("%s: mark as default signing key\n", name) + fmt.Printf("%s: marked as default signing key\n", name) } return nil } diff --git a/specs/cmd/certificate.md b/specs/cmd/certificate.md index 92090ea29..98736dfd5 100644 --- a/specs/cmd/certificate.md +++ b/specs/cmd/certificate.md @@ -248,13 +248,13 @@ If users execute the deletion without specifying required flags using `notation Error: required flag(s) "store", "type" not set ``` -### Generate a local RSA key and a corresponding self-generated certificate for testing purpose and add the certificate into trust store +### Generate a local RSA key and a corresponding self-generated certificate for testing purpose ```bash notation certificate generate-test "wabbit-networks.io" ``` -Upon successful execution, a local key file and certificate file named `wabbit-networks.io` are generated and stored in `$XDG_CONFIG_HOME/notation/localkeys/`. `wabbit-networks.io` is also used as certificate subject.CommonName. +Upon successful execution, a local key file named `wabbit-networks.io.key` and a certificate file named `wabbit-networks.io.crt` are generated and stored in `$XDG_CONFIG_HOME/notation/localkeys/`. `wabbit-networks.io` is also used as the certificate's subject.CommonName. The certificate is added to trust store `wabbit-networks.io` of type `ca`. And the key with name `wabbit-networks.io` is added into `{NOTATION_CONFIG}/signingkeys.json`. ### Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 643962cf8..3114b1480 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -118,7 +118,7 @@ var _ = Describe("notation cert", func() { "wrote key:", "e2e-test.key", "wrote certificate:", "e2e-test.crt", "Successfully added e2e-test.crt to named store e2e-test of type ca", - "e2e-test: added to the key list", + "e2e-test: added to signingkeys.json", ) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). @@ -141,8 +141,8 @@ var _ = Describe("notation cert", func() { "wrote key:", "e2e-test.key", "wrote certificate:", "e2e-test.crt", "Successfully added e2e-test.crt to named store e2e-test of type ca", - "e2e-test: added to the key list", - "e2e-test: mark as default signing key", + "e2e-test: added to signingkeys.json", + "e2e-test: marked as default signing key", ) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). diff --git a/test/e2e/suite/scenario/blob.go b/test/e2e/suite/scenario/blob.go index 7c01b52b6..8178b7680 100644 --- a/test/e2e/suite/scenario/blob.go +++ b/test/e2e/suite/scenario/blob.go @@ -39,7 +39,7 @@ var _ = Describe("notation blob", Serial, func() { notation.Exec("cert", "generate-test", "--default", "testcert"). MatchKeyWords( "Successfully added testcert.crt to named store testcert of type ca", - "testcert: added to the key list", + "testcert: added to signingkeys.json", ) // sign the file diff --git a/test/e2e/suite/scenario/quickstart.go b/test/e2e/suite/scenario/quickstart.go index cec27a137..dc5b77560 100644 --- a/test/e2e/suite/scenario/quickstart.go +++ b/test/e2e/suite/scenario/quickstart.go @@ -52,8 +52,8 @@ var _ = Describe("notation quickstart E2E test", Ordered, func() { notation.Exec("cert", "generate-test", "--default", "wabbit-networks.io"). MatchKeyWords( "Successfully added wabbit-networks.io.crt", - "wabbit-networks.io: added to the key list", - "wabbit-networks.io: mark as default signing key") + "wabbit-networks.io: added to signingkeys.json", + "wabbit-networks.io: marked as default signing key") notation.Exec("key", "ls"). MatchKeyWords( From d8662709bfacec48723381cc30baab15ce340bab Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 25 Mar 2025 17:44:27 +0800 Subject: [PATCH 19/25] clean up Signed-off-by: Patrick Zheng --- cmd/notation/cert/cmd.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/notation/cert/cmd.go b/cmd/notation/cert/cmd.go index 2167ef349..c50500deb 100644 --- a/cmd/notation/cert/cmd.go +++ b/cmd/notation/cert/cmd.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package cert provides implementation of the `notation certificate` command package cert import "github.com/spf13/cobra" From 8dff0ec8947b0382c067dae7c48eb281a18e5e74 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 26 Mar 2025 11:09:34 +0800 Subject: [PATCH 20/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 2 +- cmd/notation/cert/generateTest.go | 6 +++--- specs/cmd/certificate.md | 4 ++-- test/e2e/suite/command/cert.go | 4 ++-- test/e2e/suite/scenario/blob.go | 2 +- test/e2e/suite/scenario/quickstart.go | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 7d3a4a322..b499592d9 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -37,7 +37,7 @@ func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { opts = &certCleanupTestOpts{} } command := &cobra.Command{ - Use: "cleanup-test [flags] ", + Use: "cleanup-test [flags] ", Short: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { diff --git a/cmd/notation/cert/generateTest.go b/cmd/notation/cert/generateTest.go index 9addec76d..72c78a54d 100644 --- a/cmd/notation/cert/generateTest.go +++ b/cmd/notation/cert/generateTest.go @@ -52,11 +52,11 @@ func certGenerateTestCommand(opts *certGenerateTestOpts) *cobra.Command { opts = &certGenerateTestOpts{} } command := &cobra.Command{ - Use: "generate-test [flags] ", + Use: "generate-test [flags] ", Short: "Generate a test RSA key and a corresponding self-signed certificate.", Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - return errors.New("missing certificate key_name") + return errors.New("missing certificate common_name") } opts.name = args[0] return nil @@ -136,7 +136,7 @@ func generateTestCert(opts *certGenerateTestOpts) error { } // write out - fmt.Printf("%s: added to signingkeys.json\n", name) + fmt.Printf("%s: added to the key list\n", name) if opts.isDefault { fmt.Printf("%s: marked as default signing key\n", name) } diff --git a/specs/cmd/certificate.md b/specs/cmd/certificate.md index 98736dfd5..afd103039 100644 --- a/specs/cmd/certificate.md +++ b/specs/cmd/certificate.md @@ -131,7 +131,7 @@ Flags: Generate a test RSA key and a corresponding self-signed certificate. Usage: - notation certificate generate-test [flags] + notation certificate generate-test [flags] Flags: -b, --bits int RSA key bits (default 2048) @@ -145,7 +145,7 @@ Flags: Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command. Usage: - notation certificate cleanup-test [flags] + notation certificate cleanup-test [flags] Flags: -h, --help help for generate-test diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index 3114b1480..dc2867852 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -118,7 +118,7 @@ var _ = Describe("notation cert", func() { "wrote key:", "e2e-test.key", "wrote certificate:", "e2e-test.crt", "Successfully added e2e-test.crt to named store e2e-test of type ca", - "e2e-test: added to signingkeys.json", + "e2e-test: added to the key list", ) notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). @@ -141,7 +141,7 @@ var _ = Describe("notation cert", func() { "wrote key:", "e2e-test.key", "wrote certificate:", "e2e-test.crt", "Successfully added e2e-test.crt to named store e2e-test of type ca", - "e2e-test: added to signingkeys.json", + "e2e-test: added to the key list", "e2e-test: marked as default signing key", ) diff --git a/test/e2e/suite/scenario/blob.go b/test/e2e/suite/scenario/blob.go index 8178b7680..7c01b52b6 100644 --- a/test/e2e/suite/scenario/blob.go +++ b/test/e2e/suite/scenario/blob.go @@ -39,7 +39,7 @@ var _ = Describe("notation blob", Serial, func() { notation.Exec("cert", "generate-test", "--default", "testcert"). MatchKeyWords( "Successfully added testcert.crt to named store testcert of type ca", - "testcert: added to signingkeys.json", + "testcert: added to the key list", ) // sign the file diff --git a/test/e2e/suite/scenario/quickstart.go b/test/e2e/suite/scenario/quickstart.go index dc5b77560..76347ea29 100644 --- a/test/e2e/suite/scenario/quickstart.go +++ b/test/e2e/suite/scenario/quickstart.go @@ -52,7 +52,7 @@ var _ = Describe("notation quickstart E2E test", Ordered, func() { notation.Exec("cert", "generate-test", "--default", "wabbit-networks.io"). MatchKeyWords( "Successfully added wabbit-networks.io.crt", - "wabbit-networks.io: added to signingkeys.json", + "wabbit-networks.io: added to the key list", "wabbit-networks.io: marked as default signing key") notation.Exec("key", "ls"). From e29b050e224edd95b4c0400a4d78e380423595e5 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 26 Mar 2025 11:32:40 +0800 Subject: [PATCH 21/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 6 +++--- test/e2e/suite/command/cert.go | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index b499592d9..bdd3e3326 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -95,12 +95,12 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { err = config.LoadExecSaveSigningKeys(exec) if err != nil { if errors.Is(err, config.KeyNotFoundError{KeyName: name}) { - fmt.Printf("Key %s does not exist in signingkeys.json\n", name) + fmt.Printf("Key %s does not exist in the key list\n", name) } else { - return fmt.Errorf("failed to remove key %s from signingkeys.json: %w", name, err) + return fmt.Errorf("failed to remove key %s from the key list: %w", name, err) } } else { - fmt.Printf("Successfully removed key %s from signingkeys.json\n", name) + fmt.Printf("Successfully removed key %s from the key list\n", name) } // 3. delete key and certificate files from LocalKeyPath diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index dc2867852..e85ce2b55 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -124,7 +124,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - "Successfully removed key e2e-test from signingkeys.json", + "Successfully removed key e2e-test from the key list", "Successfully deleted key file:", "e2e-test.key", "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", @@ -148,7 +148,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - "Successfully removed key e2e-test from signingkeys.json", + "Successfully removed key e2e-test from the key list", "Successfully deleted key file:", "e2e-test.key", "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", @@ -163,7 +163,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Certificate e2e-test.crt does not exist in trust store e2e-test of type ca", - "Key e2e-test does not exist in signingkeys.json", + "Key e2e-test does not exist in the key list", fmt.Sprintf("Key file %s does not exist", localKeyPath), fmt.Sprintf("Certificate file %s does not exist", localCertPath), "Cleanup completed successfully", @@ -183,7 +183,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Certificate e2e-test.crt does not exist in trust store e2e-test of type ca", - "Successfully removed key e2e-test from signingkeys.json", + "Successfully removed key e2e-test from the key list", "Successfully deleted key file:", "e2e-test.key", "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", @@ -202,7 +202,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - "Successfully removed key e2e-test from signingkeys.json", + "Successfully removed key e2e-test from the key list", fmt.Sprintf("Key file %s does not exist", localKeyPath), "Successfully deleted certificate file:", "e2e-test.crt", "Cleanup completed successfully", @@ -221,7 +221,7 @@ var _ = Describe("notation cert", func() { notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchKeyWords( "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", - "Successfully removed key e2e-test from signingkeys.json", + "Successfully removed key e2e-test from the key list", "Successfully deleted key file:", "e2e-test.key", fmt.Sprintf("Certificate file %s does not exist", localCertPath), "Cleanup completed successfully", @@ -273,7 +273,7 @@ var _ = Describe("notation cert", func() { notation.ExpectFailure().Exec("cert", "cleanup-test", "e2e-test", "-y"). MatchErrKeyWords( - "failed to remove key e2e-test from signingkeys.json", + "failed to remove key e2e-test from the key list", "permission denied", ) }) From 7ab32577a066152478144de8b75f5b98861f548c Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 26 Mar 2025 15:17:59 +0800 Subject: [PATCH 22/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 20 ++++++++++++++------ specs/cmd/certificate.md | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index bdd3e3326..a94eb9a8c 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -50,6 +50,7 @@ func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { return nil }, Long: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command. + Example - Clean up a test key and corresponding certificate named "wabbit-networks.io": notation cert cleanup-test wabbit-networks.io `, @@ -63,7 +64,19 @@ Example - Clean up a test key and corresponding certificate named "wabbit-networ func cleanupTestCert(opts *certCleanupTestOpts) error { name := opts.name - prompt := fmt.Sprintf("Are you sure you want to clean up test key %q and its certificate?", name) + relativeKeyPath, relativeCertPath := dir.LocalKeyPath(name) + configFS := dir.ConfigFS() + certPath, _ := configFS.SysPath(relativeCertPath) // err is always nil + certFileName := filepath.Base(certPath) + keyPath, _ := configFS.SysPath(relativeKeyPath) // err is always nil + + prompt := fmt.Sprintf(`The test key %s and its corresponding certificate will be cleaned up with the following changes: +- Delete certificate %s.crt from trust store %s of type ca +- Remove key %s from the key list +- Delete key file: %s +- Delete certificate file: %s + +Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) confirmed, err := display.AskForConfirmation(os.Stdin, prompt, opts.confirmed) if err != nil { return err @@ -73,10 +86,6 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { } // 1. remove from trust store - relativeKeyPath, relativeCertPath := dir.LocalKeyPath(name) - configFS := dir.ConfigFS() - certPath, _ := configFS.SysPath(relativeCertPath) // err is always nil - certFileName := filepath.Base(certPath) err = truststore.DeleteCert("ca", name, certFileName, true) if err != nil { var pathError *fs.PathError @@ -104,7 +113,6 @@ func cleanupTestCert(opts *certCleanupTestOpts) error { } // 3. delete key and certificate files from LocalKeyPath - keyPath, _ := configFS.SysPath(relativeKeyPath) // err is always nil err = os.Remove(keyPath) if err != nil { var pathError *fs.PathError diff --git a/specs/cmd/certificate.md b/specs/cmd/certificate.md index 9765f48c2..65eb129cc 100644 --- a/specs/cmd/certificate.md +++ b/specs/cmd/certificate.md @@ -148,7 +148,7 @@ Usage: notation certificate cleanup-test [flags] Flags: - -h, --help help for generate-test + -h, --help help for cleanup-test -y, --yes do not prompt for confirmation ``` From 6bbc9ef306fe0f7bf844c148dca7d17a0381b603 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 26 Mar 2025 15:22:13 +0800 Subject: [PATCH 23/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index a94eb9a8c..565c81d32 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -65,11 +65,9 @@ Example - Clean up a test key and corresponding certificate named "wabbit-networ func cleanupTestCert(opts *certCleanupTestOpts) error { name := opts.name relativeKeyPath, relativeCertPath := dir.LocalKeyPath(name) - configFS := dir.ConfigFS() - certPath, _ := configFS.SysPath(relativeCertPath) // err is always nil + certPath, _ := dir.ConfigFS().SysPath(relativeCertPath) // err is always nil certFileName := filepath.Base(certPath) - keyPath, _ := configFS.SysPath(relativeKeyPath) // err is always nil - + keyPath, _ := dir.ConfigFS().SysPath(relativeKeyPath) // err is always nil prompt := fmt.Sprintf(`The test key %s and its corresponding certificate will be cleaned up with the following changes: - Delete certificate %s.crt from trust store %s of type ca - Remove key %s from the key list From ade54ced358f674fdfc28bcbfdf203815c89ac8b Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 26 Mar 2025 16:18:21 +0800 Subject: [PATCH 24/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 16 +++++----- test/e2e/suite/command/cert.go | 50 +++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index 565c81d32..b3fbc8664 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -41,10 +41,10 @@ func certCleanupTestCommand(opts *certCleanupTestOpts) *cobra.Command { Short: `Clean up a test RSA key and its corresponding certificate that were generated using the "generate-test" command.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - return errors.New("missing key name") + return errors.New("missing certificate common name") } if !truststore.IsValidFileName(args[0]) { - return errors.New("key name must follow [a-zA-Z0-9_.-]+ format") + return errors.New("certificate common name must follow [a-zA-Z0-9_.-]+ format") } opts.name = args[0] return nil @@ -86,8 +86,7 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) // 1. remove from trust store err = truststore.DeleteCert("ca", name, certFileName, true) if err != nil { - var pathError *fs.PathError - if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { fmt.Printf("Certificate %s does not exist in trust store %s of type ca\n", certFileName, name) } else { return fmt.Errorf("failed to delete certificate %s from trust store %s of type ca: %w", certFileName, name, err) @@ -101,7 +100,8 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) } err = config.LoadExecSaveSigningKeys(exec) if err != nil { - if errors.Is(err, config.KeyNotFoundError{KeyName: name}) { + var keyNotFoundError config.KeyNotFoundError + if errors.As(err, &keyNotFoundError) { fmt.Printf("Key %s does not exist in the key list\n", name) } else { return fmt.Errorf("failed to remove key %s from the key list: %w", name, err) @@ -113,8 +113,7 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) // 3. delete key and certificate files from LocalKeyPath err = os.Remove(keyPath) if err != nil { - var pathError *fs.PathError - if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { fmt.Printf("Key file %s does not exist\n", keyPath) } else { return fmt.Errorf("failed to delete key file %s: %w", keyPath, err) @@ -124,8 +123,7 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) } err = os.Remove(certPath) if err != nil { - var pathError *fs.PathError - if errors.As(err, &pathError) && errors.Is(pathError, fs.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { fmt.Printf("Certificate file %s does not exist\n", certPath) } else { return fmt.Errorf("failed to delete certificate file %s: %w", certPath, err) diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go index e85ce2b55..ee5ea8f4f 100644 --- a/test/e2e/suite/command/cert.go +++ b/test/e2e/suite/command/cert.go @@ -156,6 +156,48 @@ var _ = Describe("notation cert", func() { }) }) + It("cleanup test with same name more than one time", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "generate-test", "e2e-test"). + MatchKeyWords( + "generating RSA Key with 2048 bits", + "generated certificate expiring on", + "wrote key:", "e2e-test.key", + "wrote certificate:", "e2e-test.crt", + "Successfully added e2e-test.crt to named store e2e-test of type ca", + "e2e-test: added to the key list", + ) + + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + "Successfully removed key e2e-test from the key list", + "Successfully deleted key file:", "e2e-test.key", + "Successfully deleted certificate file:", "e2e-test.crt", + "Cleanup completed successfully", + ) + + notation.Exec("cert", "generate-test", "e2e-test"). + MatchKeyWords( + "generating RSA Key with 2048 bits", + "generated certificate expiring on", + "wrote key:", "e2e-test.key", + "wrote certificate:", "e2e-test.crt", + "Successfully added e2e-test.crt to named store e2e-test of type ca", + "e2e-test: added to the key list", + ) + + notation.Exec("cert", "cleanup-test", "e2e-test", "-y"). + MatchKeyWords( + "Successfully deleted e2e-test.crt from trust store e2e-test of type ca", + "Successfully removed key e2e-test from the key list", + "Successfully deleted key file:", "e2e-test.key", + "Successfully deleted certificate file:", "e2e-test.crt", + "Cleanup completed successfully", + ) + }) + }) + It("cleanup test with key never generated", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { localKeyPath := vhost.AbsolutePath(NotationDirName, LocalKeysDirName, "e2e-test.key") @@ -229,20 +271,20 @@ var _ = Describe("notation cert", func() { }) }) - It("cleanup test missing key name", func() { + It("cleanup test missing certificate common name", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.ExpectFailure().Exec("cert", "cleanup-test"). MatchErrKeyWords( - "missing key name", + "missing certificate common name", ) }) }) - It("cleanup test with empty key name", func() { + It("cleanup test with empty certificate common name", func() { Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { notation.ExpectFailure().Exec("cert", "cleanup-test", ""). MatchErrKeyWords( - "key name must follow [a-zA-Z0-9_.-]+ format", + "certificate common name must follow [a-zA-Z0-9_.-]+ format", ) }) }) From 796337f8caca0de63f7bc51cc78e28bb6e2b523c Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 26 Mar 2025 16:43:13 +0800 Subject: [PATCH 25/25] update Signed-off-by: Patrick Zheng --- cmd/notation/cert/cleanupTest.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/cmd/notation/cert/cleanupTest.go b/cmd/notation/cert/cleanupTest.go index b3fbc8664..5aafc5fc1 100644 --- a/cmd/notation/cert/cleanupTest.go +++ b/cmd/notation/cert/cleanupTest.go @@ -86,11 +86,10 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) // 1. remove from trust store err = truststore.DeleteCert("ca", name, certFileName, true) if err != nil { - if errors.Is(err, fs.ErrNotExist) { - fmt.Printf("Certificate %s does not exist in trust store %s of type ca\n", certFileName, name) - } else { + if !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("failed to delete certificate %s from trust store %s of type ca: %w", certFileName, name, err) } + fmt.Printf("Certificate %s does not exist in trust store %s of type ca\n", certFileName, name) } // 2. remove key from signingkeys.json config @@ -101,11 +100,10 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) err = config.LoadExecSaveSigningKeys(exec) if err != nil { var keyNotFoundError config.KeyNotFoundError - if errors.As(err, &keyNotFoundError) { - fmt.Printf("Key %s does not exist in the key list\n", name) - } else { + if !errors.As(err, &keyNotFoundError) { return fmt.Errorf("failed to remove key %s from the key list: %w", name, err) } + fmt.Printf("Key %s does not exist in the key list\n", name) } else { fmt.Printf("Successfully removed key %s from the key list\n", name) } @@ -113,21 +111,19 @@ Are you sure you want to continue?`, name, name, name, name, keyPath, certPath) // 3. delete key and certificate files from LocalKeyPath err = os.Remove(keyPath) if err != nil { - if errors.Is(err, fs.ErrNotExist) { - fmt.Printf("Key file %s does not exist\n", keyPath) - } else { + if !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("failed to delete key file %s: %w", keyPath, err) } + fmt.Printf("Key file %s does not exist\n", keyPath) } else { fmt.Printf("Successfully deleted key file: %s\n", keyPath) } err = os.Remove(certPath) if err != nil { - if errors.Is(err, fs.ErrNotExist) { - fmt.Printf("Certificate file %s does not exist\n", certPath) - } else { + if !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("failed to delete certificate file %s: %w", certPath, err) } + fmt.Printf("Certificate file %s does not exist\n", certPath) } else { fmt.Printf("Successfully deleted certificate file: %s\n", certPath) }