-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from lightstep/create-repo
First working state
- Loading branch information
Showing
25 changed files
with
2,196 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
name: Go Build | ||
on: [push] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Setup Go | ||
uses: actions/setup-go@v4 | ||
with: | ||
go-version: '1.20.x' | ||
- name: Install dependencies | ||
run: go get . | ||
- name: Build | ||
run: go build -v ./... | ||
- name: Test with the Go CLI | ||
run: go test ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
releases-matrix: | ||
name: Release Go Binary | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
# build and publish in parallel: linux/386, linux/amd64, linux/arm64, windows/386, windows/amd64, darwin/amd64, darwin/arm64 | ||
goos: [linux, windows, darwin] | ||
goarch: ["386", amd64, arm64] | ||
exclude: | ||
- goarch: "386" | ||
goos: darwin | ||
- goarch: arm64 | ||
goos: windows | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: wangyoucao577/go-release-action@v1 | ||
with: | ||
github_token: ${{ secrets.GITHUB_TOKEN }} | ||
goos: ${{ matrix.goos }} | ||
goarch: ${{ matrix.goarch }} | ||
goversion: "1.20.5" | ||
binary_name: "collector-cluster-check" | ||
extra_files: LICENSE README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,40 @@ | ||
# collector-cluster-check | ||
A shippable binary that you can run to confirm you can successfully run a collector in Kubernetes to send data to Lightstep | ||
|
||
This tool allows you to test various parts of your infrastructure and observability stack. | ||
The goal is to provide you with confidence that you are able to effectively use the OpenTelemetry Operator, | ||
create OpenTelemetry Collectors, and send data to your desired destination. | ||
|
||
``` | ||
Usage: | ||
collector-cluster-check [command] | ||
Available Commands: | ||
check runs one of multiple checks, use -h for more | ||
completion Generate the autocompletion script for the specified shell | ||
help Help about any command | ||
Flags: | ||
--config string config file (default is $HOME/.collector-cluster-check.yaml) | ||
-h, --help help for collector-cluster-check | ||
-t, --toggle Help message for toggle | ||
Use "collector-cluster-check [command] --help" for more information about a command. | ||
runs one of multiple checks, use -h for more | ||
``` | ||
|
||
## `check` Command | ||
|
||
``` | ||
Usage: | ||
collector-cluster-check check [metrics|tracing|preflight|all] [flags] | ||
Flags: | ||
--accessToken string access token to send data to Lightstep | ||
-h, --help help for check | ||
--http should telemetry be sent over http | ||
--kubeConfig string (optional) absolute path to the kubeconfig file (default "/Users/jacob.aronoff/.kube/config") | ||
Global Flags: | ||
--config string config file (default is $HOME/.collector-cluster-check.yaml) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
/* | ||
Copyright © 2023 Jacob Aronoff <[email protected]> | ||
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 cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/jedib0t/go-pretty/v6/table" | ||
"github.com/spf13/cobra" | ||
"k8s.io/client-go/util/homedir" | ||
|
||
"github.com/lightstep/collector-cluster-check/pkg/checks" | ||
"github.com/lightstep/collector-cluster-check/pkg/checks/certmanager" | ||
"github.com/lightstep/collector-cluster-check/pkg/checks/kubernetes" | ||
"github.com/lightstep/collector-cluster-check/pkg/checks/lightstep" | ||
"github.com/lightstep/collector-cluster-check/pkg/checks/oteloperator" | ||
"github.com/lightstep/collector-cluster-check/pkg/checks/prometheus" | ||
"github.com/lightstep/collector-cluster-check/pkg/dependencies" | ||
) | ||
|
||
type checkGroup struct { | ||
dependencies []dependencies.Initializer | ||
checkers []checks.NewChecker | ||
} | ||
|
||
var ( | ||
kubeConfig string | ||
accessToken string | ||
http bool | ||
availableChecks = map[string]checkGroup{ | ||
"metrics": { | ||
dependencies: []dependencies.Initializer{dependencies.MetricInitializer}, | ||
checkers: []checks.NewChecker{lightstep.NewMetricCheck}, | ||
}, | ||
"tracing": { | ||
dependencies: []dependencies.Initializer{dependencies.TraceInitializer}, | ||
checkers: []checks.NewChecker{lightstep.NewTraceCheck}, | ||
}, | ||
"preflight": { | ||
dependencies: []dependencies.Initializer{dependencies.KubernetesClientInitializer, dependencies.CustomResourceClientInitializer}, | ||
checkers: []checks.NewChecker{kubernetes.NewVersionCheck, prometheus.NewCheck, certmanager.NewCheck, oteloperator.NewCheck}, | ||
}, | ||
"all": { | ||
dependencies: []dependencies.Initializer{dependencies.KubernetesClientInitializer, dependencies.CustomResourceClientInitializer, dependencies.MetricInitializer, dependencies.TraceInitializer}, | ||
checkers: []checks.NewChecker{kubernetes.NewVersionCheck, prometheus.NewCheck, certmanager.NewCheck, oteloperator.NewCheck, lightstep.NewMetricCheck, lightstep.NewTraceCheck}, | ||
}, | ||
} | ||
) | ||
|
||
// checkCmd represents the check command | ||
var checkCmd = &cobra.Command{ | ||
Use: "check [metrics|tracing|preflight|all]", | ||
Short: "runs one of multiple checks, use -h for more", | ||
Args: func(cmd *cobra.Command, args []string) error { | ||
if len(args) == 0 { | ||
return fmt.Errorf("must specify at least one check to run") | ||
} | ||
var validArgs []string | ||
for _, v := range cmd.ValidArgs { | ||
validArgs = append(validArgs, strings.Split(v, "\t")[0]) | ||
} | ||
for _, v := range args { | ||
if _, ok := availableChecks[v]; !ok { | ||
return fmt.Errorf("invalid argument %q for %q", v, cmd.CommandPath()) | ||
} | ||
} | ||
return nil | ||
}, | ||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
var comps []string | ||
if len(args) == 0 { | ||
comps = cobra.AppendActiveHelp(comps, "You must choose at least one check to run") | ||
} else { | ||
for _, arg := range args { | ||
if _, ok := availableChecks[arg]; !ok { | ||
comps = cobra.AppendActiveHelp(comps, fmt.Sprintf("%s is not a valid check", arg)) | ||
} | ||
} | ||
} | ||
return comps, cobra.ShellCompDirectiveNoFileComp | ||
}, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
for _, c := range args { | ||
group := availableChecks[c] | ||
var depResults []*checks.Check | ||
var results map[string]checks.CheckerResult | ||
var opts []checks.RunnerOption | ||
for _, d := range group.dependencies { | ||
runnerOption, checkResult := d.Apply(cmd.Context(), http, accessToken, kubeConfig) | ||
depResults = append(depResults, checkResult) | ||
if checkResult.IsFailure() { | ||
return | ||
} | ||
opts = append(opts, runnerOption) | ||
} | ||
runner := checks.NewRunner(group.checkers, opts...) | ||
results = runner.Run(cmd.Context()) | ||
prettyPrintDependenciesResults(depResults) | ||
prettyPrint(results) | ||
} | ||
}, | ||
} | ||
|
||
func prettyPrintDependenciesResults(results []*checks.Check) { | ||
t := table.NewWriter() | ||
rowConfigAutoMerge := table.RowConfig{AutoMerge: true} | ||
t.AppendHeader(table.Row{"dependency", "Result", "Message", "Error"}) | ||
t.SetColumnConfigs([]table.ColumnConfig{ | ||
{Number: 1, AutoMerge: true}, | ||
}) | ||
for _, check := range results { | ||
prettyResult := "🟩" | ||
if !check.IsSuccess() { | ||
prettyResult = "🟥" | ||
} | ||
t.AppendRow(table.Row{check.Name, prettyResult, check.Message, check.Error}, rowConfigAutoMerge) | ||
} | ||
t.SetOutputMirror(os.Stdout) | ||
t.SetStyle(table.StyleLight) | ||
t.Style().Options.SeparateRows = true | ||
t.Render() | ||
} | ||
|
||
func prettyPrint(results map[string]checks.CheckerResult) { | ||
t := table.NewWriter() | ||
rowConfigAutoMerge := table.RowConfig{AutoMerge: true} | ||
t.AppendHeader(table.Row{"Checker", "Result", "Check Name", "Message", "Error"}) | ||
t.SetColumnConfigs([]table.ColumnConfig{ | ||
{Number: 1, AutoMerge: true}, | ||
}) | ||
for checker, result := range results { | ||
for _, check := range result { | ||
prettyResult := "🟩" | ||
if !check.IsSuccess() { | ||
prettyResult = "🟥" | ||
} | ||
t.AppendRow(table.Row{checker, prettyResult, check.Name, check.Message, check.Error}, rowConfigAutoMerge) | ||
} | ||
} | ||
t.SetOutputMirror(os.Stdout) | ||
t.SetStyle(table.StyleLight) | ||
t.Style().Options.SeparateRows = true | ||
t.Render() | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(checkCmd) | ||
|
||
if home := homedir.HomeDir(); home != "" { | ||
checkCmd.PersistentFlags().StringVarP(&kubeConfig, "kubeConfig", "", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") | ||
} else { | ||
checkCmd.PersistentFlags().StringVarP(&kubeConfig, "kubeconfig", "", "", "absolute path to the kubeconfig file") | ||
} | ||
checkCmd.PersistentFlags().StringVarP(&accessToken, "accessToken", "", os.Getenv("LS_TOKEN"), "access token to send data to Lightstep") | ||
checkCmd.PersistentFlags().BoolVarP(&http, "http", "", false, "should telemetry be sent over http") | ||
|
||
// Here you will define your flags and configuration settings. | ||
|
||
// Cobra supports Persistent Flags which will work for this command | ||
// and all subcommands, e.g.: | ||
// checkCmd.PersistentFlags().String("foo", "", "A help for foo") | ||
|
||
// Cobra supports local flags which will only run when this command | ||
// is called directly, e.g.: | ||
// checkCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
Copyright © 2023 Jacob Aronoff <[email protected]> | ||
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 cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
var cfgFile string | ||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "collector-cluster-check", | ||
Short: "this tool is used to run a variety of checks in your current kube context", | ||
Long: `This tool allows you to test various parts of your infrastructure and observability stack. | ||
The goal is to provide you with confidence that you are able to effectively use the OpenTelemetry Operator, | ||
create OpenTelemetry Collectors, and send data to your desired destination.`, | ||
// Uncomment the following line if your bare application | ||
// has an action associated with it: | ||
// Run: func(cmd *cobra.Command, args []string) { }, | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
err := rootCmd.Execute() | ||
if err != nil { | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func init() { | ||
cobra.OnInitialize(initConfig) | ||
|
||
// Here you will define your flags and configuration settings. | ||
// Cobra supports persistent flags, which, if defined here, | ||
// will be global for your application. | ||
|
||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.collector-cluster-check.yaml)") | ||
|
||
// Cobra also supports local flags, which will only run | ||
// when this action is called directly. | ||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") | ||
} | ||
|
||
// initConfig reads in config file and ENV variables if set. | ||
func initConfig() { | ||
if cfgFile != "" { | ||
// Use config file from the flag. | ||
viper.SetConfigFile(cfgFile) | ||
} else { | ||
// Find home directory. | ||
home, err := os.UserHomeDir() | ||
cobra.CheckErr(err) | ||
|
||
// Search config in home directory with name ".collector-cluster-check" (without extension). | ||
viper.AddConfigPath(home) | ||
viper.SetConfigType("yaml") | ||
viper.SetConfigName(".collector-cluster-check") | ||
} | ||
|
||
viper.AutomaticEnv() // read in environment variables that match | ||
|
||
// If a config file is found, read it in. | ||
if err := viper.ReadInConfig(); err == nil { | ||
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) | ||
} | ||
} |
Oops, something went wrong.