Fuzzing: Initial commit
Signed-off-by: AdamKorcz <adam@adalogics.com>
This commit is contained in:
parent
b18584a652
commit
7f8441672e
|
|
@ -0,0 +1,29 @@
|
|||
FROM golang:1.16-buster as builder
|
||||
|
||||
RUN apt-get update && apt-get install -y git vim clang
|
||||
RUN git clone https://github.com/fluxcd/kustomize-controller /kustomize-controller
|
||||
|
||||
WORKDIR /kustomize-controller
|
||||
|
||||
# fillippo.io/age v1.0.0-beta7 throws an error
|
||||
RUN sed 's/filippo.io\/age v1.0.0-beta7/filippo.io\/age v1.0.0/g' -i /kustomize-controller/go.mod
|
||||
RUN make download-crd-deps
|
||||
RUN mkdir /kustomize-controller/fuzz
|
||||
COPY fuzz.go /kustomize-controller/controllers/
|
||||
|
||||
RUN go mod tidy
|
||||
|
||||
RUN cd / \
|
||||
&& go get -u github.com/dvyukov/go-fuzz/go-fuzz@latest github.com/dvyukov/go-fuzz/go-fuzz-build@latest
|
||||
RUN go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
|
||||
RUN go get github.com/AdaLogics/go-fuzz-headers
|
||||
RUN go mod download golang.org/x/sync
|
||||
RUN go mod download github.com/dvyukov/go-fuzz
|
||||
|
||||
RUN mkdir /fuzzers
|
||||
RUN cd /kustomize-controller/controllers \
|
||||
&& go-fuzz-build -libfuzzer -func=Fuzz \
|
||||
&& clang -o /fuzzers/Fuzz reflect-fuzz.a \
|
||||
-fsanitize=fuzzer
|
||||
|
||||
RUN cd /kustomize-controller/controllers && /fuzzers/Fuzz
|
||||
|
|
@ -0,0 +1,591 @@
|
|||
// +build gofuzz
|
||||
/*
|
||||
Copyright 2021 The Flux authors
|
||||
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
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
|
||||
"github.com/fluxcd/pkg/runtime/controller"
|
||||
"github.com/fluxcd/pkg/testserver"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
)
|
||||
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var k8sManager ctrl.Manager
|
||||
var testEnv *envtest.Environment
|
||||
var kubeConfig []byte
|
||||
var testServer *testserver.ArtifactServer
|
||||
var testEventsH controller.Events
|
||||
var testMetricsH controller.Metrics
|
||||
var ctx = ctrl.SetupSignalHandler()
|
||||
var initter sync.Once
|
||||
var runningInOssfuzz = false
|
||||
var (
|
||||
localCRDpath = []string{filepath.Join("..", "config", "crd", "bases")}
|
||||
|
||||
// Variables for the OSS-fuzz environment:
|
||||
downloadLink = "https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-1.19.2-linux-amd64.tar.gz"
|
||||
downloadPath = "/tmp/envtest-bins.tar.gz"
|
||||
binariesDir = "/tmp/test-binaries"
|
||||
ossFuzzCrdPath = []string{filepath.Join(".", "bases")}
|
||||
ossFuzzCrdYaml = "https://raw.githubusercontent.com/fluxcd/kustomize-controller/main/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml"
|
||||
ossFuzzGitYaml = "https://raw.githubusercontent.com/fluxcd/source-controller/v0.15.4/config/crd/bases/source.toolkit.fluxcd.io_gitrepositories.yaml"
|
||||
ossFuzzBucYaml = "https://raw.githubusercontent.com/fluxcd/source-controller/v0.15.4/config/crd/bases/source.toolkit.fluxcd.io_buckets.yaml"
|
||||
crdPath []string
|
||||
pgpAscFile = "https://raw.githubusercontent.com/fluxcd/kustomize-controller/main/controllers/testdata/sops/pgp.asc"
|
||||
ageTxtFile = "https://raw.githubusercontent.com/fluxcd/kustomize-controller/main/controllers/testdata/sops/age.txt"
|
||||
)
|
||||
|
||||
// createKUBEBUILDER_ASSETS runs "setup-envtest use" and
|
||||
// returns the path of the 3 binaries that are created.
|
||||
// If this one fails, it means that setup-envtest is not
|
||||
// available in the runtime environment, and that means
|
||||
// that the fuzzer is being run by OSS-fuzz. In that case
|
||||
// we set "runningInOssfuzz" to true which will later trigger
|
||||
// download of all required files so the OSS-fuzz can run
|
||||
// the fuzzer.
|
||||
func createKUBEBUILDER_ASSETS() string {
|
||||
out, err := exec.Command("setup-envtest", "use").Output()
|
||||
if err != nil {
|
||||
// If there is an error here, the fuzzer is running
|
||||
// in OSS-fuzz where the binary setup-envtest is
|
||||
// not available, so we have to get them in an
|
||||
// alternative way
|
||||
runningInOssfuzz = true
|
||||
return ""
|
||||
}
|
||||
|
||||
// split the output:
|
||||
splitString := strings.Split(string(out), " ")
|
||||
binPath := strings.TrimSuffix(splitString[len(splitString)-1], "\n")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return binPath
|
||||
}
|
||||
|
||||
// Downloads a file to a path. This is only needed when
|
||||
// the fuzzer is running in OSS-fuzz.
|
||||
func DownloadFile(filepath string, url string) error {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Create the file
|
||||
out, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
return err
|
||||
}
|
||||
|
||||
// When OSS-fuzz runs the fuzzer a few files need to
|
||||
// be download during initialization. No files from the
|
||||
// kustomize-controller repo are available at runtime,
|
||||
// and each of the files that are needed must be downloaded
|
||||
// manually.
|
||||
func downloadFilesForOssFuzz() error {
|
||||
err := DownloadFile(downloadPath, downloadLink)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.MkdirAll(binariesDir, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command("tar", "xvf", downloadPath, "-C", binariesDir)
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Download crds
|
||||
err = os.MkdirAll("bases", 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DownloadFile("./bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml", ossFuzzCrdYaml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DownloadFile("./bases/source.toolkit.fluxcd.io_gitrepositories.yaml", ossFuzzGitYaml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DownloadFile("./bases/source.toolkit.fluxcd.io_buckets.yaml", ossFuzzBucYaml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Download sops files
|
||||
err = os.MkdirAll("testdata/sops", 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DownloadFile("./testdata/sops/pgp.asc", pgpAscFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DownloadFile("./testdata/sops/age.txt", ageTxtFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// customInit implements an init function that
|
||||
// is invoked by way of sync.Do
|
||||
func customInit() {
|
||||
kubebuilder_assets := createKUBEBUILDER_ASSETS()
|
||||
os.Setenv("KUBEBUILDER_ASSETS", kubebuilder_assets)
|
||||
|
||||
// Set up things for fuzzing in the OSS-fuzz environment:
|
||||
if runningInOssfuzz {
|
||||
err := downloadFilesForOssFuzz()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Setenv("KUBEBUILDER_ASSETS", binariesDir+"/kubebuilder/bin")
|
||||
crdPath = ossFuzzCrdPath
|
||||
runningInOssfuzz = false
|
||||
} else {
|
||||
crdPath = localCRDpath
|
||||
}
|
||||
|
||||
var err error
|
||||
err = sourcev1.AddToScheme(scheme.Scheme)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = kustomizev1.AddToScheme(scheme.Scheme)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: crdPath,
|
||||
}
|
||||
|
||||
testServer, err = testserver.NewTempArtifactServer()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create a temporary storage server: %v", err))
|
||||
}
|
||||
fmt.Println("Starting the test storage server")
|
||||
testServer.Start()
|
||||
|
||||
cfg, err = testEnv.Start()
|
||||
|
||||
user, err := testEnv.ControlPlane.AddUser(envtest.User{
|
||||
Name: "envtest-admin",
|
||||
Groups: []string{"system:masters"},
|
||||
}, nil)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create envtest-admin user: %v", err))
|
||||
}
|
||||
|
||||
kubeConfig, err = user.KubeConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create the envtest-admin user kubeconfig: %v", err))
|
||||
}
|
||||
|
||||
// client with caching disabled
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
||||
|
||||
k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
|
||||
Scheme: scheme.Scheme,
|
||||
})
|
||||
|
||||
if err := (&KustomizationReconciler{
|
||||
Client: k8sManager.GetClient(),
|
||||
}).SetupWithManager(k8sManager, KustomizationReconcilerOptions{MaxConcurrentReconciles: 1}); err != nil {
|
||||
panic(fmt.Sprintf("Failed to start GitRepositoryReconciler: %v", err))
|
||||
}
|
||||
time.Sleep(1*time.Second)
|
||||
|
||||
go func() {
|
||||
fmt.Println("Starting the test environment")
|
||||
if err := k8sManager.Start(ctx); err != nil {
|
||||
panic(fmt.Sprintf("Failed to start the test environment manager: %v", err))
|
||||
}
|
||||
}()
|
||||
time.Sleep(time.Second*1)
|
||||
<-k8sManager.Elected()
|
||||
}
|
||||
|
||||
// Fuzz implements the fuzz harness
|
||||
func Fuzz(data []byte) int {
|
||||
initter.Do(customInit)
|
||||
f := fuzz.NewConsumer(data)
|
||||
dname, err := os.MkdirTemp("", "artifact-dir")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
defer os.RemoveAll(dname)
|
||||
err = f.CreateFiles(dname)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
id, err := randString(f)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
namespace, err := createNamespaceForFuzzing(id)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
defer k8sClient.Delete(context.Background(), namespace)
|
||||
|
||||
fmt.Println("createKubeConfigSecretForFuzzing...")
|
||||
secret, err := createKubeConfigSecretForFuzzing(id)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return 0
|
||||
}
|
||||
defer k8sClient.Delete(context.Background(), secret)
|
||||
|
||||
artifactFile, err := randString(f)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
fmt.Println("createArtifact...")
|
||||
artifactChecksum, err := createArtifact(testServer, dname, artifactFile)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return 0
|
||||
}
|
||||
_ = artifactChecksum
|
||||
fmt.Println("testServer.URLForFile...")
|
||||
artifactURL, err := testServer.URLForFile(artifactFile)
|
||||
if err != nil {
|
||||
fmt.Println("URLForFile error: ", err)
|
||||
return 0
|
||||
}
|
||||
_ = artifactURL
|
||||
repName, err := randString(f)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
repositoryName := types.NamespacedName{
|
||||
Name: repName,
|
||||
Namespace: id,
|
||||
}
|
||||
fmt.Println("applyGitRepository...")
|
||||
err = applyGitRepository(repositoryName, artifactURL, "main/"+artifactChecksum, artifactChecksum)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
pgpKey, err := ioutil.ReadFile("testdata/sops/pgp.asc")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
ageKey, err := ioutil.ReadFile("testdata/sops/age.txt")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
sskName, err := randString(f)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
sopsSecretKey := types.NamespacedName{
|
||||
Name: sskName,
|
||||
Namespace: id,
|
||||
}
|
||||
|
||||
sopsSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: sopsSecretKey.Name,
|
||||
Namespace: sopsSecretKey.Namespace,
|
||||
},
|
||||
StringData: map[string]string{
|
||||
"pgp.asc": string(pgpKey),
|
||||
"age.agekey": string(ageKey),
|
||||
},
|
||||
}
|
||||
err = k8sClient.Create(context.Background(), sopsSecret)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
defer k8sClient.Delete(context.Background(), sopsSecret)
|
||||
|
||||
kkName, err := randString(f)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
kustomizationKey := types.NamespacedName{
|
||||
Name: kkName,
|
||||
Namespace: id,
|
||||
}
|
||||
kustomization := &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: kustomizationKey.Name,
|
||||
Namespace: kustomizationKey.Namespace,
|
||||
},
|
||||
Spec: kustomizev1.KustomizationSpec{
|
||||
Path: "./",
|
||||
KubeConfig: &kustomizev1.KubeConfig{
|
||||
SecretRef: meta.LocalObjectReference{
|
||||
Name: "kubeconfig",
|
||||
},
|
||||
},
|
||||
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||
Name: repositoryName.Name,
|
||||
Namespace: repositoryName.Namespace,
|
||||
Kind: sourcev1.GitRepositoryKind,
|
||||
},
|
||||
Decryption: &kustomizev1.Decryption{
|
||||
Provider: "sops",
|
||||
SecretRef: &meta.LocalObjectReference{
|
||||
Name: sopsSecretKey.Name,
|
||||
},
|
||||
},
|
||||
TargetNamespace: id,
|
||||
},
|
||||
}
|
||||
|
||||
err = k8sClient.Create(context.TODO(), kustomization)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return 0
|
||||
}
|
||||
defer k8sClient.Delete(context.TODO(), kustomization)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Allows the fuzzer to create a random lowercase string
|
||||
func randString(f *fuzz.ConsumeFuzzer) (string, error) {
|
||||
stringLength, err := f.GetInt()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
maxLength := 50
|
||||
var buffer bytes.Buffer
|
||||
for i:=0;i<stringLength%maxLength;i++ {
|
||||
getByte, err := f.GetByte()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
if getByte < 'a' || getByte > 'z' {
|
||||
return "", errors.New("Not a good char")
|
||||
}
|
||||
buffer.WriteByte(getByte)
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
// Creates a namespace.
|
||||
// Caller must delete the created namespace.
|
||||
func createNamespaceForFuzzing(name string) (*corev1.Namespace, error) {
|
||||
namespace := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||
}
|
||||
err := k8sClient.Create(context.Background(), namespace)
|
||||
if err != nil {
|
||||
return namespace, err
|
||||
}
|
||||
return namespace, nil
|
||||
}
|
||||
|
||||
// Creates a secret.
|
||||
// Caller must delete the created secret.
|
||||
func createKubeConfigSecretForFuzzing(namespace string) (*corev1.Secret, error) {
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubeconfig",
|
||||
Namespace: namespace,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"value.yaml": kubeConfig,
|
||||
},
|
||||
}
|
||||
err := k8sClient.Create(context.Background(), secret)
|
||||
if err != nil {
|
||||
return secret, err
|
||||
}
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
// taken from https://github.com/fluxcd/kustomize-controller/blob/main/controllers/suite_test.go#L222
|
||||
func createArtifact(artifactServer *testserver.ArtifactServer, fixture, path string) (string, error) {
|
||||
if f, err := os.Stat(fixture); os.IsNotExist(err) || !f.IsDir() {
|
||||
return "", fmt.Errorf("invalid fixture path: %s", fixture)
|
||||
}
|
||||
f, err := os.Create(filepath.Join(artifactServer.Root(), path))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
os.Remove(f.Name())
|
||||
}
|
||||
}()
|
||||
|
||||
h := sha1.New()
|
||||
|
||||
mw := io.MultiWriter(h, f)
|
||||
gw := gzip.NewWriter(mw)
|
||||
tw := tar.NewWriter(gw)
|
||||
|
||||
if err = filepath.Walk(fixture, func(p string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ignore anything that is not a file (directories, symlinks)
|
||||
if !fi.Mode().IsRegular() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ignore dotfiles
|
||||
if strings.HasPrefix(fi.Name(), ".") {
|
||||
return nil
|
||||
}
|
||||
|
||||
header, err := tar.FileInfoHeader(fi, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
relFilePath := p
|
||||
if filepath.IsAbs(fixture) {
|
||||
relFilePath, err = filepath.Rel(fixture, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
header.Name = relFilePath
|
||||
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Open(p)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tw, f); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tw.Close(); err != nil {
|
||||
gw.Close()
|
||||
f.Close()
|
||||
return "", err
|
||||
}
|
||||
if err := gw.Close(); err != nil {
|
||||
f.Close()
|
||||
return "", err
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := os.Chmod(f.Name(), 0644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// Taken from https://github.com/fluxcd/kustomize-controller/blob/main/controllers/suite_test.go#L171
|
||||
func applyGitRepository(objKey client.ObjectKey, artifactURL, artifactRevision, artifactChecksum string) error {
|
||||
repo := &sourcev1.GitRepository{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: sourcev1.GitRepositoryKind,
|
||||
APIVersion: sourcev1.GroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: objKey.Name,
|
||||
Namespace: objKey.Namespace,
|
||||
},
|
||||
Spec: sourcev1.GitRepositorySpec{
|
||||
URL: "https://github.com/test/repository",
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
},
|
||||
}
|
||||
|
||||
status := sourcev1.GitRepositoryStatus{
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: meta.ReadyCondition,
|
||||
Status: metav1.ConditionTrue,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: sourcev1.GitOperationSucceedReason,
|
||||
},
|
||||
},
|
||||
Artifact: &sourcev1.Artifact{
|
||||
Path: artifactURL,
|
||||
URL: artifactURL,
|
||||
Revision: artifactRevision,
|
||||
Checksum: artifactChecksum,
|
||||
LastUpdateTime: metav1.Now(),
|
||||
},
|
||||
}
|
||||
|
||||
opt := []client.PatchOption{
|
||||
client.ForceOwnership,
|
||||
client.FieldOwner("kustomize-controller"),
|
||||
}
|
||||
|
||||
if err := k8sClient.Patch(context.Background(), repo, client.Apply, opt...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo.ManagedFields = nil
|
||||
repo.Status = status
|
||||
if err := k8sClient.Status().Patch(context.Background(), repo, client.Apply, opt...); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in New Issue