Add filter option, update Readme
This commit is contained in:
111
cmd/list.go
111
cmd/list.go
@ -4,6 +4,7 @@ import (
|
||||
"os"
|
||||
"fmt"
|
||||
"log"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
"io/ioutil"
|
||||
@ -13,6 +14,46 @@ import (
|
||||
)
|
||||
|
||||
|
||||
// Recurse into structure, returning reflect.Value of wanted field.
|
||||
// Nested fields are named with a dot (ex "MyStruct.MyField")
|
||||
func getStructFieldValue(parentStruct interface{}, fieldName string) (reflect.Value, string, error) {
|
||||
v := reflect.ValueOf(parentStruct)
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if false {
|
||||
for i := 0 ; i < v.NumField(); i++ {
|
||||
f := v.Field(i)
|
||||
if f.Kind() == reflect.String {
|
||||
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(fieldName, ".") {
|
||||
fs := strings.Split(fieldName, ".")
|
||||
f := v.FieldByName(fs[0])
|
||||
if f.Kind() == reflect.Struct {
|
||||
return getStructFieldValue(f.Interface(), strings.Join(fs[1:], "."))
|
||||
} else {
|
||||
log.Fatalln(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String()))
|
||||
}
|
||||
} else {
|
||||
f := v.FieldByName(fieldName)
|
||||
if f.IsValid() {
|
||||
return f, fieldName, nil
|
||||
} else {
|
||||
return v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
|
||||
}
|
||||
}
|
||||
|
||||
return v, fieldName, nil
|
||||
}
|
||||
|
||||
|
||||
// TODO : Replace by getStructFieldValue
|
||||
// Recurse into structure, returning reflect.Value of wanted field.
|
||||
// Nested fields are named with a dot (ex "MyStruct.MyField")
|
||||
func getStructField(parentStruct interface{}, fieldName string) (reflect.Value, string) {
|
||||
@ -101,6 +142,11 @@ func displayStructFields(jails []Jail, valsToDisplay []string) {
|
||||
out = append(out, line)
|
||||
}
|
||||
|
||||
if len(out) == 0 {
|
||||
fmt.Printf("Nothing to see here!\n")
|
||||
return
|
||||
}
|
||||
|
||||
// Get real maximum length
|
||||
maxlen := make([]int, len(valsToDisplay))
|
||||
for i := 0; i< len(valsToDisplay); i++ {
|
||||
@ -173,6 +219,7 @@ func displayStructFields(jails []Jail, valsToDisplay []string) {
|
||||
// Then display data
|
||||
// Loop through lines
|
||||
for _, l := range out {
|
||||
|
||||
// Loop through fields
|
||||
// In case we need to add a line for a 2nd IP, or whatever object
|
||||
var supplines = make(map[string]string)
|
||||
@ -251,29 +298,67 @@ func displayStructFields(jails []Jail, valsToDisplay []string) {
|
||||
|
||||
/* Get Jails from datastores. Store config and running metadata into gJails global var */
|
||||
func ListJails(args []string, display bool) {
|
||||
//fields := []string{"JID", "Name", "Config.Release", "Config.Ip4_addr", "RootPath", "Running", "Config.Jail_zfs", "Config.Jail_zfs_dataset", "Zpool"}
|
||||
//fields := []string{"JID", "Name", "Config.Release", "Config.Ip4_addr", "Running", "Zpool"}
|
||||
fields := strings.Split(gDisplayColumns, ",")
|
||||
|
||||
for _, d := range viper.GetStringSlice("datastore") {
|
||||
listJailsFromDatastore(d)
|
||||
}
|
||||
|
||||
if display {
|
||||
if len(args) > 0 {
|
||||
var js []Jail
|
||||
for _, a := range args {
|
||||
for _, j := range gJails {
|
||||
if j.Name == a {
|
||||
js = append(js, j)
|
||||
break
|
||||
// This is the structure we will filter, then display
|
||||
var jails []Jail
|
||||
|
||||
/************************************************************************************
|
||||
/ Filter jails with "filter" options
|
||||
/***********************************************************************************/
|
||||
if len(gFilterJails) > 0 && gFilterJails != "none" {
|
||||
flts := make(map[string]string)
|
||||
for _, flt := range strings.Split(gFilterJails, ",") {
|
||||
sa := strings.Split(flt, "=")
|
||||
if len(sa) != 2 {
|
||||
fmt.Printf("Invalid format for filter %s\n", gFilterJails)
|
||||
return
|
||||
}
|
||||
flts[sa[0]] = sa[1]
|
||||
}
|
||||
|
||||
if len(flts) > 0 {
|
||||
// Browse global gJails array to get filtered results
|
||||
for _, j := range gJails {
|
||||
for key, val := range flts {
|
||||
v, _, err := getStructFieldValue(&j, key)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: Field %s not found\n", key)
|
||||
return
|
||||
}
|
||||
if strings.EqualFold(fmt.Sprintf("%v", v.Interface()), val) {
|
||||
jails = append(jails, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
displayStructFields(js, fields)
|
||||
} else {
|
||||
displayStructFields(gJails, fields)
|
||||
}
|
||||
} else {
|
||||
jails = gJails
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
/ Filter jails by names given on command line
|
||||
/***********************************************************************************/
|
||||
if len(args) > 0 {
|
||||
var js []Jail
|
||||
for _, a := range args {
|
||||
for _, j := range jails {
|
||||
if j.Name == a {
|
||||
js = append(js, j)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
jails = js
|
||||
}
|
||||
|
||||
if display {
|
||||
displayStructFields(jails, fields)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user