Skip to content

Commit

Permalink
update: properly handle assets dir when installing assets
Browse files Browse the repository at this point in the history
Signed-off-by: Lorenzo Susini <[email protected]>
  • Loading branch information
loresuso committed Jul 31, 2023
1 parent cec33fa commit 83f13d1
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 47 deletions.
47 changes: 28 additions & 19 deletions cmd/artifact/follow/follow.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ Example - Install and follow "cloudtrail" plugins using a fully qualified refere
type artifactFollowOptions struct {
*options.CommonOptions
*options.RegistryOptions
rulesfilesDir string
pluginsDir string
*options.DirectoryOptions
tmpDir string
every time.Duration
cron string
Expand All @@ -96,10 +95,11 @@ type artifactFollowOptions struct {
// NewArtifactFollowCmd returns the artifact follow command.
func NewArtifactFollowCmd(ctx context.Context, opt *options.CommonOptions) *cobra.Command {
o := artifactFollowOptions{
CommonOptions: opt,
RegistryOptions: &options.RegistryOptions{},
closeChan: make(chan bool),
versions: config.FalcoVersions{},
CommonOptions: opt,
RegistryOptions: &options.RegistryOptions{},
DirectoryOptions: &options.DirectoryOptions{},
closeChan: make(chan bool),
versions: config.FalcoVersions{},
}

cmd := &cobra.Command{
Expand Down Expand Up @@ -146,26 +146,38 @@ func NewArtifactFollowCmd(ctx context.Context, opt *options.CommonOptions) *cobr
}

// Override "rulesfiles-dir" flag with viper config if not set by user.
f = cmd.Flags().Lookup(install.FlagRulesFilesDir)
f = cmd.Flags().Lookup(options.FlagRulesFilesDir)
if f == nil {
// should never happen
return fmt.Errorf("unable to retrieve flag %q", install.FlagRulesFilesDir)
return fmt.Errorf("unable to retrieve flag %q", options.FlagRulesFilesDir)
} else if !f.Changed && viper.IsSet(config.ArtifactFollowRulesfilesDirKey) {
val := viper.Get(config.ArtifactFollowRulesfilesDirKey)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
return fmt.Errorf("unable to overwrite %q flag: %w", install.FlagRulesFilesDir, err)
return fmt.Errorf("unable to overwrite %q flag: %w", options.FlagRulesFilesDir, err)
}
}

// Override "plugins-dir" flag with viper config if not set by user.
f = cmd.Flags().Lookup(install.FlagPluginsFilesDir)
f = cmd.Flags().Lookup(options.FlagPluginsFilesDir)
if f == nil {
// should never happen
return fmt.Errorf("unable to retrieve flag %q", install.FlagPluginsFilesDir)
return fmt.Errorf("unable to retrieve flag %q", options.FlagPluginsFilesDir)
} else if !f.Changed && viper.IsSet(config.ArtifactFollowPluginsDirKey) {
val := viper.Get(config.ArtifactFollowPluginsDirKey)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
return fmt.Errorf("unable to overwrite %q flag: %w", install.FlagPluginsFilesDir, err)
return fmt.Errorf("unable to overwrite %q flag: %w", options.FlagPluginsFilesDir, err)
}
}

// Override "assets-dir" flag with viper config if not set by user.
f = cmd.Flags().Lookup(options.FlagAssetsFilesDir)
if f == nil {
// should never happen
return fmt.Errorf("unable to retrieve flag %q", options.FlagAssetsFilesDir)
} else if !f.Changed && viper.IsSet(config.ArtifactFollowAssetsDirKey) {
val := viper.Get(config.ArtifactFollowAssetsDirKey)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
return fmt.Errorf("unable to overwrite %q flag: %w", options.FlagAssetsFilesDir, err)
}
}

Expand Down Expand Up @@ -221,15 +233,11 @@ func NewArtifactFollowCmd(ctx context.Context, opt *options.CommonOptions) *cobr
}

