Skip to content

Commit

Permalink
feat(app): impl the app resources creation logic in controller (#351)
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow authored Sep 28, 2022
1 parent 821e875 commit 501a62a
Show file tree
Hide file tree
Showing 16 changed files with 199 additions and 49 deletions.
6 changes: 3 additions & 3 deletions controllers/application/api/v1/application_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ const (
InstanceCreated string = "InstanceCreated"
InstanceDeleted string = "InstanceDeleted"

DatabaseDeleted string = "DatabaseDeleted"
StorageDeleted string = "ObjectStorageDeleted"
GatewayDeleted string = "GatewayDeleted"
DatabaseDeleted string = "DatabaseDeleted"
ObjectStorageDeleted string = "ObjectStorageDeleted"
GatewayDeleted string = "GatewayDeleted"
)

// ApplicationSpec defines the desired state of Application
Expand Down
16 changes: 13 additions & 3 deletions controllers/application/controllers/application_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
appv1 "github.com/labring/laf/controllers/application/api/v1"
"github.com/labring/laf/controllers/application/resourcer"
runtimev1 "github.com/labring/laf/controllers/runtime/api/v1"
"github.com/labring/laf/pkg/common"
"github.com/labring/laf/pkg/util"
Expand Down Expand Up @@ -205,7 +206,10 @@ func (r *ApplicationReconciler) initialize(ctx context.Context, app *appv1.Appli

// create the database
if util.ConditionIsNotTrue(app.Status.Conditions, appv1.DatabaseCreated) {
// TODO create database
// create app database
if err := resourcer.CreateDatabase(ctx, r.Client, r.Scheme, app); err != nil {
return ctrl.Result{}, err
}

// set condition DatabaseCreated to true
condition := metav1.Condition{
Expand All @@ -227,7 +231,10 @@ func (r *ApplicationReconciler) initialize(ctx context.Context, app *appv1.Appli

// create the oss user
if util.ConditionIsNotTrue(app.Status.Conditions, appv1.ObjectStorageCreated) {
// TODO create oss user
// create oss user
if err := resourcer.CreateObjectStorageUser(ctx, r.Client, r.Scheme, app); err != nil {
return ctrl.Result{}, err
}

// set condition ObjectStorageCreated to true
condition := metav1.Condition{
Expand All @@ -249,7 +256,10 @@ func (r *ApplicationReconciler) initialize(ctx context.Context, app *appv1.Appli

// create the gateway
if util.ConditionIsNotTrue(app.Status.Conditions, appv1.GatewayCreated) {
// TODO create the gateway
// create the gateway
if err := resourcer.CreateGateway(ctx, r.Client, r.Scheme, app); err != nil {
return ctrl.Result{}, err
}

// set condition GatewayCreated to true
condition := metav1.Condition{
Expand Down
3 changes: 0 additions & 3 deletions controllers/application/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package main

import (
"flag"
"github.com/labring/laf/controllers/application/resourcer"
databasev1 "github.com/labring/laf/controllers/database/api/v1"
gatewayv1 "github.com/labring/laf/controllers/gateway/api/v1"
ossv1 "github.com/labring/laf/controllers/oss/api/v1"
Expand Down Expand Up @@ -99,8 +98,6 @@ func main() {
os.Exit(1)
}

resourcer.SetClient(mgr.GetClient())

if err = (&controllers.ApplicationReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Expand Down
20 changes: 0 additions & 20 deletions controllers/application/resourcer/client.go

This file was deleted.

35 changes: 32 additions & 3 deletions controllers/application/resourcer/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
appv1 "github.com/labring/laf/controllers/application/api/v1"
databasev1 "github.com/labring/laf/controllers/database/api/v1"
"github.com/labring/laf/pkg/common"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func CreateAppDatabase(ctx context.Context, app *appv1.Application) error {
//client := GetClient()
func CreateDatabase(ctx context.Context, c client.Client, schema *runtime.Scheme, app *appv1.Application) error {

// Create a new database
var db databasev1.Database
Expand All @@ -20,7 +22,34 @@ func CreateAppDatabase(ctx context.Context, app *appv1.Application) error {

db.Spec.Provider = "mongodb"
db.Spec.Region = app.Spec.Region
db.Spec.Username = app.Spec.AppId
db.Spec.Password = common.GenerateAlphaNumericPassword(64)
db.Spec.Capacity.Storage = app.Status.BundleSpec.DatabaseCapacity

return nil
if err := controllerutil.SetControllerReference(app, &db, schema); err != nil {
return err
}

err := c.Create(ctx, &db)
return err
}

func GetDatabase(ctx context.Context, c client.Client, app *appv1.Application) (*databasev1.Database, error) {

// Get the database
var db databasev1.Database
err := c.Get(ctx, client.ObjectKey{Namespace: app.Namespace, Name: "mongodb"}, &db)
return &db, err
}

func DeleteDatabase(ctx context.Context, c client.Client, app *appv1.Application) error {

// Delete the database
db, err := GetDatabase(ctx, c, app)
if err != nil {
return err
}

err = c.Delete(ctx, db)
return err
}
38 changes: 38 additions & 0 deletions controllers/application/resourcer/gateway.go
Original file line number Diff line number Diff line change
@@ -1 +1,39 @@
package resourcer

import (
"context"
appv1 "github.com/labring/laf/controllers/application/api/v1"
gatewayv1 "github.com/labring/laf/controllers/gateway/api/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func CreateGateway(ctx context.Context, c client.Client, schema *runtime.Scheme, app *appv1.Application) error {

// Create a new gateway
var gw gatewayv1.Gateway
gw.Namespace = app.Namespace
gw.Name = "gateway"
gw.Labels = map[string]string{
"laf.dev/appid": app.Spec.AppId,
}

gw.Spec.AppId = app.Spec.AppId

// TODO? may the gateway add region spec field
// gw.Spec.Region = app.Spec.AppId

if err := controllerutil.SetControllerReference(app, &gw, schema); err != nil {
return err
}
err := c.Create(ctx, &gw)
return err
}

func GetGateway(ctx context.Context, c client.Client, app *appv1.Application) (*gatewayv1.Gateway, error) {
// Get the gateway
var gw gatewayv1.Gateway
err := c.Get(ctx, client.ObjectKey{Namespace: app.Namespace, Name: "gateway"}, &gw)
return &gw, err
}
40 changes: 40 additions & 0 deletions controllers/application/resourcer/oss.go
Original file line number Diff line number Diff line change
@@ -1 +1,41 @@
package resourcer

import (
"context"
appv1 "github.com/labring/laf/controllers/application/api/v1"
ossv1 "github.com/labring/laf/controllers/oss/api/v1"
"github.com/labring/laf/pkg/common"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func CreateObjectStorageUser(ctx context.Context, c client.Client, schema *runtime.Scheme, app *appv1.Application) error {

// Create a new oss user
var oss ossv1.User
oss.Namespace = app.Namespace
oss.Name = "oss"
oss.Labels = map[string]string{
"laf.dev/appid": app.Spec.AppId,
}

oss.Spec.Provider = "minio"
oss.Spec.Region = app.Spec.Region
oss.Spec.AppId = app.Spec.AppId
oss.Spec.Password = common.GenerateAlphaNumericPassword(64)
oss.Spec.Capacity.Storage = app.Status.BundleSpec.StorageCapacity

if err := controllerutil.SetControllerReference(app, &oss, schema); err != nil {
return err
}
err := c.Create(ctx, &oss)
return err
}

func GetObjectStorageUser(ctx context.Context, c client.Client, app *appv1.Application) (*ossv1.User, error) {
// Get the oss user
var oss ossv1.User
err := c.Get(ctx, client.ObjectKey{Namespace: app.Namespace, Name: "oss"}, &oss)
return &oss, err
}
72 changes: 66 additions & 6 deletions controllers/application/tests/e2e/app_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package e2e
import (
appv1 "github.com/labring/laf/controllers/application/api/v1"
"github.com/labring/laf/controllers/application/tests/api"
api2 "github.com/labring/laf/controllers/database/tests/api"
api3 "github.com/labring/laf/controllers/oss/tests/api"
runtimeapi "github.com/labring/laf/controllers/runtime/tests/api"
"github.com/labring/laf/pkg/common"
baseapi "github.com/labring/laf/tests/api"
Expand Down Expand Up @@ -43,11 +45,6 @@ func TestCreateApp(t *testing.T) {
t.Fatalf("ERROR: get app failed: %v", err)
}

t.Log("verify the app")
if app.Name != name {
t.Fatalf("ERROR: app name is not correct, expect %s, got %s", name, app.Name)
}

t.Log("verify the runtime")
if app.Status.RuntimeName != runtimeName {
t.Errorf("ERROR: runtime name expect %s got %s", runtimeName, app.Status.RuntimeName)
Expand All @@ -57,7 +54,7 @@ func TestCreateApp(t *testing.T) {
t.Errorf("ERROR: invalid runtime type got %s", app.Status.RuntimeSpec.Type)
}

t.Log("verify")
t.Log("verify the phase is running")
if app.Status.Phase != appv1.ApplicationStateRunning {
t.Errorf("ERROR: invalid app phase got %s", app.Status.Phase)
}
Expand All @@ -71,6 +68,69 @@ func TestCreateApp(t *testing.T) {
t.Errorf("ERROR: bundle display name cannot be empty")
}

t.Log("verify the database created")
database, err := api2.GetDatabase(namespace, "mongodb")
if err != nil {
t.Errorf("ERROR: get database failed: %v", err)
}

if database.Spec.Username != appid {
t.Errorf("ERROR: database username expect %s got %s", appid, database.Spec.Username)
}

if database.Spec.Password == "" {
t.Errorf("ERROR: database password cannot be empty")
}

if database.Spec.Capacity.Storage != app.Status.BundleSpec.DatabaseCapacity {
t.Errorf("ERROR: database capacity expect %s got %s", app.Status.BundleSpec.DatabaseCapacity.String(), database.Spec.Capacity.Storage.String())
}

if database.Labels["laf.dev/appid"] != appid {
t.Errorf("ERROR: database appid expect %s got %s", appid, database.Labels["laf.dev/appid"])
}

if database.OwnerReferences[0].Name != name {
t.Errorf("ERROR: db owner reference expect %s got %s", name, database.OwnerReferences[0].Name)
}

t.Log("verify the oss user")
ossUser, err := api3.GetOssUser(namespace, "oss")
if err != nil {
t.Errorf("ERROR: get oss user failed: %v", err)
}

if ossUser.Spec.AppId != appid {
t.Errorf("ERROR: oss user appid expect %s got %s", appid, ossUser.Spec.AppId)
}

if ossUser.Spec.Region != region {
t.Errorf("ERROR: oss user region expect %s got %s", region, ossUser.Spec.Region)
}

if ossUser.Spec.Provider != "minio" {
t.Errorf("ERROR: oss user provider expect minio got %s", ossUser.Spec.Provider)
}

if ossUser.Spec.Password == "" {
t.Errorf("ERROR: oss user password cannot be empty")
}

if ossUser.Spec.Capacity.Storage != app.Status.BundleSpec.StorageCapacity {
t.Errorf("ERROR: oss user capacity expect %s got %s", app.Status.BundleSpec.StorageCapacity.String(), ossUser.Spec.Capacity.Storage.String())
}

if ossUser.Labels["laf.dev/appid"] != appid {
t.Errorf("ERROR: oss user appid expect %s got %s", appid, ossUser.Labels["laf.dev/appid"])
}

if ossUser.OwnerReferences[0].Name != name {
t.Errorf("ERROR: oss user owner reference expect %s got %s", name, ossUser.OwnerReferences[0].Name)
}

// TODO? verify the gateway while gateway testing api supported
t.Log("TODO: verify the gateway")

})

t.Cleanup(func() {
Expand Down
3 changes: 1 addition & 2 deletions controllers/database/api/v1/database_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@ type DatabaseSpec struct {
//+kubebuilder:validation:Required
//+kubebuilder:validation:MinLength=6
//+kubebuilder:validation:MaxLength=32

Username string `json:"username"`

// Password of the database.
//+kubebuilder:validation:Required
//+kubebuilder:validation:MinLength=16
//+kubebuilder:validation:MaxLength=32
//+kubebuilder:validation:MaxLength=64
Password string `json:"password"`
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ spec:
type: object
password:
description: Password of the database.
maxLength: 32
maxLength: 64
minLength: 16
type: string
provider:
Expand All @@ -59,6 +59,7 @@ spec:
description: Region of the database.
type: string
username:
description: Username of the database.
maxLength: 32
minLength: 6
type: string
Expand Down
4 changes: 0 additions & 4 deletions controllers/gateway/api/v1/gateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ type GatewaySpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Foo is an example field of Gateway. Edit gateway_types.go to remove/update

// AppId是应用id,字母数字组成,长度5至16位,必须存在
// +kubebuilder:validation:Pattern="^[a-zA-Z0-9]{5,16}$"
// +kubebuilder:validation:Required
AppId string `json:"appid"`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ spec:
description: GatewaySpec defines the desired state of Gateway
properties:
appid:
description: AppId是应用id,字母数字组成,长度5至16位,必须存在
pattern: ^[a-zA-Z0-9]{5,16}$
type: string
buckets:
description: Buckets是存储桶, 是一个数组,可选存在
Expand Down
2 changes: 1 addition & 1 deletion controllers/oss/api/v1/user_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type UserSpec struct {

// Password is the secret name of the user, which is used to authenticate the user.
//+kubebuilder:validation:MinLength=3
//+kubebuilder:validation:MaxLength=32
//+kubebuilder:validation:MaxLength=64
//+kubebuilder:validation:Required
Password string `json:"password"`

Expand Down
2 changes: 1 addition & 1 deletion controllers/oss/config/crd/bases/oss.laf.dev_users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ spec:
password:
description: Password is the secret name of the user, which is used
to authenticate the user.
maxLength: 32
maxLength: 64
minLength: 3
type: string
provider:
Expand Down
Loading

0 comments on commit 501a62a

Please sign in to comment.