-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve separation between type implementations and CLI code (#339)
* Refactor PKI factory and add type checking This allows for more DRY addition of new PKI types, and stricter type checking. This also allows for simpler enumeration of supported PKI formats which will be used in further updates to simplify the CLI codebase. Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * revamp CLI flags; support different versions for upload Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * Add Alpine Package type This adds support for the alpine package format used by Alpine Linux, which is the concatenation of three tgz files (signature, control data, and then the actual package files). Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * use shaFlag for --artifact-hash Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * change arg type to PKIFormat Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * defer type-specific validation logic to type code (instead of in CLI); also use CliLogger throughout CLI Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * refactor factory code Signed-off-by: Bob Callaway <bob.callaway@gmail.com> * review comments Signed-off-by: Bob Callaway <bob.callaway@gmail.com>
- Loading branch information
1 parent
e63fe71
commit 53d71cd
Showing
51 changed files
with
1,399 additions
and
1,195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,5 +153,6 @@ var logInfoCmd = &cobra.Command{ | |
} | ||
|
||
func init() { | ||
initializePFlagMap() | ||
rootCmd.AddCommand(logInfoCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
// | ||
// Copyright 2021 The Sigstore 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 app | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/url" | ||
"strings" | ||
|
||
"github.com/sigstore/rekor/pkg/pki" | ||
"github.com/sigstore/rekor/pkg/types" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
// addFlagToCmd adds the specified command of a specified type to the command's flag set | ||
func addFlagToCmd(cmd *cobra.Command, required bool, flagType FlagType, flag, desc string) error { | ||
cmd.Flags().Var(NewFlagValue(flagType, ""), flag, desc) | ||
if required { | ||
return cmd.MarkFlagRequired(flag) | ||
} | ||
return nil | ||
} | ||
|
||
// addLogIndexFlag adds the "log-index" command to the command's flag set | ||
func addLogIndexFlag(cmd *cobra.Command, required bool) error { | ||
return addFlagToCmd(cmd, required, logIndexFlag, "log-index", "the index of the entry in the transparency log") | ||
} | ||
|
||
// addUUIDPFlags adds the "uuid" command to the command's flag set | ||
func addUUIDPFlags(cmd *cobra.Command, required bool) error { | ||
return addFlagToCmd(cmd, required, uuidFlag, "uuid", "UUID of entry in transparency log (if known)") | ||
} | ||
|
||
func addArtifactPFlags(cmd *cobra.Command) error { | ||
flags := map[string]struct { | ||
flagType FlagType | ||
desc string | ||
required bool | ||
}{ | ||
"signature": { | ||
fileOrURLFlag, | ||
"path or URL to detached signature file", | ||
false, | ||
}, | ||
"type": { | ||
typeFlag, | ||
fmt.Sprintf("type of entry expressed as type(:version)?; supported types = %v", types.ListImplementedTypes()), | ||
false, | ||
}, | ||
"pki-format": { | ||
pkiFormatFlag, | ||
fmt.Sprintf("format of the signature and/or public key; options = %v", pki.SupportedFormats()), | ||
false, | ||
}, | ||
"public-key": { | ||
fileOrURLFlag, | ||
"path or URL to public key file", | ||
false, | ||
}, | ||
"artifact": { | ||
fileOrURLFlag, | ||
"path or URL to artifact file", | ||
false, | ||
}, | ||
"artifact-hash": { | ||
shaFlag, | ||
"hex encoded SHA256 hash of artifact (when using URL)", | ||
false, | ||
}, | ||
"entry": { | ||
fileOrURLFlag, | ||
"path or URL to pre-formatted entry file", | ||
false, | ||
}, | ||
} | ||
|
||
for flag, flagVal := range flags { | ||
if err := addFlagToCmd(cmd, flagVal.required, flagVal.flagType, flag, flagVal.desc); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func validateArtifactPFlags(uuidValid, indexValid bool) error { | ||
uuidGiven := false | ||
if uuidValid && viper.GetString("uuid") != "" { | ||
uuidGiven = true | ||
} | ||
indexGiven := false | ||
if indexValid && viper.GetString("log-index") != "" { | ||
indexGiven = true | ||
} | ||
|
||
// if neither --entry or --artifact were given, then a reference to a uuid or index is needed | ||
if viper.GetString("entry") == "" && viper.GetString("artifact") == "" { | ||
if (uuidGiven && uuidValid) || (indexGiven && indexValid) { | ||
return nil | ||
} | ||
return errors.New("either 'entry' or 'artifact' must be specified") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func CreatePropsFromPflags() *types.ArtifactProperties { | ||
props := &types.ArtifactProperties{} | ||
|
||
artifactString := viper.GetString("artifact") | ||
if artifactString != "" { | ||
if isURL(artifactString) { | ||
props.ArtifactPath, _ = url.Parse(artifactString) | ||
} else { | ||
props.ArtifactPath = &url.URL{Path: artifactString} | ||
} | ||
} | ||
|
||
props.ArtifactHash = viper.GetString("artifact-hash") | ||
|
||
signatureString := viper.GetString("signature") | ||
if signatureString != "" { | ||
if isURL(signatureString) { | ||
props.SignaturePath, _ = url.Parse(signatureString) | ||
} else { | ||
props.SignaturePath = &url.URL{Path: signatureString} | ||
} | ||
} | ||
|
||
publicKeyString := viper.GetString("public-key") | ||
if publicKeyString != "" { | ||
if isURL(publicKeyString) { | ||
props.PublicKeyPath, _ = url.Parse(publicKeyString) | ||
} else { | ||
props.PublicKeyPath = &url.URL{Path: publicKeyString} | ||
} | ||
} | ||
|
||
props.PKIFormat = viper.GetString("pki-format") | ||
|
||
return props | ||
} | ||
|
||
//TODO: add tests for this | ||
func ParseTypeFlag(typeStr string) (string, string, error) { | ||
// typeStr can come in as: | ||
// type -> use default version for this kind | ||
// type:version_string -> attempt to use specified version string | ||
|
||
typeStrings := strings.SplitN(typeStr, ":", 2) | ||
if _, ok := types.TypeMap.Load(typeStrings[0]); !ok { | ||
return "", "", fmt.Errorf("unknown type %v", typeStrings[0]) | ||
} | ||
|
||
switch len(typeStrings) { | ||
case 1: | ||
return typeStrings[0], "", nil | ||
case 2: | ||
return typeStrings[0], typeStrings[1], nil | ||
} | ||
return "", "", errors.New("malformed type string") | ||
} |
Oops, something went wrong.