o.RegistryOptions.AddFlags(cmd)
o.DirectoryOptions.AddFlags(cmd)
cmd.Flags().DurationVarP(&o.every, "every", "e", config.FollowResync, "Time interval how often it checks for a new version of the "+
"artifact. Cannot be used together with 'cron' option.")
cmd.Flags().StringVar(&o.cron, "cron", "", "Cron-like string to specify interval how often it checks for a new version of the artifact."+
" Cannot be used together with 'every' option.")
// TODO (alacuku): move it in a dedicate data structure since they are in common with artifactInstall command.
cmd.Flags().StringVarP(&o.rulesfilesDir, install.FlagRulesFilesDir, "", config.RulesfilesDir,
"Directory where to install rules")
cmd.Flags().StringVarP(&o.pluginsDir, install.FlagPluginsFilesDir, "", config.PluginsDir,
"Directory where to install plugins")
cmd.Flags().StringVar(&o.tmpDir, "tmp-dir", "", "Directory where to save temporary files")
cmd.Flags().StringVar(&o.falcoVersions, "falco-versions", "http://localhost:8765/versions",
"Where to retrieve versions, it can be either an URL or a path to a file")
Expand Down Expand Up @@ -298,8 +306,9 @@ func (o *artifactFollowOptions) RunArtifactFollow(ctx context.Context, args []st
cfg := &follower.Config{
WaitGroup: &wg,
Resync: sched,
RulesfilesDir: o.rulesfilesDir,
PluginsDir: o.pluginsDir,
RulesfilesDir: o.RulesfilesDir,
PluginsDir: o.PluginsDir,
AssetsDir: o.AssetsDir,
ArtifactReference: ref,
PlainHTTP: o.PlainHTTP,
Verbose: o.IsVerbose(),
Expand Down
7 changes: 0 additions & 7 deletions cmd/artifact/install/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@
package install

const (

// FlagRulesFilesDir is the name of the flag to specify the directory path of the rules files.
FlagRulesFilesDir = "rulesfiles-dir"

// FlagPluginsFilesDir is the name of the flag to specify the directory path of the plugins.
FlagPluginsFilesDir = "plugins-dir"

// FlagAllowedTypes is the name of the flag to specify allowed artifact types.
FlagAllowedTypes = "allowed-types"

Expand Down
51 changes: 32 additions & 19 deletions cmd/artifact/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,18 @@ Example - Install "cloudtrail" plugins using a fully qualified reference:
type artifactInstallOptions struct {
*options.CommonOptions
*options.RegistryOptions
rulesfilesDir string
pluginsDir string
allowedTypes oci.ArtifactTypeSlice
resolveDeps bool
noVerify bool
*options.DirectoryOptions
allowedTypes oci.ArtifactTypeSlice
resolveDeps bool
noVerify bool
}

// NewArtifactInstallCmd returns the artifact install command.
func NewArtifactInstallCmd(ctx context.Context, opt *options.CommonOptions) *cobra.Command {
o := artifactInstallOptions{
CommonOptions: opt,
RegistryOptions: &options.RegistryOptions{},
CommonOptions: opt,
RegistryOptions: &options.RegistryOptions{},
DirectoryOptions: &options.DirectoryOptions{},
}

cmd := &cobra.Command{
Expand All @@ -94,26 +94,38 @@ func NewArtifactInstallCmd(ctx context.Context, opt *options.CommonOptions) *cob
SilenceUsage: true,
PreRunE: func(cmd *cobra.Command, args []string) error {
// Override "rulesfiles-dir" flag with viper config if not set by user.
f := cmd.Flags().Lookup(FlagRulesFilesDir)
f := cmd.Flags().Lookup(options.FlagRulesFilesDir)
if f == nil {
// should never happen
return fmt.Errorf("unable to retrieve flag %q", FlagRulesFilesDir)
return fmt.Errorf("unable to retrieve flag %q", options.FlagRulesFilesDir)
} else if !f.Changed && viper.IsSet(config.ArtifactInstallRulesfilesDirKey) {
val := viper.Get(config.ArtifactInstallRulesfilesDirKey)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
return fmt.Errorf("unable to overwrite %q flag: %w", FlagRulesFilesDir, err)
return fmt.Errorf("unable to overwrite %q flag: %w", options.FlagRulesFilesDir, err)
}
}

// Override "plugins-dir" flag with viper config if not set by user.
f = cmd.Flags().Lookup(FlagPluginsFilesDir)
f = cmd.Flags().Lookup(options.FlagPluginsFilesDir)
if f == nil {
// should never happen
return fmt.Errorf("unable to retrieve flag %q", FlagPluginsFilesDir)
return fmt.Errorf("unable to retrieve flag %q", options.FlagPluginsFilesDir)
} else if !f.Changed && viper.IsSet(config.ArtifactInstallPluginsDirKey) {
val := viper.Get(config.ArtifactInstallPluginsDirKey)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
return fmt.Errorf("unable to overwrite %q flag: %w", FlagPluginsFilesDir, err)
return fmt.Errorf("unable to overwrite %q flag: %w", options.FlagPluginsFilesDir, err)
}
}

// Override "assets-dir" flag with viper config if not set by user.
f = cmd.Flags().Lookup(options.FlagAssetsFilesDir)
if f == nil {
// should never happen
return fmt.Errorf("unable to retrieve flag %q", options.FlagAssetsFilesDir)
} else if !f.Changed && viper.IsSet(config.ArtifactFollowAssetsDirKey) {
val := viper.Get(config.ArtifactFollowAssetsDirKey)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
return fmt.Errorf("unable to overwrite %q flag: %w", options.FlagAssetsFilesDir, err)
}
}

Expand Down Expand Up @@ -162,10 +174,7 @@ func NewArtifactInstallCmd(ctx context.Context, opt *options.CommonOptions) *cob
}

o.RegistryOptions.AddFlags(cmd)
cmd.Flags().StringVarP(&o.rulesfilesDir, FlagRulesFilesDir, "", config.RulesfilesDir,
"directory where to install rules.")
cmd.Flags().StringVarP(&o.pluginsDir, FlagPluginsFilesDir, "", config.PluginsDir,
"directory where to install plugins.")
o.DirectoryOptions.AddFlags(cmd)
cmd.Flags().Var(&o.allowedTypes, FlagAllowedTypes,
fmt.Sprintf(`list of artifact types that can be installed. If not specified or configured, all types are allowed.
It accepts comma separated values or it can be repeated multiple times.
Expand Down Expand Up @@ -300,9 +309,13 @@ func (o *artifactInstallOptions) RunArtifactInstall(ctx context.Context, args []
var destDir string
switch result.Type {
case oci.Plugin:
destDir = o.pluginsDir
destDir = o.PluginsDir
case oci.Rulesfile:
destDir = o.rulesfilesDir
destDir = o.RulesfilesDir
case oci.Asset:
destDir = o.AssetsDir
default:
return fmt.Errorf("unrecognized result type %q while pulling artifact", result.Type)
}

// Check if directory exists and is writable.
Expand Down
6 changes: 6 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ const (
PluginsDir = "/usr/share/falco/plugins"
// RulesfilesDir default path where rulesfiles are installed.
RulesfilesDir = "/etc/falco"
// AssetsDir default path where assets are installed.
AssetsDir = "/etc/falco/assets"
// FollowResync time interval how often it checks for newer version of the artifact.
// Default values is set every 24 hours.
FollowResync = time.Hour * 24
Expand Down Expand Up @@ -94,6 +96,8 @@ const (
ArtifactFollowRulesfilesDirKey = "artifact.follow.rulesfilesdir"
// ArtifactFollowPluginsDirKey is the Viper key for follower "pluginsDir" configuration.
ArtifactFollowPluginsDirKey = "artifact.follow.pluginsdir"
// ArtifactFollowAssetsDirKey is the Viper key for follower "pluginsDir" configuration.
ArtifactFollowAssetsDirKey = "artifact.follow.assetsdir"
// ArtifactFollowTmpDirKey is the Viper key for follower "pluginsDir" configuration.
ArtifactFollowTmpDirKey = "artifact.follow.tmpdir"
// ArtifactInstallArtifactsKey is the Viper key for installer "artifacts" configuration.
Expand All @@ -102,6 +106,8 @@ const (
ArtifactInstallRulesfilesDirKey = "artifact.install.rulesfilesdir"
// ArtifactInstallPluginsDirKey is the Viper key for follower "pluginsDir" configuration.
ArtifactInstallPluginsDirKey = "artifact.install.pluginsdir"
// ArtifactInstallAssetsDirKey is the Viper key for follower "pluginsDir" configuration.
ArtifactInstallAssetsDirKey = "artifact.install.assetsdir"
// ArtifactInstallResolveDepsKey is the Viper key for installer "resolveDeps" configuration.
ArtifactInstallResolveDepsKey = "artifact.install.resolveDeps"
// ArtifactAllowedTypesKey is the Viper key for the whitelist of artifacts to be installed in the system.
Expand Down
8 changes: 6 additions & 2 deletions internal/follower/follower.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ type Config struct {
CloseChan <-chan bool
// Resync time after which periodically it checks for new a new version.
Resync cron.Schedule
// RulesfileDir directory where the rulesfile are stored.
// RulesfilesDir directory where the rulesfile are stored.
RulesfilesDir string
// PluginsDir directory where the plugins are stored.
// PluginsDir directory where plugins are stored.
PluginsDir string
// AssetsDir directory where assets are stored.
AssetsDir string
// ArtifactReference reference to the artifact in a remote repository.
ArtifactReference string
// PlainHTTP is set to true if all registry interaction must be in plain http.
Expand Down Expand Up @@ -302,6 +304,8 @@ func (f *Follower) destinationDir(res *oci.RegistryResult) string {
dir = f.PluginsDir
case oci.Rulesfile:
dir = f.RulesfilesDir
case oci.Asset:
dir = f.AssetsDir
}
return dir
}
Expand Down
51 changes: 51 additions & 0 deletions pkg/options/directory_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2023 The Falco 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 options

import (
"github.com/falcosecurity/falcoctl/internal/config"

Check failure on line 18 in pkg/options/directory_options.go

View workflow job for this annotation

GitHub Actions / Lint golang files

File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/falcosecurity/falcoctl) (gci)
"github.com/spf13/cobra"

Check failure on line 19 in pkg/options/directory_options.go

View workflow job for this annotation

GitHub Actions / Lint golang files

File is not `gci`-ed with --skip-generated -s standard,default,prefix(github.com/falcosecurity/falcoctl) (gci)
)

const (
// FlagRulesFilesDir is the name of the flag to specify the directory path of rules files.
FlagRulesFilesDir = "rulesfiles-dir"

// FlagPluginsFilesDir is the name of the flag to specify the directory path of plugins.
FlagPluginsFilesDir = "plugins-dir"

// FlagAssetsFilesDir is the name of the flag to specify the directory path of assets.
FlagAssetsFilesDir = "assets-dir"
)

// DirectoryOptions options for install directories for atifacts.
type DirectoryOptions struct {
// RulesfilesDir path where rule are installed
RulesfilesDir string
// PluginsDir path where plugins are installed
PluginsDir string
// AssetsDire path where assets are installed
AssetsDir string
}

// AddFlags registers the directories flags.
func (o *DirectoryOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.RulesfilesDir, FlagRulesFilesDir, "", config.RulesfilesDir,
"Directory where to install rules")
cmd.Flags().StringVarP(&o.PluginsDir, FlagPluginsFilesDir, "", config.PluginsDir,
"Directory where to install plugins")
cmd.Flags().StringVarP(&o.AssetsDir, FlagAssetsFilesDir, "", config.AssetsDir,
"Directory where to install assets")
}

0 comments on commit 83f13d1

Please sign in to comment.