Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .goreleaser.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,3 @@ release:
kubectl apply -f https://github.com/operator-framework/rukpak/releases/download/{{ .Tag }}/rukpak.yaml
kubectl wait --for=condition=Available --namespace=rukpak-system deployment/core --timeout=60s
kubectl wait --for=condition=Available --namespace=rukpak-system deployment/rukpak-webhooks --timeout=60s
kubectl wait --for=condition=Available --namespace=crdvalidator-system deployment/crd-validation-webhook --timeout=60s
```
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ kind-load-bundles: kind ## Load the e2e testdata container images into a kind cl
$(CONTAINER_RUNTIME) build $(TESTDATA_DIR)/bundles/plain-v0/invalid-crds-and-crs -t testdata/bundles/plain-v0:invalid-crds-and-crs
$(CONTAINER_RUNTIME) build $(TESTDATA_DIR)/bundles/plain-v0/subdir -t testdata/bundles/plain-v0:subdir
$(CONTAINER_RUNTIME) build $(TESTDATA_DIR)/bundles/registry/valid -t testdata/bundles/registry:valid
$(CONTAINER_RUNTIME) build $(TESTDATA_DIR)/bundles/registry/invalid -t testdata/bundles/registry:invalid
$(KIND) load docker-image testdata/bundles/plain-v0:valid --name $(KIND_CLUSTER_NAME)
$(KIND) load docker-image testdata/bundles/plain-v0:dependent --name $(KIND_CLUSTER_NAME)
$(KIND) load docker-image testdata/bundles/plain-v0:provides --name $(KIND_CLUSTER_NAME)
Expand All @@ -174,6 +175,7 @@ kind-load-bundles: kind ## Load the e2e testdata container images into a kind cl
$(KIND) load docker-image testdata/bundles/plain-v0:invalid-crds-and-crs --name $(KIND_CLUSTER_NAME)
$(KIND) load docker-image testdata/bundles/plain-v0:subdir --name $(KIND_CLUSTER_NAME)
$(KIND) load docker-image testdata/bundles/registry:valid --name $(KIND_CLUSTER_NAME)
$(KIND) load docker-image testdata/bundles/registry:invalid --name $(KIND_CLUSTER_NAME)

kind-load: kind ## Loads the currently constructed image onto the cluster
$(KIND) load docker-image $(IMAGE) --name $(KIND_CLUSTER_NAME)
Expand Down
2 changes: 1 addition & 1 deletion cmd/rukpakctl/cmd/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
2 changes: 1 addition & 1 deletion cmd/rukpakctl/cmd/bundledeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
2 changes: 1 addition & 1 deletion cmd/rukpakctl/cmd/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
2 changes: 1 addition & 1 deletion cmd/rukpakctl/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
1 change: 1 addition & 0 deletions cmd/rukpakctl/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

Expand Down
1 change: 1 addition & 0 deletions cmd/rukpakctl/cmd/run.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

Expand Down
1 change: 1 addition & 0 deletions cmd/rukpakctl/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package main

Expand Down
4 changes: 3 additions & 1 deletion cmd/rukpakctl/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package utils

import (
"context"
"io/ioutil"
"os"
"path/filepath"

Expand All @@ -23,7 +25,7 @@ func CreateConfigmap(ctx context.Context, core typedv1.CoreV1Interface, name, di
if info.IsDir() {
return nil
}
c, err := os.ReadFile(path)
c, err := ioutil.ReadFile(path)
if err != nil {
return err
}
Expand Down
74 changes: 74 additions & 0 deletions docs/sources/http.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Http source

## Summary

The http source provides a compressed archive file (`tgz` format) downloadable by the http protocol as the source of the bundle.
The `source.type` for the http source is `http`. When creating a http source, a URL of the compressed archive file must be specified.
It is expected that a proper format of bundle content is present
in the compressed archive file.

## Example

Referencing a compressed archive file in a github repository release archive:

```yaml
apiVersion: core.rukpak.io/v1alpha1
kind: BundleDeployment
metadata:
name: my-ahoy
spec:
provisionerClassName: core-rukpak-io-helm
template:
metadata:
labels:
app: my-ahoy
spec:
provisionerClassName: core-rukpak-io-helm
source:
http:
url: https://github.com/helm/examples/releases/download/hello-world-0.1.0/hello-world-0.1.0.tgz
type: http
```

## Authorization

An http source can provide authorization for access to private compressed archives by creating a secret in the namespace that the provisioner is deployed.
The secret used in the http source is based around [Basic authentication secret](https://kubernetes.io/docs/concepts/configuration/secret/#basic-authentication-secret)
and is expected to contain `data.username` and `data.password` for the username and password, respectively.
If the `http.auth.secret.insecureSkipVerify` is set true, the download operation will accept any certificate presented by the server and any host name in that
certificate. In this mode, TLS is susceptible to machine-in-the-middle attacks unless custom verification is
used. This should be used only for testing.

### Example with authorization

1. Create the secret

```sh
kubectl create secret generic accesssecret --type "kubernetes.io/basic-auth" --from-literal=username=myusername --from-literal=password=mypassword -n rukpak-system
```

2. Create a bundle deployment referencing a private compressed archive file:

```bash
kubectl apply -f -<<EOF
apiVersion: core.rukpak.io/v1alpha1
kind: BundleDeployment
metadata:
name: my-ahoy
spec:
provisionerClassName: core-rukpak-io-helm
template:
metadata:
labels:
app: my-ahoy
spec:
provisionerClassName: core-rukpak-io-helm
source:
http:
url: https://github.com/helm/examples/releases/download/hello-world-0.1.0/hello-world-0.1.0.tgz
auth:
secret:
name: accesssecret
type: http
EOF
```
3 changes: 3 additions & 0 deletions internal/convert/registryv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ func Convert(in RegistryV1, installNamespace string, targetNamespaces []string)
supportedInstallModes.Insert(string(im.Type))
}
}
if !supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
return nil, fmt.Errorf("AllNamespace install mode must be enabled")
}
if targetNamespaces == nil {
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
targetNamespaces = []string{""}
Expand Down
18 changes: 9 additions & 9 deletions internal/crd/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import (
)

// Validate is a wrapper for doing four things:
// 1. Retrieving the existing version of the specified CRD where it exists.
// 2. Calling validateCRDCompatibility() on the newCrd.
// 3. Calling safeStorageVersionUpgrade() on the newCrd.
// 4. Reporting any errors that it encounters along the way.
// 1. Retrieving the existing version of the specified CRD where it exists.
// 2. Calling validateCRDCompatibility() on the newCrd.
// 3. Calling safeStorageVersionUpgrade() on the newCrd.
// 4. Reporting any errors that it encounters along the way.
func Validate(ctx context.Context, cl client.Client, newCrd *apiextensionsv1.CustomResourceDefinition) error {
oldCRD := &apiextensionsv1.CustomResourceDefinition{}

Expand Down Expand Up @@ -68,11 +68,11 @@ func keys(m map[string]apiextensionsv1.CustomResourceDefinitionVersion) sets.Str
}

// validateCRDCompatibility runs through the following cases to test:
// 1. New CRD removes version that Old CRD had => Must ensure nothing is stored at removed version
// 2. New CRD changes a version that Old CRD has => Must validate existing CRs with new schema
// 3. New CRD adds a version that Old CRD does not have =>
// - If conversion strategy is None, ensure existing CRs validate with new schema.
// - If conversion strategy is Webhook, allow update (assume webhook handles conversion correctly)
// 1. New CRD removes version that Old CRD had => Must ensure nothing is stored at removed version
// 2. New CRD changes a version that Old CRD has => Must validate existing CRs with new schema
// 3. New CRD adds a version that Old CRD does not have =>
// - If conversion strategy is None, ensure existing CRs validate with new schema.
// - If conversion strategy is Webhook, allow update (assume webhook handles conversion correctly)
func validateCRDCompatibility(ctx context.Context, cl client.Client, oldCRD *apiextensionsv1.CustomResourceDefinition, newCRD *apiextensionsv1.CustomResourceDefinition) error {
oldVersions := map[string]apiextensionsv1.CustomResourceDefinitionVersion{}
newVersions := map[string]apiextensionsv1.CustomResourceDefinitionVersion{}
Expand Down
54 changes: 47 additions & 7 deletions internal/source/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"
"path/filepath"
"strings"
"syscall"

"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/memfs"
Expand Down Expand Up @@ -107,10 +108,19 @@ func (r *Git) Unpack(ctx context.Context, bundle *rukpakv1alpha1.Bundle) (*Resul
bundleFS = &billyFS{sub}
}

commitHash, err := repo.ResolveRevision("HEAD")
if err != nil {
return nil, fmt.Errorf("resolve commit hash: %v", err)
}

resolvedGit := bundle.Spec.Source.Git.DeepCopy()
resolvedGit.Ref = rukpakv1alpha1.GitRef{
Commit: commitHash.String(),
}

resolvedSource := &rukpakv1alpha1.BundleSource{
Type: rukpakv1alpha1.SourceTypeGit,
// TODO: improve git source implementation to return result with commit hash.
Git: bundle.Spec.Source.Git.DeepCopy(),
Git: resolvedGit,
}

return &Result{Bundle: bundleFS, ResolvedSource: resolvedSource, State: StateUnpacked}, nil
Expand Down Expand Up @@ -209,12 +219,18 @@ func (f *billyFS) ReadFile(name string) ([]byte, error) {
}

func (f *billyFS) Open(path string) (fs.File, error) {
fi, err := f.Filesystem.Stat(path)
if err != nil {
return nil, err
}
if fi.IsDir() {
return &billyDirFile{billyFile{nil, fi}, f, path}, nil
}
file, err := f.Filesystem.Open(path)
if err != nil {
return nil, err
}
fi, err := f.Filesystem.Stat(path)
return &billyFile{file, fi, err}, nil
return &billyFile{file, fi}, nil
}

func (f *billyFS) ReadDir(name string) ([]fs.DirEntry, error) {
Expand All @@ -231,10 +247,34 @@ func (f *billyFS) ReadDir(name string) ([]fs.DirEntry, error) {

type billyFile struct {
billy.File
fi os.FileInfo
fiErr error
fi os.FileInfo
}

func (b billyFile) Stat() (fs.FileInfo, error) {
return b.fi, b.fiErr
return b.fi, nil
}

func (b billyFile) Close() error {
if b.File == nil {
return nil
}
return b.File.Close()
}

type billyDirFile struct {
billyFile
fs *billyFS
path string
}

func (d *billyDirFile) ReadDir(n int) ([]fs.DirEntry, error) {
entries, err := d.fs.ReadDir(d.path)
if n <= 0 || n > len(entries) {
n = len(entries)
}
return entries[:n], err
}

func (d billyDirFile) Read(data []byte) (int, error) {
return 0, &fs.PathError{Op: "read", Path: d.path, Err: syscall.EISDIR}
}
Loading