-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a show command to the Diki CLI #412
Changes from 10 commits
70446dc
5c608f6
a69a4d4
d8ae1c3
30719f1
686523d
1de2bb0
619ac19
6a31e32
d4a4f1c
c5e8f5e
688fadc
99e3b2e
683c7b5
98adb5e
9011efd
ff6f2e6
03bc32a
95bc6bd
98131a6
7e20b39
afe1993
d5ac7d0
94a0128
271e590
7ca3599
8fbdbce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -20,7 +20,9 @@ import ( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"k8s.io/component-base/version" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/gardener/diki/pkg/config" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/gardener/diki/pkg/metadata" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/gardener/diki/pkg/provider" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/gardener/diki/pkg/provider/builder" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/gardener/diki/pkg/report" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/gardener/diki/pkg/ruleset" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -124,6 +126,28 @@ e.g. to check compliance of your hyperscaler accounts.`, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
addReportGenerateDiffFlags(generateDiffCmd, &generateDiffOpts) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
generateCmd.AddCommand(generateDiffCmd) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showCmd := &cobra.Command{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Use: "show", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Short: "Show metadata of the providers that the current diki binary supports.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Long: "Show metadata of the providers that the current diki binary supports.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RunE: func(_ *cobra.Command, _ []string) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return errors.New("show subcommand not selected") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rootCmd.AddCommand(showCmd) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showProviderCmd := &cobra.Command{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Use: "provider", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Short: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Long: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RunE: func(_ *cobra.Command, args []string) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return showProviderCmd(args) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showCmd.AddCommand(showProviderCmd) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return rootCmd | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -156,6 +180,51 @@ func addReportGenerateDiffFlags(cmd *cobra.Command, opts *generateDiffOptions) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cmd.PersistentFlags().Var(cliflag.NewMapStringString(&opts.identityAttributes), "identity-attributes", "The keys are the IDs of the providers that will be present in the generated difference report and the values are metadata attributes to be used as identifiers.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func showProviderCmd(args []string) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if len(args) > 1 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return errors.New("command `show provider` accepts at most one provider") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
providerFuncMap = map[string]func() metadata.ProviderMetadata{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"gardener": builder.GardenerProviderMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"garden": builder.GardenProviderMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"managedk8s": builder.ManagedK8SProviderMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"virtualgarden": builder.VirtualGardenProviderMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is this customizable when it is hardcoded here? I would not be able to configure it through main.go. Please see how the command accepts builder functions through main.go and do the same for these. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if len(args) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
providersMetadata := []metadata.Provider{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's stay consistent with the slice initializations.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for providerID := range providerFuncMap { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
providersMetadata = append(providersMetadata, metadata.Provider{ProviderID: providerID, ProviderName: providerFuncMap[providerID]().ProviderName}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if bytes, err := json.Marshal(providersMetadata); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fmt.Println(string(bytes)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dimityrmirchev marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var providerArg = args[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
metadataFunc, ok := providerFuncMap[providerArg] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return fmt.Errorf("provider %s does not exist in the current diki binary", providerArg) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
providerMetadata := metadataFunc() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if bytes, err := json.Marshal(providerMetadata); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fmt.Println(string(bytes)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func generateDiffCmd(args []string, generateDiffOpts generateDiffOptions, rootOpts reportOptions, logger *slog.Logger) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if len(args) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return errors.New("generate diff command requires a minimum of one filepath argument") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||||||||
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Gardener contributors | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// | ||||||||||||
// SPDX-License-Identifier: Apache-2.0 | ||||||||||||
|
||||||||||||
package metadata | ||||||||||||
|
||||||||||||
// Version is used to represent a specific version of a ruleset | ||||||||||||
type Version struct { | ||||||||||||
// Version is the human-readable name of the ruleset release | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
Version string `json:"version"` | ||||||||||||
// Latest is a bool tag that showcases if the specific version is the latest one | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
Latest bool `json:"latest"` | ||||||||||||
} | ||||||||||||
|
||||||||||||
// RulesetMetadata is used to represent a specific ruleset and it's metadata | ||||||||||||
type RulesetMetadata struct { | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// RulesetID is the unique identifier of the ruleset | ||||||||||||
RulesetID string `json:"rulesetID"` | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// RulesetName is the user-friendly name of the ruleset | ||||||||||||
RulesetName string `json:"rulesetName"` | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// Versions is used to showcase the supported versions of the specific ruleset | ||||||||||||
Versions []Version `json:"versions"` | ||||||||||||
} | ||||||||||||
|
||||||||||||
// Provider is used to represent an available provider by it's name and unique identifier | ||||||||||||
type Provider struct { | ||||||||||||
// ProviderID is the unique identifier of the provider | ||||||||||||
ProviderID string `json:"id"` | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// ProviderName is the user-friendly name of the provider | ||||||||||||
ProviderName string `json:"name"` | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
} | ||||||||||||
|
||||||||||||
// ProviderMetadata is used to represent a specific provider and it's metadata | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put dots at the end of all sentences. |
||||||||||||
type ProviderMetadata struct { | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// ProviderID is the unique identifier of the provider | ||||||||||||
ProviderID string `json:"providerID"` | ||||||||||||
// ProviderName is the user-friendly name of the provider | ||||||||||||
ProviderName string `json:"providerName"` | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
// ProviderRulesets is a list of rulesets supported by the specific provider | ||||||||||||
ProviderRulesets []RulesetMetadata `json:"rulesets"` | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -9,6 +9,7 @@ import ( | |||||||||
"log/slog" | ||||||||||
|
||||||||||
"github.com/gardener/diki/pkg/config" | ||||||||||
"github.com/gardener/diki/pkg/metadata" | ||||||||||
"github.com/gardener/diki/pkg/provider" | ||||||||||
"github.com/gardener/diki/pkg/provider/garden" | ||||||||||
"github.com/gardener/diki/pkg/provider/garden/ruleset/securityhardenedshoot" | ||||||||||
|
@@ -48,3 +49,42 @@ func GardenProviderFromConfig(conf config.ProviderConfig) (provider.Provider, er | |||||||||
|
||||||||||
return p, nil | ||||||||||
} | ||||||||||
|
||||||||||
// gardenGetSupportedVersions returns the Supported Versions of a specific ruleset that is supported by the Garden provider. | ||||||||||
func gardenGetSupportedVersions(ruleset string) []string { | ||||||||||
switch ruleset { | ||||||||||
case securityhardenedshoot.RulesetID: | ||||||||||
return securityhardenedshoot.SupportedVersions | ||||||||||
default: | ||||||||||
return nil | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
// GardenProviderMetadata returns available metadata for the Garden Provider and it's supported rulesets. | ||||||||||
func GardenProviderMetadata() metadata.ProviderMetadata { | ||||||||||
providerMetadata := metadata.ProviderMetadata{} | ||||||||||
providerMetadata.ProviderID = "garden" | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would not be correct if the provider id changes here Lines 19 to 22 in a4a8e8f
We should either fix the provider id to a constant or not hardcode it here. |
||||||||||
providerMetadata.ProviderName = "Garden" | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||
|
||||||||||
var availableRulesets = map[string]string{ | ||||||||||
securityhardenedshoot.RulesetID: securityhardenedshoot.RulesetName, | ||||||||||
} | ||||||||||
|
||||||||||
for rulesetID, rulesetName := range availableRulesets { | ||||||||||
rulesetMetadata := &metadata.RulesetMetadata{} | ||||||||||
rulesetMetadata.RulesetID = rulesetID | ||||||||||
rulesetMetadata.RulesetName = rulesetName | ||||||||||
rulesetSupportedVersions := gardenGetSupportedVersions(rulesetMetadata.RulesetID) | ||||||||||
|
||||||||||
for index, supportedVersion := range rulesetSupportedVersions { | ||||||||||
if index == 0 { | ||||||||||
rulesetMetadata.Versions = append(rulesetMetadata.Versions, metadata.Version{Version: supportedVersion, Latest: true}) | ||||||||||
} else { | ||||||||||
rulesetMetadata.Versions = append(rulesetMetadata.Versions, metadata.Version{Version: supportedVersion, Latest: false}) | ||||||||||
} | ||||||||||
} | ||||||||||
providerMetadata.ProviderRulesets = append(providerMetadata.ProviderRulesets, *rulesetMetadata) | ||||||||||
} | ||||||||||
|
||||||||||
return providerMetadata | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just initialize the structs? providerMetadata := metadata.ProviderMetadata{
ProviderID: "garden",
ProviderName: "Garden",
ProviderRulesets: []metadata.RulesetMetadata{
{
RulesetID: securityhardenedshoot.RulesetID,
RulesetName: securityhardenedshoot.RulesetName,
},
},
}
for i := range providerMetadata.ProviderRulesets {
supportedVersions := gardenGetSupportedVersions(providerMetadata.ProviderRulesets[i].RulesetID)
for _, supportedVersion := range supportedVersions {
providerMetadata.ProviderRulesets[i].Versions = append(
providerMetadata.ProviderRulesets[i].Versions,
metadata.Version{Version: supportedVersion, Latest: false},
)
}
// Mark the first version as latest as the versions are sorted from newest to oldest
if len(providerMetadata.ProviderRulesets[i].Versions) > 0 {
providerMetadata.ProviderRulesets[i].Versions[0].Latest = true
}
}
return providerMetadata |
||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.