Preflight server and CLI

This commit is contained in:
Marc Campbell
2019-07-11 21:16:14 +00:00
parent 8ea6dae7a3
commit e2d0254804
21 changed files with 433 additions and 215 deletions
+3 -3
View File
@@ -79,9 +79,9 @@ snapshot-release:
.PHONY: local-release
local-release: snapshot-release
docker tag replicatedhq/troubleshoot:alpha localhost:32000/troubleshoot:alpha
docker tag replicatedhq/preflight:alpha localhost:32000/preflight:alpha
docker tag replicatedhq/troubleshoot-manager:alpha localhost:32000/troubleshoot-manager:alpha
docker tag replicated/troubleshoot:alpha localhost:32000/troubleshoot:alpha
docker tag replicated/preflight:alpha localhost:32000/preflight:alpha
docker tag replicated/troubleshoot-manager:alpha localhost:32000/troubleshoot-manager:alpha
docker push localhost:32000/troubleshoot:alpha
docker push localhost:32000/preflight:alpha
docker push localhost:32000/troubleshoot-manager:alpha
+5 -4
View File
@@ -13,16 +13,17 @@ import (
func Server() *cobra.Command {
cmd := &cobra.Command{
Use: "server",
Short: "run the http server",
Long: `...`,
Use: "server",
Short: "run the http server",
Hidden: true,
Long: `...`,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlag("port", cmd.Flags().Lookup("port"))
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
server.Serve(context.Background(), fmt.Sprintf(":%d", v.GetInt("port")))
server.ServeCollector(context.Background(), fmt.Sprintf(":%d", v.GetInt("port")))
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
+8 -5
View File
@@ -11,15 +11,18 @@ import (
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "troubleshoot",
Short: "Generate and manage support bundles",
Long: `A support bundle is an archive of files, output, metrics and state
from a server that can be used to assist when troubleshooting a server.`,
Use: "preflight",
Short: "Run and retrieve preflight checks in a cluster",
Long: `A preflight check is a set of validations that can and should be run to ensure
that a cluster meets the requirements to run an application.`,
SilenceUsage: true,
}
cobra.OnInitialize(initConfig)
cmd.AddCommand(Run())
cmd.AddCommand(Server())
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
return cmd
}
@@ -32,6 +35,6 @@ func InitAndExecute() {
}
func initConfig() {
viper.SetEnvPrefix("TROUBLESHOOT")
viper.SetEnvPrefix("PREFLIGHT")
viper.AutomaticEnv()
}
+141
View File
@@ -0,0 +1,141 @@
package cli
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/spf13/cobra"
"github.com/spf13/viper"
kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func Run() *cobra.Command {
cmd := &cobra.Command{
Use: "run",
Short: "run a set of preflight checks in a cluster",
Long: `run preflight checks and return the results`,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlags(cmd.Flags())
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
troubleshootClient, err := createTroubleshootK8sClient()
if err != nil {
return err
}
preflightName := v.GetString("preflight")
if preflightName == "" {
preflights, err := troubleshootClient.Preflights(v.GetString("namespace")).List(metav1.ListOptions{})
if err != nil {
return err
}
if len(preflights.Items) == 1 {
preflightName = preflights.Items[0].Name
}
}
if preflightName == "" {
return errors.New("unable to fly, try using the --preflight flags")
}
// generate a unique name
now := time.Now()
suffix := fmt.Sprintf("%d", now.Unix())
preflightJobName := fmt.Sprintf("%s-job-%s", preflightName, suffix[len(suffix)-4:])
preflightJob := troubleshootv1beta1.PreflightJob{
ObjectMeta: metav1.ObjectMeta{
Name: preflightJobName,
Namespace: v.GetString("namespace"),
},
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "preflightjob.troubleshoot.replicated.com",
},
Spec: troubleshootv1beta1.PreflightJobSpec{
Preflight: troubleshootv1beta1.PreflightRef{
Name: preflightName,
Namespace: v.GetString("namespace"),
},
Image: v.GetString("image"),
ImagePullPolicy: v.GetString("pullpolicy"),
CollectorImage: v.GetString("collector-image"),
CollectorImagePullPolicy: v.GetString("collector-pullpolicy"),
},
}
if _, err := troubleshootClient.PreflightJobs(v.GetString("namespace")).Create(&preflightJob); err != nil {
return err
}
// Poll the status of the Custom Resource for it to include a callback
var found *troubleshootv1beta1.PreflightJob
start := time.Now()
for {
current, err := troubleshootClient.PreflightJobs(v.GetString("namespace")).Get(preflightJobName, metav1.GetOptions{})
if err != nil && kuberneteserrors.IsNotFound(err) {
continue
} else if err != nil {
return err
}
if current.Status.IsServerReady {
found = current
break
}
if time.Now().Sub(start) > time.Duration(time.Second*10) {
return errors.New("preflightjob failed to start")
}
time.Sleep(time.Millisecond * 200)
}
// Connect to the callback
stopChan, err := k8sutil.PortForward(v.GetString("kubecontext"), 8000, 8000, found.Status.ServerPodNamespace, found.Status.ServerPodName)
if err != nil {
return err
}
// if err := receiveSupportBundle(found.Namespace, found.Name); err != nil {
// return err
// }
// Write
close(stopChan)
return nil
},
}
cmd.Flags().String("preflight", "", "name of the preflight to use")
cmd.Flags().String("namespace", "default", "namespace the preflight can be found in")
cmd.Flags().String("kubecontext", filepath.Join(homeDir(), ".kube", "config"), "the kubecontext to use when connecting")
cmd.Flags().String("image", "", "the full name of the preflight image to use")
cmd.Flags().String("pullpolicy", "", "the pull policy of the preflight image")
cmd.Flags().String("collector-image", "", "the full name of the collector image to use")
cmd.Flags().String("collector-pullpolicy", "", "the pull policy of the collector image")
cmd.Flags().String("analyzer-image", "", "the full name of the analyzer image to use")
cmd.Flags().String("analyzer-pullpolicy", "", "the pull policy of the analyzer image")
viper.BindPFlags(cmd.Flags())
return cmd
}
func homeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
}
return os.Getenv("USERPROFILE") // windows
}
+43
View File
@@ -0,0 +1,43 @@
package cli
import (
"context"
"fmt"
"os"
"os/signal"
"github.com/replicatedhq/troubleshoot/pkg/server"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func Server() *cobra.Command {
cmd := &cobra.Command{
Use: "server",
Short: "run the http server",
Hidden: true,
Long: `...`,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlag("port", cmd.Flags().Lookup("port"))
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
server.ServePreflight(context.Background(), fmt.Sprintf(":%d", v.GetInt("port")))
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
select {
case <-c:
return nil
}
},
}
cmd.Flags().Int("port", 8000, "port to listen on")
viper.BindPFlags(cmd.Flags())
return cmd
}
+22
View File
@@ -0,0 +1,22 @@
package cli
import (
troubleshootclientv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
"github.com/spf13/viper"
"k8s.io/client-go/tools/clientcmd"
)
func createTroubleshootK8sClient() (*troubleshootclientv1beta1.TroubleshootV1beta1Client, error) {
v := viper.GetViper()
config, err := clientcmd.BuildConfigFromFlags("", v.GetString("kubecontext"))
if err != nil {
return nil, err
}
troubleshootClient, err := troubleshootclientv1beta1.NewForConfig(config)
if err != nil {
return nil, err
}
return troubleshootClient, nil
}
@@ -399,6 +399,8 @@ spec:
type: string
collectorImagePullPolicy:
type: string
imagePullPolicy:
type: string
preflight:
properties:
name:
@@ -408,6 +410,8 @@ spec:
required:
- name
type: object
preflightImage:
type: string
required:
- preflight
type: object
+2 -2
View File
@@ -590,8 +590,8 @@ func (in *PreflightJobStatus) DeepCopyInto(out *PreflightJobStatus) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.AnakyzersFailed != nil {
in, out := &in.AnakyzersFailed, &out.AnakyzersFailed
if in.AnalyzersFailed != nil {
in, out := &in.AnalyzersFailed, &out.AnalyzersFailed
*out = make([]string, len(*in))
copy(*out, *in)
}
+6 -4
View File
@@ -84,19 +84,21 @@ archives:
dockers:
- dockerfile: ./deploy/Dockerfile.troubleshoot
image_templates:
- "replicatedhq/troubleshoot:alpha"
- "replicated/troubleshoot:alpha"
binaries:
- collector
- troubleshoot
- dockerfile: ./deploy/Dockerfile.preflight
- preflight
- dockerfile: ./deploy/Dockerfile.troubleshoot
image_templates:
- "replicatedhq/preflight:alpha"
- "replicated/preflight:alpha"
binaries:
- collector
- troubleshoot
- preflight
- dockerfile: ./deploy/Dockerfile.manager
image_templates:
- "replicatedhq/troubleshoot-manager:alpha"
- "replicated/troubleshoot-manager:alpha"
binaries:
- manager
snapshot:
-12
View File
@@ -1,12 +0,0 @@
FROM debian:buster
WORKDIR /
RUN apt-get -qq update \
&& apt-get -qq -y install \
ca-certificates
COPY preflight /preflight/preflight
COPY collector /preflight/collector
ENV PATH="/preflight:${PATH}"
+1
View File
@@ -7,6 +7,7 @@ RUN apt-get -qq update \
COPY troubleshoot /troubleshoot/troubleshoot
COPY collector /troubleshoot/collector
COPY preflight /troubleshoot/preflight
ENV PATH="/troubleshoot:${PATH}"
@@ -29,6 +29,8 @@ type PreflightRef struct {
type PreflightJobSpec struct {
Preflight PreflightRef `json:"preflight"`
Image string `json:"preflightImage,omitempty"`
ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
CollectorImage string `json:"collectorImage,omitempty"`
CollectorImagePullPolicy string `json:"collectorImagePullPolicy,omitempty"`
@@ -51,7 +53,7 @@ type PreflightJobStatus struct {
IsAnalyzersComplete bool `json:"isAnalyzersComplete"`
AnalyzersRunning []string `json:"analyzersRunning"`
AnalyzersSuccessful []string `json:"analyzersSuccessful"`
AnakyzersFailed []string `json:"analyzersFailed"`
AnalyzersFailed []string `json:"analyzersFailed"`
}
// +genclient
@@ -606,8 +606,8 @@ func (in *PreflightJobStatus) DeepCopyInto(out *PreflightJobStatus) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.AnakyzersFailed != nil {
in, out := &in.AnakyzersFailed, &out.AnakyzersFailed
if in.AnalyzersFailed != nil {
in, out := &in.AnalyzersFailed, &out.AnalyzersFailed
*out = make([]string, len(*in))
copy(*out, *in)
}
@@ -34,11 +34,6 @@ import (
var log = logf.Log.WithName("controller")
/**
* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller
* business logic. Delete these comments after modifying this file.*
*/
// Add creates a new Collector Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
@@ -18,18 +18,12 @@ package preflight
import (
"context"
"reflect"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -39,11 +33,6 @@ import (
var log = logf.Log.WithName("controller")
/**
* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller
* business logic. Delete these comments after modifying this file.*
*/
// Add creates a new Preflight Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
@@ -69,16 +58,6 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
return err
}
// TODO(user): Modify this to be the types you create
// Uncomment watch a Deployment created by Preflight - change this for objects you create
err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{
IsController: true,
OwnerType: &troubleshootv1beta1.Preflight{},
})
if err != nil {
return err
}
return nil
}
@@ -104,7 +83,7 @@ func (r *ReconcilePreflight) Reconcile(request reconcile.Request) (reconcile.Res
instance := &troubleshootv1beta1.Preflight{}
err := r.Get(context.TODO(), request.NamespacedName, instance)
if err != nil {
if errors.IsNotFound(err) {
if kuberneteserrors.IsNotFound(err) {
// Object not found, return. Created objects are automatically garbage collected.
// For additional cleanup logic use finalizers.
return reconcile.Result{}, nil
@@ -113,55 +92,5 @@ func (r *ReconcilePreflight) Reconcile(request reconcile.Request) (reconcile.Res
return reconcile.Result{}, err
}
// TODO(user): Change this to be the object type created by your controller
// Define the desired Deployment object
deploy := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: instance.Name + "-deployment",
Namespace: instance.Namespace,
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "nginx",
Image: "nginx",
},
},
},
},
},
}
if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil {
return reconcile.Result{}, err
}
// TODO(user): Change this for the object type created by your controller
// Check if the Deployment already exists
found := &appsv1.Deployment{}
err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found)
if err != nil && errors.IsNotFound(err) {
log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name)
err = r.Create(context.TODO(), deploy)
return reconcile.Result{}, err
} else if err != nil {
return reconcile.Result{}, err
}
// TODO(user): Change this for the object type created by your controller
// Update the found object and write the result back if there are any changes
if !reflect.DeepEqual(deploy.Spec, found.Spec) {
found.Spec = deploy.Spec
log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name)
err = r.Update(context.TODO(), found)
if err != nil {
return reconcile.Result{}, err
}
}
return reconcile.Result{}, nil
}
+1 -1
View File
@@ -1,5 +1,5 @@
package preflightjob
func (r *ReconcilePreflightJob) reconcileAnalyzers() error {
func (r *ReconcilePreflightJob) reconcilePreflightAnalyzers() error {
return nil
}
+15 -1
View File
@@ -1,5 +1,19 @@
package preflightjob
func (r *ReconcilePreflightJob) reconcileCollectors() error {
import (
"fmt"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
// troubleshootclientv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
// kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// "sigs.k8s.io/controller-runtime/pkg/client/config"
)
func (r *ReconcilePreflightJob) reconcilePreflightCollectors(instance *troubleshootv1beta1.PreflightJob, preflight *troubleshootv1beta1.Preflight) error {
for _, collector := range preflight.Spec.Collectors {
fmt.Printf("collector = %#v\n", collector)
}
return nil
}
+100 -93
View File
@@ -1,119 +1,126 @@
package preflightjob
import (
"context"
"fmt"
"time"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
corev1 "k8s.io/api/core/v1"
kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
func (r *ReconcilePreflightJob) createPreflightServer(instance *troubleshootv1beta1.PreflightJob) error {
name := fmt.Sprintf("%s-%s", instance.Name, "preflight")
fmt.Printf("name = %s\n", name)
// namespacedName := types.NamespacedName{
// Name: name,
// Namespace: instance.Namespace,
// }
namespacedName := types.NamespacedName{
Name: name,
Namespace: instance.Namespace,
}
// found := &corev1.Pod{}
// err := r.Get(context.Background(), namespacedName, found)
// if err == nil || !kuberneteserrors.IsNotFound(err) {
// return err
// }
found := &corev1.Pod{}
err := r.Get(context.Background(), namespacedName, found)
if err == nil || !kuberneteserrors.IsNotFound(err) {
return err
}
// imageName := "replicatedhq/troubleshoot:latest"
// imagePullPolicy := corev1.PullAlways
imageName := "replicatedhq/troubleshoot:latest"
imagePullPolicy := corev1.PullAlways
// if instance.Spec.Image != "" {
// imageName = instance.Spec.Image
// }
// if instance.Spec.ImagePullPolicy != "" {
// imagePullPolicy = corev1.PullPolicy(instance.Spec.ImagePullPolicy)
// }
if instance.Spec.Image != "" {
imageName = instance.Spec.Image
}
if instance.Spec.ImagePullPolicy != "" {
imagePullPolicy = corev1.PullPolicy(instance.Spec.ImagePullPolicy)
}
// podLabels := make(map[string]string)
// podLabels["collector"] = instance.Name
// podLabels["troubleshoot-role"] = "collector"
podLabels := make(map[string]string)
podLabels["preflight"] = instance.Name
podLabels["troubleshoot-role"] = "preflight"
// pod := corev1.Pod{
// ObjectMeta: metav1.ObjectMeta{
// Name: name,
// Namespace: instance.Namespace,
// Labels: podLabels,
// },
// TypeMeta: metav1.TypeMeta{
// APIVersion: "v1",
// Kind: "Pod",
// },
// Spec: corev1.PodSpec{
// RestartPolicy: corev1.RestartPolicyNever,
// Containers: []corev1.Container{
// {
// Image: imageName,
// ImagePullPolicy: imagePullPolicy,
// Name: "collector",
// Command: []string{"collector"},
// Args: []string{"server"},
// Ports: []corev1.ContainerPort{
// {
// Name: "http",
// ContainerPort: 8000,
// },
// },
// },
// },
// },
// }
pod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: instance.Namespace,
Labels: podLabels,
},
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Pod",
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Image: imageName,
ImagePullPolicy: imagePullPolicy,
Name: "preflight",
Command: []string{"preflight"},
Args: []string{"server"},
Ports: []corev1.ContainerPort{
{
Name: "http",
ContainerPort: 8000,
},
},
},
},
},
}
// if err := controllerutil.SetControllerReference(instance, &pod, r.scheme); err != nil {
// return err
// }
if err := controllerutil.SetControllerReference(instance, &pod, r.scheme); err != nil {
return err
}
// if err := r.Create(context.Background(), &pod); err != nil {
// return err
// }
if err := r.Create(context.Background(), &pod); err != nil {
return err
}
// service := corev1.Service{
// ObjectMeta: metav1.ObjectMeta{
// Name: name,
// Namespace: instance.Namespace,
// },
// TypeMeta: metav1.TypeMeta{
// APIVersion: "v1",
// Kind: "Service",
// },
// Spec: corev1.ServiceSpec{
// Selector: podLabels,
// Type: corev1.ServiceTypeClusterIP,
// Ports: []corev1.ServicePort{
// {
// Name: "http",
// Port: 8000,
// TargetPort: intstr.FromInt(8000),
// },
// },
// },
// }
service := corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: instance.Namespace,
},
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
Spec: corev1.ServiceSpec{
Selector: podLabels,
Type: corev1.ServiceTypeClusterIP,
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 8000,
TargetPort: intstr.FromInt(8000),
},
},
},
}
// if err := controllerutil.SetControllerReference(instance, &service, r.scheme); err != nil {
// return err
// }
if err := controllerutil.SetControllerReference(instance, &service, r.scheme); err != nil {
return err
}
// if err := r.Create(context.Background(), &service); err != nil {
// return err
// }
if err := r.Create(context.Background(), &service); err != nil {
return err
}
// instance.Status.ServerPodName = name
// instance.Status.ServerPodNamespace = instance.Namespace
// instance.Status.ServerPodPort = 8000
// instance.Status.IsServerReady = true
instance.Status.ServerPodName = name
instance.Status.ServerPodNamespace = instance.Namespace
instance.Status.ServerPodPort = 8000
instance.Status.IsServerReady = true
// // wait for the server to be ready
// // TODO
// time.Sleep(time.Second * 5)
// wait for the server to be ready
// TODO
time.Sleep(time.Second * 5)
// if err := r.Update(context.Background(), instance); err != nil {
// return err
// }
if err := r.Update(context.Background(), instance); err != nil {
return err
}
return nil
}
@@ -18,7 +18,6 @@ package preflightjob
import (
"context"
"fmt"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
troubleshootclientv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
@@ -112,7 +111,18 @@ func (r *ReconcilePreflightJob) Reconcile(request reconcile.Request) (reconcile.
return reconcile.Result{}, err
}
fmt.Printf("preflightSpec = %#v\n", preflightSpec)
// the preflight job will be in collector mode or analyzer mode
if !instance.Status.IsCollectorsComplete {
if err := r.reconcilePreflightCollectors(instance, preflightSpec); err != nil {
return reconcile.Result{}, err
}
} else if !instance.Status.IsAnalyzersComplete {
if err := r.reconcilePreflightAnalyzers(); err != nil {
return reconcile.Result{}, err
}
}
// just finished, nothing to do
return reconcile.Result{}, nil
}
@@ -10,9 +10,9 @@ import (
"github.com/gin-gonic/gin"
)
var queue = make(map[string][]byte)
var collectorQueue = make(map[string][]byte)
func Serve(ctx context.Context, address string) {
func ServeCollector(ctx context.Context, address string) {
g := gin.New()
root := g.Group("/")
@@ -35,20 +35,20 @@ func putCollectorOutput(c *gin.Context) {
return
}
queue[collectorID] = body
collectorQueue[collectorID] = body
fmt.Printf("queue = %#v\n", queue)
fmt.Printf("collectorQueue = %#v\n", collectorQueue)
c.Status(201)
}
func getCollectorOutput(c *gin.Context) {
encoded := base64.StdEncoding.EncodeToString(queue[c.Param("id")])
encoded := base64.StdEncoding.EncodeToString(collectorQueue[c.Param("id")])
c.String(200, encoded)
}
func getQueuedCollectors(c *gin.Context) {
keys := make([]string, 0, len(queue))
for k := range queue {
keys := make([]string, 0, len(collectorQueue))
for k := range collectorQueue {
keys = append(keys, k)
}
+56
View File
@@ -0,0 +1,56 @@
package server
import (
"context"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"github.com/gin-gonic/gin"
)
var preflightQueue = make(map[string][]byte)
func ServePreflight(ctx context.Context, address string) {
g := gin.New()
root := g.Group("/")
root.PUT("/", putPreflightOutput)
root.GET("/", getQueuedPreflights)
root.GET("/preflight/:id", getPreflightOutput)
srvr := http.Server{Addr: address, Handler: g}
go func() {
srvr.ListenAndServe()
}()
}
func putPreflightOutput(c *gin.Context) {
preflightID := c.Request.Header.Get("collector-id")
body, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
c.AbortWithStatus(500)
return
}
preflightQueue[preflightID] = body
fmt.Printf("preflightQueue = %#v\n", preflightQueue)
c.Status(201)
}
func getPreflightOutput(c *gin.Context) {
encoded := base64.StdEncoding.EncodeToString(preflightQueue[c.Param("id")])
c.String(200, encoded)
}
func getQueuedPreflights(c *gin.Context) {
keys := make([]string, 0, len(preflightQueue))
for k := range preflightQueue {
keys = append(keys, k)
}
c.JSON(200, keys)
}