func GetCRDs(fs http.FileSystem) ([]CRDFile, error) {
	log.Info("Getting CRDs")
	crddir, err := fs.Open(".")
	if err != nil {
		return nil, errors.Wrap(err, "failed to list cluster API CRDs")
	}
	log.Info("Opened CRDs")
	crdFiles := make([]CRDFile, 0)
	for {
		entry, err := crddir.Readdir(1)
		if err != nil && err != io.EOF {
			return nil, errors.Wrap(err, "failed to open cluster API CRD directory")
		}
		if entry == nil {
			break
		}
		if entry[0].IsDir() || !strings.HasPrefix(entry[0].Name(), "cluster") {
			continue
		}
		fname := entry[0].Name()
		crd, err := fs.Open(fname)
		if err != nil {
			return nil, errors.Wrap(err, "failed to open cluster API CRD")
		}
		data, err := ioutil.ReadAll(crd)
		if err != nil {
			return nil, errors.Wrap(err, "failed to read cluster API CRD")
		}
		crdFiles = append(crdFiles, CRDFile{fname, data})
	}
	log.Info("Got CRDs")
	return crdFiles, nil
}
Retrieve all CRD definitions needed for cluster API
package os
import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"path/filepath"
	"regexp"
	"strings"
	"text/template"
	"github.com/drone/envsubst"
	"github.com/fatih/structs"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	existinginfrav1 "github.com/weaveworks/cluster-api-provider-existinginfra/apis/cluster.weave.works/v1alpha3"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/apis/wksprovider/machine/config"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/apis/wksprovider/machine/crds"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/flavors/eksd"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/recipe"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/resource"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/runners/sudo"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/envcfg"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/kubeadm"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/manifest"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/object"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/version"
	"github.com/weaveworks/libgitops/pkg/serializer"
	appsv1 "k8s.io/api/apps/v1"
	"k8s.io/api/apps/v1beta2"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
	"sigs.k8s.io/yaml"
)
const (
	LocalCluster              = "wks.weave.works/local-cluster"
	Created                   = "wks.weave.works/is-created"
	PemDestDir                = "/etc/pki/weaveworks/wksctl/pem"
	ConfigDestDir             = "/etc/pki/weaveworks/wksctl"
	sealedSecretVersion       = "v0.11.0"
	sealedSecretKeySecretName = "sealed-secrets-key"
	fluxSecretTemplate        = `apiVersion: v1
{{ if .SecretValue }}
data:
  identity: {{.SecretValue}}
{{ end }}
kind: Secret
metadata:
  name: flux-git-deploy
  namespace: {{.Namespace}}
type: Opaque`
	connectionSecretTemplate = `apiVersion: v1
data:
  config: {{.SecretValue}}
kind: Secret
metadata:
  name: connection-info
  namespace: {{.Namespace}}
type: Opaque`
)
type OS struct {
	Name    string
	Runner  plan.Runner
	PkgType resource.PkgType
}
type CRDFile struct {
	Fname string
	Data  []byte
}