Skip to content

Commit

Permalink
improve/rename local source to support multiple configmaps
Browse files Browse the repository at this point in the history
- new name is "configmaps"
- updated unpacker to use a separate client/cache which is capable
  of watching all objects in the rukpak system namespace
- added a webhook for bundles and configmaps to ensure expected
  invariants around bundle immutability are met.
  • Loading branch information
joelanford committed Mar 29, 2023
1 parent 218217c commit ab7e5fe
Show file tree
Hide file tree
Showing 32 changed files with 468 additions and 598 deletions.
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ clean: ## Remove binaries and test artifacts

generate: controller-gen ## Generate code and manifests
$(Q)$(CONTROLLER_GEN) crd:crdVersions=v1,generateEmbeddedObjectMeta=true output:crd:dir=./manifests/apis/crds paths=./api/...
$(Q)$(CONTROLLER_GEN) webhook paths=./api/... output:stdout > ./manifests/apis/webhooks/resources/webhook.yaml
$(Q)$(CONTROLLER_GEN) webhook paths=./api/... paths=./internal/webhook/... output:stdout > ./manifests/apis/webhooks/resources/webhook.yaml
$(Q)$(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths=./api/...
$(Q)$(CONTROLLER_GEN) rbac:roleName=core-admin \
paths=./internal/provisioner/bundle/... \
Expand All @@ -77,6 +77,7 @@ generate: controller-gen ## Generate code and manifests
paths=./internal/provisioner/registry/... \
paths=./internal/uploadmgr/... \
output:stdout > ./manifests/core/resources/cluster_role.yaml
$(Q)$(CONTROLLER_GEN) rbac:roleName=webhooks-admin paths=./internal/webhook/... output:stdout > ./manifests/apis/webhooks/resources/cluster_role.yaml
$(Q)$(CONTROLLER_GEN) rbac:roleName=helm-provisioner-admin \
paths=./internal/provisioner/bundle/... \
paths=./internal/provisioner/bundledeployment/... \
Expand All @@ -100,10 +101,10 @@ UNIT_TEST_DIRS=$(shell go list ./... | grep -v /test/)
test-unit: setup-envtest ## Run the unit tests
eval $$($(SETUP_ENVTEST) use -p env $(ENVTEST_VERSION)) && go test -tags $(GO_BUILD_TAGS) -count=1 -short $(UNIT_TEST_DIRS)

FOCUS := $(if $(TEST),-v -focus "$(TEST)")
E2E_FLAGS ?= ""
FOCUS := $(if $(TEST),-v --focus "$(TEST)")
E2E_FLAGS ?=
test-e2e: ginkgo ## Run the e2e tests
$(GINKGO) --tags $(GO_BUILD_TAGS) $(E2E_FLAGS) -trace -progress $(FOCUS) test/e2e
$(GINKGO) --tags $(GO_BUILD_TAGS) $(E2E_FLAGS) --trace --progress $(FOCUS) test/e2e

e2e: KIND_CLUSTER_NAME=rukpak-e2e
e2e: rukpakctl run image-registry local-git kind-load-bundles registry-load-bundles test-e2e kind-cluster-cleanup ## Run e2e tests against an ephemeral kind cluster
Expand Down
23 changes: 14 additions & 9 deletions api/v1alpha1/bundle_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ var (
type SourceType string

const (
SourceTypeImage SourceType = "image"
SourceTypeGit SourceType = "git"
SourceTypeLocal SourceType = "local"
SourceTypeUpload SourceType = "upload"
SourceTypeHTTP SourceType = "http"
SourceTypeImage SourceType = "image"
SourceTypeGit SourceType = "git"
SourceTypeConfigMaps SourceType = "configMaps"
SourceTypeUpload SourceType = "upload"
SourceTypeHTTP SourceType = "http"

TypeUnpacked = "Unpacked"

Expand Down Expand Up @@ -65,8 +65,9 @@ type BundleSource struct {
Image *ImageSource `json:"image,omitempty"`
// Git is the git repository that backs the content of this Bundle.
Git *GitSource `json:"git,omitempty"`
// Local is a reference to a local object in the cluster.
Local *LocalSource `json:"local,omitempty"`
// ConfigMaps is a list of config map references and their relative
// directory paths that represent a bundle filesystem.
ConfigMaps []ConfigMapSource `json:"configMaps,omitempty"`
// Upload is a source that enables this Bundle's content to be uploaded
// via Rukpak's bundle upload service. This source type is primarily useful
// with bundle development workflows because it enables bundle developers
Expand Down Expand Up @@ -99,8 +100,12 @@ type GitSource struct {
Auth Authorization `json:"auth,omitempty"`
}

type LocalSource struct {
ConfigMapRef *ConfigMapRef `json:"configMap"`
type ConfigMapSource struct {
// ConfigMap is a reference to a configmap in the rukpak system namespace
ConfigMap corev1.LocalObjectReference `json:"configMap"`
// Path is the relative directory path within the bundle where the files
// from the configmap will be present when the bundle is unpacked.
Path string `json:"path,omitempty"`
}

type HTTPSource struct {
Expand Down
9 changes: 9 additions & 0 deletions api/v1alpha1/bundle_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ func checkBundleSource(r *Bundle) error {
if strings.HasPrefix(filepath.Clean(r.Spec.Source.Git.Directory), "../") {
return fmt.Errorf(`bundle.spec.source.git.directory begins with "../": directory must define path within the repository`)
}
case SourceTypeConfigMaps:
if len(r.Spec.Source.ConfigMaps) == 0 {
return fmt.Errorf(`bundle.spec.source.configmaps must be set for source type "configmaps"`)
}
for i, cm := range r.Spec.Source.ConfigMaps {
if strings.HasPrefix(filepath.Clean(cm.Path), ".."+string(filepath.Separator)) {
return fmt.Errorf("bundle.spec.source.configmaps[%d].path is invalid: %s is outside bundle root", i, cm.Path)
}
}
}
return nil
}
Expand Down
44 changes: 20 additions & 24 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 19 additions & 5 deletions cmd/core/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/cluster"
crfinalizer "sigs.k8s.io/controller-runtime/pkg/finalizer"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
Expand Down Expand Up @@ -116,6 +117,15 @@ func main() {
dependentSelector := labels.NewSelector().Add(*dependentRequirement)

cfg := ctrl.GetConfigOrDie()
systemNs := util.PodNamespace(systemNamespace)
systemNsCluster, err := cluster.New(cfg, func(opts *cluster.Options) {
opts.Scheme = scheme
opts.Namespace = systemNs
})
if err != nil {
setupLog.Error(err, "unable to create system namespace cluster")
os.Exit(1)
}
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: httpBindAddr,
Expand All @@ -138,7 +148,11 @@ func main() {
os.Exit(1)
}

ns := util.PodNamespace(systemNamespace)
if err := mgr.Add(systemNsCluster); err != nil {
setupLog.Error(err, "unable to add system namespace cluster to manager")
os.Exit(1)
}

storageURL, err := url.Parse(fmt.Sprintf("%s/bundles/", httpExternalAddr))
if err != nil {
setupLog.Error(err, "unable to parse bundle content server URL")
Expand Down Expand Up @@ -201,7 +215,7 @@ func main() {
os.Exit(1)
}

unpacker, err := source.NewDefaultUnpacker(mgr, ns, unpackImage, baseUploadManagerURL, rootCAs)
unpacker, err := source.NewDefaultUnpacker(systemNsCluster, systemNs, unpackImage, baseUploadManagerURL, rootCAs)
if err != nil {
setupLog.Error(err, "unable to setup bundle unpacker")
os.Exit(1)
Expand All @@ -216,12 +230,12 @@ func main() {
cfgGetter := helmclient.NewActionConfigGetter(mgr.GetConfig(), mgr.GetRESTMapper(), mgr.GetLogger())
acg := helmclient.NewActionClientGetter(cfgGetter)
commonBDProvisionerOptions := []bundledeployment.Option{
bundledeployment.WithReleaseNamespace(ns),
bundledeployment.WithReleaseNamespace(systemNs),
bundledeployment.WithActionClientGetter(acg),
bundledeployment.WithStorage(bundleStorage),
}

if err := bundle.SetupProvisioner(mgr, append(
if err := bundle.SetupProvisioner(mgr, systemNsCluster.GetCache(), systemNs, append(
commonBundleProvisionerOptions,
bundle.WithProvisionerID(plain.ProvisionerID),
bundle.WithHandler(bundle.HandlerFunc(plain.HandleBundle)),
Expand All @@ -230,7 +244,7 @@ func main() {
os.Exit(1)
}

if err := bundle.SetupProvisioner(mgr, append(
if err := bundle.SetupProvisioner(mgr, systemNsCluster.GetCache(), systemNs, append(
commonBundleProvisionerOptions,
bundle.WithProvisionerID(registry.ProvisionerID),
bundle.WithHandler(bundle.HandlerFunc(registry.HandleBundle)),
Expand Down
22 changes: 18 additions & 4 deletions cmd/helm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/cluster"
crfinalizer "sigs.k8s.io/controller-runtime/pkg/finalizer"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
Expand Down Expand Up @@ -106,6 +107,15 @@ func main() {
dependentSelector := labels.NewSelector().Add(*dependentRequirement)

cfg := ctrl.GetConfigOrDie()
systemNs := util.PodNamespace(systemNamespace)
systemNsCluster, err := cluster.New(cfg, func(opts *cluster.Options) {
opts.Scheme = scheme
opts.Namespace = systemNs
})
if err != nil {
setupLog.Error(err, "unable to create system namespace cluster")
os.Exit(1)
}
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: httpBindAddr,
Expand All @@ -128,7 +138,11 @@ func main() {
os.Exit(1)
}

ns := util.PodNamespace(systemNamespace)
if err := mgr.Add(systemNsCluster); err != nil {
setupLog.Error(err, "unable to add system namespace cluster to manager")
os.Exit(1)
}

storageURL, err := url.Parse(fmt.Sprintf("%s/bundles/", httpExternalAddr))
if err != nil {
setupLog.Error(err, "unable to parse bundle content server URL")
Expand Down Expand Up @@ -183,7 +197,7 @@ func main() {
os.Exit(1)
}

unpacker, err := source.NewDefaultUnpacker(mgr, ns, unpackImage, baseUploadManagerURL, rootCAs)
unpacker, err := source.NewDefaultUnpacker(systemNsCluster, systemNs, unpackImage, baseUploadManagerURL, rootCAs)
if err != nil {
setupLog.Error(err, "unable to setup bundle unpacker")
os.Exit(1)
Expand All @@ -198,12 +212,12 @@ func main() {
cfgGetter := helmclient.NewActionConfigGetter(mgr.GetConfig(), mgr.GetRESTMapper(), mgr.GetLogger())
acg := helmclient.NewActionClientGetter(cfgGetter)
commonBDProvisionerOptions := []bundledeployment.Option{
bundledeployment.WithReleaseNamespace(ns),
bundledeployment.WithReleaseNamespace(systemNs),
bundledeployment.WithActionClientGetter(acg),
bundledeployment.WithStorage(bundleStorage),
}

if err := bundle.SetupProvisioner(mgr, append(
if err := bundle.SetupProvisioner(mgr, systemNsCluster.GetCache(), systemNs, append(
commonBundleProvisionerOptions,
bundle.WithProvisionerID(helm.ProvisionerID),
bundle.WithHandler(bundle.HandlerFunc(helm.HandleBundle)),
Expand Down
Loading

0 comments on commit ab7e5fe

Please sign in to comment.