Skip to content

Commit

Permalink
add support for embedded apps
Browse files Browse the repository at this point in the history
  • Loading branch information
nabuskey committed Nov 16, 2023
1 parent d1feb81 commit 85fead1
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 20 deletions.
12 changes: 9 additions & 3 deletions api/v1alpha1/gitrepository_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ type GitRepositorySpec struct {
}

type GitRepositorySource struct {
// +kubebuilder:validation:Enum:=argocd;gitea;nginx
// +kubebuilder:validation:Optional
EmbeddedAppName string `json:"embeddedAppName"`
// Path is the absolute path to directory that contains Kustomize structure or raw manifests.
// +kubebuilder:validation:Required
// This is required when Type is set to local.
// +kubebuilder:validation:Optional
Path string `json:"path"`
// Type is the path type. Supports local type only. May support remote in the future.
// +kubebuilder:validation:Enum:=local
// Type is the source type.
// +kubebuilder:validation:Enum:=local;embedded
// +kubebuilder:default:=local
Type string `json:"type"`
}
Expand All @@ -40,6 +44,8 @@ type GitRepositoryStatus struct {
// Path is the path within the repository that contains the files.
// +kubebuilder:validation:Optional
Path string `json:"path"`

Synced bool `json:"synced"`
}

// +kubebuilder:object:root=true
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ var (
func init() {
SchemeBuilder.Register(&Localbuild{}, &LocalbuildList{})
SchemeBuilder.Register(&GitServer{}, &GitServerList{})
SchemeBuilder.Register(&GitRepository{}, &GitRepositoryList{})
}
80 changes: 67 additions & 13 deletions pkg/controllers/gitrepository/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import (
"code.gitea.io/sdk/gitea"
"github.com/cnoe-io/idpbuilder/api/v1alpha1"
"github.com/cnoe-io/idpbuilder/globals"
"github.com/cnoe-io/idpbuilder/pkg/controllers/localbuild"
"github.com/cnoe-io/idpbuilder/pkg/util"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
Expand All @@ -28,21 +30,26 @@ const (
// DefaultGiteaUsername and DefaultGiteaPassword taken from gitea helm chart. https://gitea.com/gitea/helm-chart#gitea
DefaultGiteaUsername = "gitea_admin"
DefaultGiteaPassword = "r8sA8CPHD9!bt6d"
requeueTime = time.Second * 60
requeueTime = time.Second * 30
gitCommitAuthorName = "git-reconciler"
gitCommitAuthorEmail = "[email protected]"
)

type ClientFN func(url string, options ...gitea.ClientOption) (GiteaClient, error)

func NewGiteaClient(url string, options ...gitea.ClientOption) (GiteaClient, error) {
return gitea.NewClient(url, options...)
}

type RepositoryReconciler struct {
client.Client
Scheme *runtime.Scheme
GiteaClientFN ClientFN
Recorder record.EventRecorder
Scheme *runtime.Scheme
}

func getRepositoryName(repo v1alpha1.GitRepository) string {
return fmt.Sprintf("%s-%s", repo.Namespace, repo.Name)
return fmt.Sprintf("%s-%s", repo.Name, repo.Namespace)
}

func getOrganizationName(repo v1alpha1.GitRepository) string {
Expand Down Expand Up @@ -73,13 +80,21 @@ func (r *RepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, client.IgnoreNotFound(err)
}

logger.Info("reconciling GitRepository", "name", req.Name, "namespace", req.Namespace)
if !filepath.IsAbs(gitRepo.Spec.Source.Path) {
if !r.shouldProcess(gitRepo) {
return ctrl.Result{Requeue: false}, nil
}

logger.Info("reconciling GitRepository", "name", req.Name, "namespace", req.Namespace)
defer r.postProcessReconcile(ctx, req, &gitRepo)
return r.reconcileGitRepo(ctx, &gitRepo)

result, err := r.reconcileGitRepo(ctx, &gitRepo)
if err != nil {
r.Recorder.Event(&gitRepo, "Warning", "reconcile error", err.Error())
} else {
r.Recorder.Event(&gitRepo, "Normal", "reconcile success", "Successfully reconciled")
}

return result, err
}

func (r *RepositoryReconciler) postProcessReconcile(ctx context.Context, req ctrl.Request, repo *v1alpha1.GitRepository) {
Expand Down Expand Up @@ -116,8 +131,8 @@ func (r *RepositoryReconciler) reconcileGitRepo(ctx context.Context, repo *v1alp
if err != nil {
return ctrl.Result{Requeue: true, RequeueAfter: requeueTime}, fmt.Errorf("failed to reconcile repo content %w", err)
}

return ctrl.Result{Requeue: false}, nil
repo.Status.Synced = true
return ctrl.Result{Requeue: true, RequeueAfter: requeueTime}, nil
}

func (r *RepositoryReconciler) reconcileRepoContent(ctx context.Context, repo *v1alpha1.GitRepository, giteaRepo *gitea.Repository) error {
Expand All @@ -132,12 +147,12 @@ func (r *RepositoryReconciler) reconcileRepoContent(ctx context.Context, repo *v
NoCheckout: true,
})
if err != nil {
return fmt.Errorf("cloing repo: %w", err)
return fmt.Errorf("cloning repo: %w", err)
}

err = util.CopyDirectory(repo.Spec.Source.Path, tempDir)
err = writeRepoContents(repo, tempDir)
if err != nil {
return fmt.Errorf("copying files: %w", err)
return err
}

tree, err := clonedRepo.Worktree()
Expand Down Expand Up @@ -219,6 +234,45 @@ func (r *RepositoryReconciler) SetupWithManager(mgr ctrl.Manager, notifyChan cha
Complete(r)
}

func NewGiteaClient(url string, options ...gitea.ClientOption) (GiteaClient, error) {
return gitea.NewClient(url, options...)
func (r *RepositoryReconciler) shouldProcess(repo v1alpha1.GitRepository) bool {
if repo.Spec.Source.Type == "local" && !filepath.IsAbs(repo.Spec.Source.Path) {
return false
}
// embedded fs does not change
if repo.Spec.Source.Type == "embedded" && repo.Status.Synced {
return false
}
return true
}

func getEmbedded(name string) ([][]byte, error) {
switch name {
case "argocd":
return localbuild.GetRawInstallResources()
default:
return nil, fmt.Errorf("unsupported embedded app name %s", name)
}
}

func writeRepoContents(repo *v1alpha1.GitRepository, tempDir string) error {
if repo.Spec.Source.EmbeddedAppName != "" {
resources, err := getEmbedded(repo.Spec.Source.EmbeddedAppName)
if err != nil {
return fmt.Errorf("getting embedded resource; %w", err)
}
for i := range resources {
filePath := filepath.Join(tempDir, fmt.Sprintf("resource%d.yaml", i))
err = os.WriteFile(filePath, resources[i], 0644)
if err != nil {
return fmt.Errorf("writing embedded resource; %w", err)
}
}
return nil
}

err := util.CopyDirectory(repo.Spec.Source.Path, tempDir)
if err != nil {
return fmt.Errorf("copying files: %w", err)
}
return nil
}
2 changes: 2 additions & 0 deletions pkg/controllers/gitrepository/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func TestGitRepositoryReconcile(t *testing.T) {
resource: v1alpha1.GitRepositoryStatus{
ExternalGitRepositoryUrl: dir,
LatestCommit: v1alpha1.Commit{Hash: hash},
Synced: true,
},
},
},
Expand All @@ -293,6 +294,7 @@ func TestGitRepositoryReconcile(t *testing.T) {
expect: expect{
resource: v1alpha1.GitRepositoryStatus{
ExternalGitRepositoryUrl: dir,
Synced: true,
},
},
},
Expand Down
18 changes: 14 additions & 4 deletions pkg/controllers/resources/idpbuilder.cnoe.io_gitrepositories.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,25 @@ spec:
type: string
source:
properties:
embeddedAppName:
enum:
- argocd
- gitea
- nginx
type: string
path:
description: Path is the absolute path to directory that contains
Kustomize structure or raw manifests.
Kustomize structure or raw manifests. This is required when
Type is set to local.
type: string
type:
default: local
description: Type is the path type. Supports local type only.
May support remote in the future.
description: Type is the source type.
enum:
- local
- embedded
type: string
required:
- path
- type
type: object
required:
Expand All @@ -76,6 +82,10 @@ spec:
description: Path is the path within the repository that contains
the files.
type: string
synced:
type: boolean
required:
- synced
type: object
type: object
served: true
Expand Down
10 changes: 10 additions & 0 deletions testEmbed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: idpbuilder.cnoe.io/v1alpha1
kind: GitRepository
metadata:
name: argocd
namespace: default
spec:
giteaURL: "http://localhost:3000"
source:
embeddedAppName: "argocd"
type: embedded
9 changes: 9 additions & 0 deletions testrepo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: idpbuilder.cnoe.io/v1alpha1
kind: GitRepository
metadata:
name: test
namespace: default
spec:
giteaURL: "http://localhost:3000"
source:
path: "/tmp/b/"

0 comments on commit 85fead1

Please sign in to comment.