mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-02-14 18:29:53 +00:00
fix: [sc-106256] Add missing uri field to troubleshoot.sh types (#1578)
* new no-uri flag for preflight * implement load additional spec from URIs
This commit is contained in:
@@ -71,6 +71,7 @@ that a cluster meets the requirements to run an application.`,
|
||||
// Dry run flag should be in cmd.PersistentFlags() flags made available to all subcommands
|
||||
// Adding here to avoid that
|
||||
cmd.Flags().Bool("dry-run", false, "print the preflight spec without running preflight checks")
|
||||
cmd.Flags().Bool("no-uri", false, "When this flag is used, Preflight does not attempt to retrieve the spec referenced by the uri: field`")
|
||||
|
||||
k8sutil.AddFlags(cmd.Flags())
|
||||
|
||||
|
||||
@@ -361,3 +361,81 @@ func LoadFromCluster(ctx context.Context, client kubernetes.Interface, selectors
|
||||
RawSpecs: rawSpecs,
|
||||
})
|
||||
}
|
||||
|
||||
// LoadAdditionalSpecFromURIs loads additional specs from the URIs provided in the kinds.
|
||||
// This function will modify kinds in place.
|
||||
func LoadAdditionalSpecFromURIs(ctx context.Context, kinds *loader.TroubleshootKinds) {
|
||||
|
||||
obj := reflect.ValueOf(*kinds)
|
||||
|
||||
// iterate over all fields of the TroubleshootKinds
|
||||
// e.g. SupportBundlesV1Beta2, PreflightsV1Beta2, etc.
|
||||
for i := 0; i < obj.NumField(); i++ {
|
||||
field := obj.Field(i)
|
||||
if field.Kind() != reflect.Slice {
|
||||
continue
|
||||
}
|
||||
|
||||
// look at each spec in the slice
|
||||
// e.g. each spec in []PreflightsV1Beta2
|
||||
for count := 0; count < field.Len(); count++ {
|
||||
currentSpec := field.Index(count)
|
||||
specName := currentSpec.Type().Name()
|
||||
|
||||
// check if .Spec.Uri exists
|
||||
specField := currentSpec.FieldByName("Spec")
|
||||
if !specField.IsValid() {
|
||||
continue
|
||||
}
|
||||
uriField := specField.FieldByName("Uri")
|
||||
if uriField.Kind() != reflect.String {
|
||||
continue
|
||||
}
|
||||
|
||||
// download spec from URI
|
||||
uri := uriField.String()
|
||||
if uri == "" {
|
||||
continue
|
||||
}
|
||||
rawSpec, err := downloadFromHttpURL(ctx, uri, nil)
|
||||
if err != nil {
|
||||
klog.Warningf("failed to download spec from URI %q: %v", uri, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// load spec from raw spec
|
||||
uriKinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{RawSpec: string(rawSpec)})
|
||||
if err != nil {
|
||||
klog.Warningf("failed to load spec from URI %q: %v", uri, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// replace original spec with the loaded spec from URI
|
||||
newSpec := getFirstSpecOf(uriKinds, specName)
|
||||
if !newSpec.IsValid() {
|
||||
klog.Warningf("failed to read spec of type %s in URI %s", specName, uri)
|
||||
continue
|
||||
}
|
||||
currentSpec.Set(newSpec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dynamically get spec from kinds of given name
|
||||
// return first element of the spec slice
|
||||
func getFirstSpecOf(kinds *loader.TroubleshootKinds, name string) reflect.Value {
|
||||
obj := reflect.ValueOf(*kinds)
|
||||
for i := 0; i < obj.NumField(); i++ {
|
||||
field := obj.Field(i)
|
||||
if field.Kind() != reflect.Slice {
|
||||
continue
|
||||
}
|
||||
if field.Len() > 0 {
|
||||
if field.Index(0).Type().Name() == name {
|
||||
// return first element
|
||||
return field.Index(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
return reflect.Value{}
|
||||
}
|
||||
|
||||
@@ -224,3 +224,39 @@ spec:
|
||||
require.NoError(t, err)
|
||||
require.Len(t, specs.HostCollectorsV1Beta2, 1)
|
||||
}
|
||||
|
||||
func TestLoadAdditionalSpecFromURIs(t *testing.T) {
|
||||
m := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`apiVersion: troubleshoot.sh/v1beta2
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Preflight
|
||||
metadata:
|
||||
name: preflight-2
|
||||
spec:
|
||||
collectors:
|
||||
- ceph: {}
|
||||
`))
|
||||
}))
|
||||
defer m.Close()
|
||||
kinds := loader.NewTroubleshootKinds()
|
||||
kinds.PreflightsV1Beta2 = []troubleshootv1beta2.Preflight{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "preflight-1",
|
||||
},
|
||||
Spec: troubleshootv1beta2.PreflightSpec{
|
||||
Uri: m.URL,
|
||||
Collectors: []*troubleshootv1beta2.Collect{
|
||||
{
|
||||
DNS: &troubleshootv1beta2.DNS{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
LoadAdditionalSpecFromURIs(context.Background(), kinds)
|
||||
require.Len(t, kinds.PreflightsV1Beta2, 1)
|
||||
require.Len(t, kinds.PreflightsV1Beta2[0].Spec.Collectors, 1)
|
||||
require.NotNil(t, kinds.PreflightsV1Beta2[0].Spec.Collectors[0].Ceph)
|
||||
}
|
||||
|
||||
@@ -29,6 +29,12 @@ func readSpecs(args []string) (*loader.TroubleshootKinds, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Load additional specs from URIs
|
||||
// only when no-uri flag is not set
|
||||
if !viper.GetBool("no-uri") {
|
||||
specs.LoadAdditionalSpecFromURIs(ctx, kinds)
|
||||
}
|
||||
|
||||
ret := loader.NewTroubleshootKinds()
|
||||
|
||||
// Concatenate all preflight inclusterSpecs that don't have an upload destination
|
||||
|
||||
Reference in New Issue
Block a user