Initial CLI and file format for fleetctl

This PR implements a program called `fleetctl` which scaffolds a high level CLI interface which can be used to manage a Fleet server. Configuration is articulated using an intent-based API that resembles the API that is used to configure Kubernetes clusters. The idea here is to use the Kubernetes file format as a pattern to reduce the need for operators to become too intimately familiar with dramatically different file formats. (#1578)
This commit is contained in:
Mike Arpaia 2017-11-12 11:58:19 -07:00 committed by GitHub
parent 3ed772a251
commit 796e0af8be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 363 additions and 1 deletions

View file

@ -97,9 +97,17 @@ endif
.pre-fleet:
$(eval APP_NAME = fleet)
build: .prefix .pre-build .pre-fleet
.pre-fleetctl:
$(eval APP_NAME = fleetctl)
build: fleet
fleet: .prefix .pre-build .pre-fleet
go build -i -o build/${OUTPUT} -ldflags ${KIT_VERSION} ./cmd/fleet
fleetctl: .prefix .pre-build .pre-fleetctl
go build -i -o build/fleetctl -ldflags ${KIT_VERSION} ./cmd/fleetctl
lint-js:
eslint frontend --ext .js,.jsx

80
cmd/fleetctl/fleetctl.go Normal file
View file

@ -0,0 +1,80 @@
package main
import (
"fmt"
"os"
"strings"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/kolide/kit/logutil"
"github.com/kolide/kit/version"
)
func runVersion(args []string) error {
version.PrintFull()
return nil
}
func runNoop(args []string) error {
fmt.Printf("%+v\n", args)
return nil
}
type runFunc func([]string) error
type subcommandMap map[string]runFunc
type commandMap map[string]subcommandMap
func usage() {
fmt.Fprintf(os.Stderr, "fleetctl controls an instance of the Kolide Fleet osquery fleet manager.\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, "Find more information at https://kolide.com/fleet\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " Usage:\n")
fmt.Fprintf(os.Stderr, " fleetctl [command] [flags]\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " Commands:\n")
fmt.Fprintf(os.Stderr, " fleetctl query - run a query across your fleet\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " fleetctl apply - apply a set of osquery configurations\n")
fmt.Fprintf(os.Stderr, " fleetctl edit - edit your complete configuration in an ephemeral editor\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " fleetctl help - get help on how to define an intent type\n")
fmt.Fprintf(os.Stderr, " fleetctl version - print full version information\n")
fmt.Fprintf(os.Stderr, "\n")
}
func main() {
logger := level.NewFilter(log.NewJSONLogger(os.Stderr), level.AllowDebug())
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
logger = log.With(logger, "caller", log.DefaultCaller)
if len(os.Args) < 2 {
usage()
os.Exit(0)
}
var run func([]string) error
switch strings.ToLower(os.Args[1]) {
case "version":
run = runVersion
case "query":
run = runNoop
case "edit":
run = runNoop
case "new":
run = runNoop
case "apply":
run = runNoop
case "help":
run = runNoop
default:
usage()
os.Exit(1)
}
if err := run(os.Args[2:]); err != nil {
logutil.Fatal(logger, "err", err)
}
}

54
examples/combine.go Normal file
View file

@ -0,0 +1,54 @@
package main
import (
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
func walk(f *os.File) func(path string, info os.FileInfo, err error) error {
return func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
content, err := ioutil.ReadFile(path)
if err != nil {
log.Fatal(err)
}
if _, err := f.WriteString(string(content) + "---\n"); err != nil {
log.Fatal(err)
}
return nil
}
}
func main() {
inputDir := "./examples/config-intent-files"
outputFile := "./examples/config-intent.yml"
if err := os.Truncate(outputFile, 0); err != nil {
log.Fatal(err)
}
f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := filepath.Walk(inputDir, walk(f)); err != nil {
log.Fatal(err)
}
f.Close()
content, err := ioutil.ReadFile(outputFile)
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(outputFile, []byte(strings.Trim(string(content), "---\n")+"\n"), 0644); err != nil {
log.Fatal(err)
}
}

View file

@ -0,0 +1,9 @@
apiVersion: v1/alpha
kind: config
spec:
config:
- distributed_interval: 3
- distributed_tls_max_attempts: 3
- logger_plugin: tls
- logger_tls_endpoint: /api/v1/osquery/log
- logger_tls_period: 10

View file

@ -0,0 +1,14 @@
apiVersion: v1/alpha
kind: decorators
spec:
decorators:
- name: hostname
query: select hostname from system_info;
type: interval
interval: 10
- name: uuid
query: select uuid from osquery_info;
type: load
- name: instance_id
query: select instance_id from osquery_info;
type: load

View file

@ -0,0 +1,14 @@
apiVersion: v1/alpha
kind: fim
spec:
fim:
interval: 500
groups:
- name: etc
paths:
- /etc/%%
- name: users
paths:
- /Users/%/Library/%%
- /Users/%/Documents/%%

View file

@ -0,0 +1,26 @@
apiVersion: v1/alpha
kind: labels
spec:
labels:
- name: all_hosts
query: select 1;
- name: macs
query: select 1 from os_version where platform = "darwin";
- name: ubuntu
query: select 1 from os_version where platform = "ubuntu";
- name: centos
query: select 1 from os_version where platform = "centos";
- name: windows
query: select 1 from os_version where platform = "windows";
- name: pending_updates
query: SELECT value from plist where path = "/Library/Preferences/ManagedInstalls.plist" and key = "PendingUpdateCount" and value > "0";
platforms:
- darwin
- name: slack_not_running
query: >
SELECT * from system_info
WHERE NOT EXISTS (
SELECT *
FROM processes
WHERE name LIKE "%Slack%"
);

View file

@ -0,0 +1,21 @@
apiVersion: v1/alpha
kind: pack
metadata:
name: osquery_monitoring
spec:
targets:
labels:
- all_hosts
queries:
- name: osquery_schedule
interval: 7200
removed: false
description: Report performance publisher health and track event counters.
- name: osquery_events
interval: 86400
removed: false
description: Report event publisher health and track event counters.
- name: oquery_info
interval: 600
removed: false
description: A heartbeat counter that reports general performance (CPU, memory) and version.

View file

@ -0,0 +1,6 @@
apiVersion: v1/alpha
kind: query
metadata:
- name: processes
spec:
query: select * from processes;

View file

@ -0,0 +1,17 @@
apiVersion: v1/alpha
kind: queries
spec:
queries:
- name: launcher_version
query: select version from kolide_launcher_info;
- name: osquery_version
query: select version from osquery_info;
- name: osquery_schedule
query: select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory, last_executed from osquery_schedule;
description: Report performance publisher health and track event counters.
- name: osquery_events
query: select name, publisher, type, subscriptions, events, active from osquery_events;
description: Report event publisher health and track event counters.
- name: osquery_info
query: select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
description: A heartbeat counter that reports general performance (CPU, memory) and version.

113
examples/config-intent.yml Normal file
View file

@ -0,0 +1,113 @@
apiVersion: v1/alpha
kind: config
spec:
config:
- distributed_interval: 3
- distributed_tls_max_attempts: 3
- logger_plugin: tls
- logger_tls_endpoint: /api/v1/osquery/log
- logger_tls_period: 10
---
apiVersion: v1/alpha
kind: decorators
spec:
decorators:
- name: hostname
query: select hostname from system_info;
type: interval
interval: 10
- name: uuid
query: select uuid from osquery_info;
type: load
- name: instance_id
query: select instance_id from osquery_info;
type: load
---
apiVersion: v1/alpha
kind: fim
spec:
fim:
interval: 500
groups:
- name: etc
paths:
- /etc/%%
- name: users
paths:
- /Users/%/Library/%%
- /Users/%/Documents/%%
---
apiVersion: v1/alpha
kind: labels
spec:
labels:
- name: all_hosts
query: select 1;
- name: macs
query: select 1 from os_version where platform = "darwin";
- name: ubuntu
query: select 1 from os_version where platform = "ubuntu";
- name: centos
query: select 1 from os_version where platform = "centos";
- name: windows
query: select 1 from os_version where platform = "windows";
- name: pending_updates
query: SELECT value from plist where path = "/Library/Preferences/ManagedInstalls.plist" and key = "PendingUpdateCount" and value > "0";
platforms:
- darwin
- name: slack_not_running
query: >
SELECT * from system_info
WHERE NOT EXISTS (
SELECT *
FROM processes
WHERE name LIKE "%Slack%"
);
---
apiVersion: v1/alpha
kind: pack
metadata:
name: osquery_monitoring
spec:
targets:
labels:
- all_hosts
queries:
- name: osquery_schedule
interval: 7200
removed: false
description: Report performance publisher health and track event counters.
- name: osquery_events
interval: 86400
removed: false
description: Report event publisher health and track event counters.
- name: oquery_info
interval: 600
removed: false
description: A heartbeat counter that reports general performance (CPU, memory) and version.
---
apiVersion: v1/alpha
kind: query
metadata:
- name: processes
spec:
query: select * from processes;
---
apiVersion: v1/alpha
kind: queries
spec:
queries:
- name: launcher_version
query: select version from kolide_launcher_info;
- name: osquery_version
query: select version from osquery_info;
- name: osquery_schedule
query: select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory, last_executed from osquery_schedule;
description: Report performance publisher health and track event counters.
- name: osquery_events
query: select name, publisher, type, subscriptions, events, active from osquery_events;
description: Report event publisher health and track event counters.
- name: osquery_info
query: select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
description: A heartbeat counter that reports general performance (CPU, memory) and version.