mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-04-15 07:16:34 +00:00
Merge pull request #153 from replicatedhq/export-function
Export function
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
@@ -64,16 +63,3 @@ func initConfig() {
|
||||
viper.SetEnvPrefix("PREFLIGHT")
|
||||
viper.AutomaticEnv()
|
||||
}
|
||||
|
||||
func ensureCollectorInList(list []*troubleshootv1beta1.Collect, collector troubleshootv1beta1.Collect) []*troubleshootv1beta1.Collect {
|
||||
for _, inList := range list {
|
||||
if collector.ClusterResources != nil && inList.ClusterResources != nil {
|
||||
return list
|
||||
}
|
||||
if collector.ClusterInfo != nil && inList.ClusterInfo != nil {
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
return append(list, &collector)
|
||||
}
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cursor "github.com/ahmetalpbalkan/go-cursor"
|
||||
"github.com/fatih/color"
|
||||
"github.com/pkg/errors"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/preflight"
|
||||
"github.com/spf13/viper"
|
||||
spin "github.com/tj/go-spin"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
@@ -66,7 +61,7 @@ func runPreflights(v *viper.Viper, arg string) error {
|
||||
return errors.Wrapf(err, "failed to parse %s", arg)
|
||||
}
|
||||
|
||||
preflight := obj.(*troubleshootv1beta1.Preflight)
|
||||
preflightSpec := obj.(*troubleshootv1beta1.Preflight)
|
||||
|
||||
s := spin.New()
|
||||
finishedCh := make(chan bool, 1)
|
||||
@@ -98,48 +93,34 @@ func runPreflights(v *viper.Viper, arg string) error {
|
||||
close(finishedCh)
|
||||
}()
|
||||
|
||||
allCollectedData, err := runCollectors(v, *preflight, progressChan)
|
||||
restConfig, err := KubernetesConfigFlags.ToRESTConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert kube flags to rest config")
|
||||
}
|
||||
|
||||
collectOpts := preflight.CollectOpts{
|
||||
Namespace: v.GetString("namespace"),
|
||||
IgnorePermissionErrors: v.GetBool("collect-without-permissions"),
|
||||
ProgressChan: progressChan,
|
||||
KubernetesRestConfig: restConfig,
|
||||
}
|
||||
|
||||
collectResults, err := preflight.Collect(collectOpts, preflightSpec)
|
||||
if err != nil {
|
||||
if !collectResults.IsRBACAllowed {
|
||||
if preflightSpec.Spec.UploadResultsTo != "" {
|
||||
err := uploadErrors(preflightSpec.Spec.UploadResultsTo, collectResults.Collectors)
|
||||
if err != nil {
|
||||
progressChan <- err
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
getCollectedFileContents := func(fileName string) ([]byte, error) {
|
||||
contents, ok := allCollectedData[fileName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("file %s was not collected", fileName)
|
||||
}
|
||||
|
||||
return contents, nil
|
||||
}
|
||||
getChildCollectedFileContents := func(prefix string) (map[string][]byte, error) {
|
||||
matching := make(map[string][]byte)
|
||||
for k, v := range allCollectedData {
|
||||
if strings.HasPrefix(k, prefix) {
|
||||
matching[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return matching, nil
|
||||
}
|
||||
|
||||
analyzeResults := []*analyzerunner.AnalyzeResult{}
|
||||
for _, analyzer := range preflight.Spec.Analyzers {
|
||||
analyzeResult, err := analyzerunner.Analyze(analyzer, getCollectedFileContents, getChildCollectedFileContents)
|
||||
if err != nil {
|
||||
analyzeResult = &analyzerunner.AnalyzeResult{
|
||||
IsFail: true,
|
||||
Title: "Analyzer Failed",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if analyzeResult != nil {
|
||||
analyzeResults = append(analyzeResults, analyzeResult)
|
||||
}
|
||||
}
|
||||
|
||||
if preflight.Spec.UploadResultsTo != "" {
|
||||
err := uploadResults(preflight.Spec.UploadResultsTo, analyzeResults)
|
||||
analyzeResults := collectResults.Analyze()
|
||||
if preflightSpec.Spec.UploadResultsTo != "" {
|
||||
err := uploadResults(preflightSpec.Spec.UploadResultsTo, analyzeResults)
|
||||
if err != nil {
|
||||
progressChan <- err
|
||||
}
|
||||
@@ -151,117 +132,8 @@ func runPreflights(v *viper.Viper, arg string) error {
|
||||
if len(analyzeResults) == 0 {
|
||||
return errors.New("no data has been collected")
|
||||
}
|
||||
return showInteractiveResults(preflight.Name, analyzeResults)
|
||||
return showInteractiveResults(preflightSpec.Name, analyzeResults)
|
||||
}
|
||||
|
||||
return showStdoutResults(v.GetString("format"), preflight.Name, analyzeResults)
|
||||
}
|
||||
|
||||
func runCollectors(v *viper.Viper, preflight troubleshootv1beta1.Preflight, progressChan chan interface{}) (map[string][]byte, error) {
|
||||
collectSpecs := make([]*troubleshootv1beta1.Collect, 0, 0)
|
||||
collectSpecs = append(collectSpecs, preflight.Spec.Collectors...)
|
||||
collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta1.Collect{ClusterInfo: &troubleshootv1beta1.ClusterInfo{}})
|
||||
collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta1.Collect{ClusterResources: &troubleshootv1beta1.ClusterResources{}})
|
||||
|
||||
allCollectedData := make(map[string][]byte)
|
||||
|
||||
config, err := KubernetesConfigFlags.ToRESTConfig()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to convert kube flags to rest config")
|
||||
}
|
||||
|
||||
var collectors collect.Collectors
|
||||
for _, desiredCollector := range collectSpecs {
|
||||
collector := collect.Collector{
|
||||
Redact: true,
|
||||
Collect: desiredCollector,
|
||||
ClientConfig: config,
|
||||
Namespace: v.GetString("namespace"),
|
||||
}
|
||||
collectors = append(collectors, &collector)
|
||||
}
|
||||
|
||||
if err := collectors.CheckRBAC(); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to check RBAC for collectors")
|
||||
}
|
||||
|
||||
foundForbidden := false
|
||||
for _, c := range collectors {
|
||||
for _, e := range c.RBACErrors {
|
||||
foundForbidden = true
|
||||
progressChan <- e
|
||||
}
|
||||
}
|
||||
|
||||
if foundForbidden && !v.GetBool("collect-without-permissions") {
|
||||
if preflight.Spec.UploadResultsTo != "" {
|
||||
err := uploadErrors(preflight.Spec.UploadResultsTo, collectors)
|
||||
if err != nil {
|
||||
progressChan <- err
|
||||
}
|
||||
}
|
||||
return nil, errors.New("insufficient permissions to run all collectors")
|
||||
}
|
||||
|
||||
// Run preflights collectors synchronously
|
||||
for _, collector := range collectors {
|
||||
if len(collector.RBACErrors) > 0 {
|
||||
// don't skip clusterResources collector due to RBAC issues
|
||||
if collector.Collect.ClusterResources == nil {
|
||||
progressChan <- fmt.Sprintf("skipping collector %s with insufficient RBAC permissions", collector.GetDisplayName())
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
result, err := collector.RunCollectorSync()
|
||||
if err != nil {
|
||||
progressChan <- errors.Errorf("failed to run collector %s: %v\n", collector.GetDisplayName(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
output, err := parseCollectorOutput(string(result))
|
||||
if err != nil {
|
||||
progressChan <- errors.Errorf("failed to parse collector output %s: %v\n", collector.GetDisplayName(), err)
|
||||
continue
|
||||
}
|
||||
for k, v := range output {
|
||||
allCollectedData[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allCollectedData, nil
|
||||
}
|
||||
|
||||
func parseCollectorOutput(output string) (map[string][]byte, error) {
|
||||
input := make(map[string]interface{})
|
||||
files := make(map[string][]byte)
|
||||
if err := json.Unmarshal([]byte(output), &input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for filename, maybeContents := range input {
|
||||
fileDir, fileName := filepath.Split(filename)
|
||||
|
||||
switch maybeContents.(type) {
|
||||
case string:
|
||||
decoded, err := base64.StdEncoding.DecodeString(maybeContents.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files[filepath.Join(fileDir, fileName)] = decoded
|
||||
|
||||
case map[string]interface{}:
|
||||
for k, v := range maybeContents.(map[string]interface{}) {
|
||||
decoded, err := base64.StdEncoding.DecodeString(v.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files[filepath.Join(fileDir, fileName, k)] = decoded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files, nil
|
||||
return showStdoutResults(v.GetString("format"), preflightSpec.Name, analyzeResults)
|
||||
}
|
||||
|
||||
@@ -8,33 +8,15 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/preflight"
|
||||
)
|
||||
|
||||
type UploadPreflightResult struct {
|
||||
IsFail bool `json:"isFail,omitempty"`
|
||||
IsWarn bool `json:"isWarn,omitempty"`
|
||||
IsPass bool `json:"isPass,omitempty"`
|
||||
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
URI string `json:"uri,omitempty"`
|
||||
}
|
||||
|
||||
type UploadPreflightError struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type UploadPreflightResults struct {
|
||||
Results []*UploadPreflightResult `json:"results,omitempty"`
|
||||
Errors []*UploadPreflightError `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
func uploadResults(uri string, analyzeResults []*analyzerunner.AnalyzeResult) error {
|
||||
uploadPreflightResults := &UploadPreflightResults{
|
||||
Results: []*UploadPreflightResult{},
|
||||
uploadPreflightResults := &preflight.UploadPreflightResults{
|
||||
Results: []*preflight.UploadPreflightResult{},
|
||||
}
|
||||
for _, analyzeResult := range analyzeResults {
|
||||
uploadPreflightResult := &UploadPreflightResult{
|
||||
uploadPreflightResult := &preflight.UploadPreflightResult{
|
||||
IsFail: analyzeResult.IsFail,
|
||||
IsWarn: analyzeResult.IsWarn,
|
||||
IsPass: analyzeResult.IsPass,
|
||||
@@ -50,23 +32,23 @@ func uploadResults(uri string, analyzeResults []*analyzerunner.AnalyzeResult) er
|
||||
}
|
||||
|
||||
func uploadErrors(uri string, collectors collect.Collectors) error {
|
||||
errors := []*UploadPreflightError{}
|
||||
errors := []*preflight.UploadPreflightError{}
|
||||
for _, collector := range collectors {
|
||||
for _, e := range collector.RBACErrors {
|
||||
errors = append(errors, &UploadPreflightError{
|
||||
errors = append(errors, &preflight.UploadPreflightError{
|
||||
Error: e.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
results := &UploadPreflightResults{
|
||||
results := &preflight.UploadPreflightResults{
|
||||
Errors: errors,
|
||||
}
|
||||
|
||||
return upload(uri, results)
|
||||
}
|
||||
|
||||
func upload(uri string, payload *UploadPreflightResults) error {
|
||||
func upload(uri string, payload *preflight.UploadPreflightResults) error {
|
||||
b, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal payload")
|
||||
|
||||
48
pkg/preflight/analyze.go
Normal file
48
pkg/preflight/analyze.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
analyze "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
)
|
||||
|
||||
// Analyze runs the analyze phase of preflight checks
|
||||
func (c CollectResult) Analyze() []*analyze.AnalyzeResult {
|
||||
getCollectedFileContents := func(fileName string) ([]byte, error) {
|
||||
contents, ok := c.AllCollectedData[fileName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("file %s was not collected", fileName)
|
||||
}
|
||||
|
||||
return contents, nil
|
||||
}
|
||||
getChildCollectedFileContents := func(prefix string) (map[string][]byte, error) {
|
||||
matching := make(map[string][]byte)
|
||||
for k, v := range c.AllCollectedData {
|
||||
if strings.HasPrefix(k, prefix) {
|
||||
matching[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return matching, nil
|
||||
}
|
||||
|
||||
analyzeResults := []*analyze.AnalyzeResult{}
|
||||
for _, analyzer := range c.Spec.Spec.Analyzers {
|
||||
analyzeResult, err := analyze.Analyze(analyzer, getCollectedFileContents, getChildCollectedFileContents)
|
||||
if err != nil {
|
||||
analyzeResult = &analyze.AnalyzeResult{
|
||||
IsFail: true,
|
||||
Title: "Analyzer Failed",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if analyzeResult != nil {
|
||||
analyzeResults = append(analyzeResults, analyzeResult)
|
||||
}
|
||||
}
|
||||
|
||||
return analyzeResults
|
||||
}
|
||||
147
pkg/preflight/collect.go
Normal file
147
pkg/preflight/collect.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type CollectOpts struct {
|
||||
Namespace string
|
||||
IgnorePermissionErrors bool
|
||||
KubernetesRestConfig *rest.Config
|
||||
ProgressChan chan interface{}
|
||||
}
|
||||
|
||||
type CollectResult struct {
|
||||
AllCollectedData map[string][]byte
|
||||
Collectors collect.Collectors
|
||||
IsRBACAllowed bool
|
||||
Spec *troubleshootv1beta1.Preflight
|
||||
}
|
||||
|
||||
// Collect runs the collection phase of preflight checks
|
||||
func Collect(opts CollectOpts, p *troubleshootv1beta1.Preflight) (CollectResult, error) {
|
||||
collectSpecs := make([]*troubleshootv1beta1.Collect, 0, 0)
|
||||
collectSpecs = append(collectSpecs, p.Spec.Collectors...)
|
||||
collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta1.Collect{ClusterInfo: &troubleshootv1beta1.ClusterInfo{}})
|
||||
collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta1.Collect{ClusterResources: &troubleshootv1beta1.ClusterResources{}})
|
||||
|
||||
allCollectedData := make(map[string][]byte)
|
||||
|
||||
var collectors collect.Collectors
|
||||
for _, desiredCollector := range collectSpecs {
|
||||
collector := collect.Collector{
|
||||
Redact: true,
|
||||
Collect: desiredCollector,
|
||||
ClientConfig: opts.KubernetesRestConfig,
|
||||
Namespace: opts.Namespace,
|
||||
}
|
||||
collectors = append(collectors, &collector)
|
||||
}
|
||||
|
||||
collectResult := CollectResult{
|
||||
Collectors: collectors,
|
||||
Spec: p,
|
||||
}
|
||||
|
||||
if err := collectors.CheckRBAC(); err != nil {
|
||||
return collectResult, errors.Wrap(err, "failed to check RBAC for collectors")
|
||||
}
|
||||
|
||||
foundForbidden := false
|
||||
for _, c := range collectors {
|
||||
for _, e := range c.RBACErrors {
|
||||
foundForbidden = true
|
||||
opts.ProgressChan <- e
|
||||
}
|
||||
}
|
||||
|
||||
if foundForbidden && !opts.IgnorePermissionErrors {
|
||||
collectResult.IsRBACAllowed = false
|
||||
return collectResult, errors.New("insufficient permissions to run all collectors")
|
||||
}
|
||||
|
||||
// Run preflights collectors synchronously
|
||||
for _, collector := range collectors {
|
||||
if len(collector.RBACErrors) > 0 {
|
||||
// don't skip clusterResources collector due to RBAC issues
|
||||
if collector.Collect.ClusterResources == nil {
|
||||
collectResult.IsRBACAllowed = false // not failing, but going to report this
|
||||
opts.ProgressChan <- fmt.Sprintf("skipping collector %s with insufficient RBAC permissions", collector.GetDisplayName())
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
result, err := collector.RunCollectorSync()
|
||||
if err != nil {
|
||||
opts.ProgressChan <- errors.Errorf("failed to run collector %s: %v\n", collector.GetDisplayName(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
output, err := parseCollectorOutput(string(result))
|
||||
if err != nil {
|
||||
opts.ProgressChan <- errors.Errorf("failed to parse collector output %s: %v\n", collector.GetDisplayName(), err)
|
||||
continue
|
||||
}
|
||||
for k, v := range output {
|
||||
allCollectedData[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectResult.AllCollectedData = allCollectedData
|
||||
return collectResult, nil
|
||||
}
|
||||
|
||||
func parseCollectorOutput(output string) (map[string][]byte, error) {
|
||||
input := make(map[string]interface{})
|
||||
files := make(map[string][]byte)
|
||||
if err := json.Unmarshal([]byte(output), &input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for filename, maybeContents := range input {
|
||||
fileDir, fileName := filepath.Split(filename)
|
||||
|
||||
switch maybeContents.(type) {
|
||||
case string:
|
||||
decoded, err := base64.StdEncoding.DecodeString(maybeContents.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files[filepath.Join(fileDir, fileName)] = decoded
|
||||
|
||||
case map[string]interface{}:
|
||||
for k, v := range maybeContents.(map[string]interface{}) {
|
||||
decoded, err := base64.StdEncoding.DecodeString(v.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files[filepath.Join(fileDir, fileName, k)] = decoded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func ensureCollectorInList(list []*troubleshootv1beta1.Collect, collector troubleshootv1beta1.Collect) []*troubleshootv1beta1.Collect {
|
||||
for _, inList := range list {
|
||||
if collector.ClusterResources != nil && inList.ClusterResources != nil {
|
||||
return list
|
||||
}
|
||||
if collector.ClusterInfo != nil && inList.ClusterInfo != nil {
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
return append(list, &collector)
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type PreflightServerOptions struct {
|
||||
ImageName string
|
||||
PullPolicy string
|
||||
|
||||
Name string
|
||||
Namespace string
|
||||
|
||||
OwnerReference metav1.Object
|
||||
}
|
||||
|
||||
func CreatePreflightServer(client client.Client, scheme *runtime.Scheme, options PreflightServerOptions) (*corev1.Pod, *corev1.Service, error) {
|
||||
name := fmt.Sprintf("%s-%s", options.Name, "preflight")
|
||||
namespacedName := types.NamespacedName{
|
||||
Name: name,
|
||||
Namespace: options.Namespace,
|
||||
}
|
||||
|
||||
found := &corev1.Pod{}
|
||||
err := client.Get(context.Background(), namespacedName, found)
|
||||
if err == nil || !kuberneteserrors.IsNotFound(err) {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
imageName := "replicated/troubleshoot:latest"
|
||||
imagePullPolicy := corev1.PullAlways
|
||||
|
||||
if options.ImageName != "" {
|
||||
imageName = options.ImageName
|
||||
}
|
||||
if options.PullPolicy != "" {
|
||||
imagePullPolicy = corev1.PullPolicy(options.PullPolicy)
|
||||
}
|
||||
|
||||
podLabels := make(map[string]string)
|
||||
podLabels["preflight"] = options.Name
|
||||
podLabels["troubleshoot-role"] = "preflight"
|
||||
|
||||
pod := corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: options.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 scheme != nil {
|
||||
if err := controllerutil.SetControllerReference(options.OwnerReference, &pod, scheme); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := client.Create(context.Background(), &pod); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
service := corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: options.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 scheme != nil {
|
||||
if err := controllerutil.SetControllerReference(options.OwnerReference, &service, scheme); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := client.Create(context.Background(), &service); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// wait for the server to be ready
|
||||
// TODO
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
return &pod, &service, nil
|
||||
}
|
||||
20
pkg/preflight/types.go
Normal file
20
pkg/preflight/types.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package preflight
|
||||
|
||||
type UploadPreflightResult struct {
|
||||
IsFail bool `json:"isFail,omitempty"`
|
||||
IsWarn bool `json:"isWarn,omitempty"`
|
||||
IsPass bool `json:"isPass,omitempty"`
|
||||
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
URI string `json:"uri,omitempty"`
|
||||
}
|
||||
|
||||
type UploadPreflightError struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type UploadPreflightResults struct {
|
||||
Results []*UploadPreflightResult `json:"results,omitempty"`
|
||||
Errors []*UploadPreflightError `json:"errors,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user