Deployment and statefulset

This commit is contained in:
Marc Campbell
2019-11-07 02:07:05 +00:00
parent 6e7715a145
commit fb5f1522ea
5 changed files with 156 additions and 132 deletions
+120
View File
@@ -0,0 +1,120 @@
package analyzer
import (
"strconv"
"strings"
"github.com/pkg/errors"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
)
func commonStatus(outcomes []*troubleshootv1beta1.Outcome, readyReplicas int) (*AnalyzeResult, error) {
result := &AnalyzeResult{}
// ordering from the spec is important, the first one that matches returns
for _, outcome := range outcomes {
if outcome.Fail != nil {
if outcome.Fail.When == "" {
result.IsFail = true
result.Message = outcome.Fail.Message
result.URI = outcome.Fail.URI
return result, nil
}
match, err := compareActualToWhen(outcome.Fail.When, readyReplicas)
if err != nil {
return nil, errors.Wrap(err, "failed to parse fail range")
}
if match {
result.IsFail = true
result.Message = outcome.Fail.Message
result.URI = outcome.Fail.URI
return result, nil
}
} else if outcome.Warn != nil {
if outcome.Warn.When == "" {
result.IsWarn = true
result.Message = outcome.Warn.Message
result.URI = outcome.Warn.URI
return result, nil
}
match, err := compareActualToWhen(outcome.Warn.When, readyReplicas)
if err != nil {
return nil, errors.Wrap(err, "failed to parse warn range")
}
if match {
result.IsWarn = true
result.Message = outcome.Warn.Message
result.URI = outcome.Warn.URI
return result, nil
}
} else if outcome.Pass != nil {
if outcome.Pass.When == "" {
result.IsPass = true
result.Message = outcome.Pass.Message
result.URI = outcome.Pass.URI
return result, nil
}
match, err := compareActualToWhen(outcome.Pass.When, readyReplicas)
if err != nil {
return nil, errors.Wrap(err, "failed to parse pass range")
}
if match {
result.IsPass = true
result.Message = outcome.Pass.Message
result.URI = outcome.Pass.URI
return result, nil
}
}
}
return result, nil
}
func compareActualToWhen(when string, actual int) (bool, error) {
parts := strings.Split(strings.TrimSpace(when), " ")
// we can make this a lot more flexible
if len(parts) != 2 {
return false, errors.New("unable to parse when range")
}
value, err := strconv.Atoi(parts[1])
if err != nil {
return false, errors.New("unable to parse when value")
}
switch parts[0] {
case "=":
fallthrough
case "==":
fallthrough
case "===":
return actual == value, nil
case "<":
return actual < value, nil
case ">":
return actual > value, nil
case "<=":
return actual <= value, nil
case ">=":
return actual >= value, nil
}
return false, errors.Errorf("unknown comparator: %q", parts[0])
}
+4 -117
View File
@@ -4,8 +4,6 @@ import (
"encoding/json"
"fmt"
"path"
"strconv"
"strings"
"github.com/pkg/errors"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
@@ -24,14 +22,10 @@ func deploymentStatus(analyzer *troubleshootv1beta1.DeploymentStatus, getCollect
}
var status *appsv1.DeploymentStatus
if analyzer.Name != "" {
for _, deployment := range deployments {
if deployment.Name == analyzer.Name {
status = &deployment.Status
}
for _, deployment := range deployments {
if deployment.Name == analyzer.Name {
status = &deployment.Status
}
} else if analyzer.Selector != nil {
}
if status == nil {
@@ -42,112 +36,5 @@ func deploymentStatus(analyzer *troubleshootv1beta1.DeploymentStatus, getCollect
}, nil
}
result := &AnalyzeResult{}
// ordering from the spec is important, the first one that matches returns
for _, outcome := range analyzer.Outcomes {
if outcome.Fail != nil {
if outcome.Fail.When == "" {
result.IsFail = true
result.Message = outcome.Fail.Message
result.URI = outcome.Fail.URI
return result, nil
}
match, err := compareActualToWhen(outcome.Fail.When, int(status.ReadyReplicas))
if err != nil {
return nil, errors.Wrap(err, "failed to parse fail range")
}
if match {
result.IsFail = true
result.Message = outcome.Fail.Message
result.URI = outcome.Fail.URI
return result, nil
}
} else if outcome.Warn != nil {
if outcome.Warn.When == "" {
result.IsWarn = true
result.Message = outcome.Warn.Message
result.URI = outcome.Warn.URI
return result, nil
}
match, err := compareActualToWhen(outcome.Warn.When, int(status.ReadyReplicas))
if err != nil {
return nil, errors.Wrap(err, "failed to parse warn range")
}
if match {
result.IsWarn = true
result.Message = outcome.Warn.Message
result.URI = outcome.Warn.URI
return result, nil
}
} else if outcome.Pass != nil {
if outcome.Pass.When == "" {
result.IsPass = true
result.Message = outcome.Pass.Message
result.URI = outcome.Pass.URI
return result, nil
}
match, err := compareActualToWhen(outcome.Pass.When, int(status.ReadyReplicas))
if err != nil {
return nil, errors.Wrap(err, "failed to parse pass range")
}
if match {
result.IsPass = true
result.Message = outcome.Pass.Message
result.URI = outcome.Pass.URI
return result, nil
}
}
}
return result, nil
}
func compareActualToWhen(when string, actual int) (bool, error) {
parts := strings.Split(strings.TrimSpace(when), " ")
// we can make this a lot more flexible
if len(parts) != 2 {
return false, errors.New("unable to parse when range")
}
value, err := strconv.Atoi(parts[1])
if err != nil {
return false, errors.New("unable to parse when value")
}
switch parts[0] {
case "=":
fallthrough
case "==":
fallthrough
case "===":
return actual == value, nil
case "<":
return actual < value, nil
case ">":
return actual > value, nil
case "<=":
return actual <= value, nil
case ">=":
return actual >= value, nil
}
return false, errors.Errorf("unknown comparator: %q", parts[0])
return commonStatus(analyzer.Outcomes, int(status.ReadyReplicas))
}
+30 -1
View File
@@ -1,11 +1,40 @@
package analyzer
import (
"encoding/json"
"fmt"
"path"
"github.com/pkg/errors"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
appsv1 "k8s.io/api/apps/v1"
)
func statefulsetStatus(analyzer *troubleshootv1beta1.StatefulsetStatus, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
collected, err := getCollectedFileContents(path.Join("cluster-resources", "statefulsets", fmt.Sprintf("%s.json", analyzer.Namespace)))
if err != nil {
return nil, errors.Wrap(err, "failed to read collected deployments from namespace")
}
return nil, errors.New("not implemented")
var statefulsets []appsv1.StatefulSet
if err := json.Unmarshal(collected, &statefulsets); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal statefulset list")
}
var status *appsv1.StatefulSetStatus
for _, statefulset := range statefulsets {
if statefulset.Name == analyzer.Name {
status = &statefulset.Status
}
}
if status == nil {
// there's not an error, but maybe the requested statefulset is not even deployed
return &AnalyzeResult{
IsFail: true,
Message: "not found",
}, nil
}
return commonStatus(analyzer.Outcomes, int(status.ReadyReplicas))
}
@@ -54,16 +54,14 @@ type DeploymentStatus struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
Namespace string `json:"namespace" yaml:"namespace"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Selector []string `json:"selector,omitempty" yaml:"selector,omitempty"`
Name string `json:"name" yaml:"name"`
}
type StatefulsetStatus struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
Namespace string `json:"namespace" yaml:"namespace"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Selector []string `json:"selector,omitempty" yaml:"selector,omitempty"`
Name string `json:"name" yaml:"name"`
}
type AnalyzeMeta struct {
@@ -756,11 +756,6 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) {
}
}
}
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatus.
@@ -1364,11 +1359,6 @@ func (in *StatefulsetStatus) DeepCopyInto(out *StatefulsetStatus) {
}
}
}
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulsetStatus.