cmd/vulndb/flags.go (114 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. // // 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 main import ( "fmt" "os" "strconv" "strings" "time" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/facebookincubator/nvdtools/vulndb" "github.com/facebookincubator/nvdtools/vulndb/debug" ) var ( // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for DSN. // And libfb/go/fbmysql for fbmysql DSN. gFlagMySQL = os.Getenv("MYSQL") // General purpose flags. gFlagOwner = os.Getenv("USER") gFlagCollector = "" gFlagProvider = "" gFlagMetadata = "" gFlagFormat = "csv" gFlagDeadline deadlineFlag gFlagDeleteAll bool gFlagCSVNoHeader = false ) func init() { fs := RootCmd.PersistentFlags() fs.VarP(&debug.Level, "debug", "v", "set verbosity level") } func addRequiredFlags(cmd *cobra.Command, names ...string) { addFlags(cmd, true, names...) } func addOptionalFlags(cmd *cobra.Command, names ...string) { addFlags(cmd, false, names...) } func addFlags(cmd *cobra.Command, required bool, names ...string) { for _, name := range names { f, exists := supportedFlags[name] if !exists { panic("unsupported flag: " + name) } f(cmd.Flags()) if required { // This requires calling fs.Set for flags that // have a default value. cmd.MarkFlagRequired(name) } } } var supportedFlags = map[string]func(*pflag.FlagSet){ "mysql": func(fs *pflag.FlagSet) { fs.StringVar(&gFlagMySQL, "mysql", gFlagMySQL, "set mysql dsn (or use $MYSQL)") if gFlagMySQL != "" { fs.Set("mysql", gFlagMySQL) } }, "owner": func(fs *pflag.FlagSet) { fs.StringVar(&gFlagOwner, "owner", gFlagOwner, "set owner of the records") fs.Set("owner", gFlagOwner) }, "collector": func(fs *pflag.FlagSet) { fs.StringVar(&gFlagCollector, "collector", gFlagCollector, "set unique name of the data collector") }, "provider": func(fs *pflag.FlagSet) { fs.StringVar(&gFlagProvider, "provider", gFlagProvider, "set short name of the data provider") }, "metadata": func(fs *pflag.FlagSet) { fs.StringVar(&gFlagMetadata, "metadata", gFlagMetadata, "set metadata") }, "format": func(fs *pflag.FlagSet) { fs.StringVar(&gFlagFormat, "format", gFlagFormat, "set output format (csv or nvdcvejson)") fs.Set("format", gFlagFormat) }, "deadline": func(fs *pflag.FlagSet) { fs.Var(&gFlagDeadline, "deadline", fmt.Sprintf("set deadline in absolute time or duration (e.g. %s or 24h, 30d)", vulndb.TimeLayout)) }, "delete_all": func(fs *pflag.FlagSet) { fs.BoolVarP(&gFlagDeleteAll, "all", "a", gFlagDeleteAll, "delete all records from database") }, "csv_noheader": func(fs *pflag.FlagSet) { fs.BoolVarP(&gFlagCSVNoHeader, "csvnoheader", "n", gFlagCSVNoHeader, "omit csv header in output") }, } // deadlineFlag implements the pflag.Value interface. type deadlineFlag struct { Time time.Time } func (d *deadlineFlag) Type() string { return "string" } func (d *deadlineFlag) String() string { if d.Time.IsZero() { return "" } return d.Time.String() } // Set sets v as the deadline's time. Takes same input as time.ParseDuration // but supports using 'd' (e.g. 30d) for representing days as d*24h. func (d *deadlineFlag) Set(v string) error { t, err := vulndb.ParseTime(v) if err == nil { d.Time = t return nil } dd, err := time.ParseDuration(v) if err == nil { d.Time = time.Now().Add(dd) return nil } idx := strings.Index(v, "d") if idx < 1 { return fmt.Errorf("invalid deadline: %q", v) } n, err := strconv.Atoi(v[0:idx]) if err != nil { return fmt.Errorf("invalid deadline: %q", v) } dd, _ = time.ParseDuration(strconv.Itoa(n*24) + "h") d.Time = time.Now().Add(dd) return nil }