Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(installer): support install platform apps #1832

Merged
merged 1 commit into from
Apr 12, 2022
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
19 changes: 18 additions & 1 deletion cmd/tke-installer/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ package config

import (
"helm.sh/helm/v3/pkg/chartutil"
"k8s.io/apimachinery/pkg/util/wait"
applicationv1 "tkestack.io/tke/api/application/v1"
"tkestack.io/tke/cmd/tke-installer/app/options"
helmaction "tkestack.io/tke/pkg/application/helm/action"
clusterprovider "tkestack.io/tke/pkg/platform/provider/cluster"
"tkestack.io/tke/pkg/util/log"
)
Expand Down Expand Up @@ -52,9 +55,10 @@ type Config struct {
EnableCustomExpansion bool
// CustomExpansionDir path to expansions. default `data/expansions`
CustomExpansionDir string
ExpansionApps []ExpansionApp
PlatformApps []PlatformApp
}
type PlatformApp struct {
type ExpansionApp struct {
Name string
Enable bool
Chart Chart
Expand All @@ -75,6 +79,19 @@ type Chart struct {
Values chartutil.Values
}

type PlatformApp struct {
HelmInstallOptions helmaction.InstallOptions
LocalChartPath string
ConditionFunc wait.ConditionFunc
Enable bool
Installed bool
// rawValues: json format or yaml format
RawValues string
RawValuesType applicationv1.RawValuesType
// values: can specify multiple or separate values: key1=val1,key2=val2
Values []string
}

// CreateConfigFromOptions creates a running configuration instance based
// on a given TKE apiserver command line or configuration file option.
func CreateConfigFromOptions(serverName string, opts *options.Options) (*Config, error) {
Expand Down
164 changes: 145 additions & 19 deletions cmd/tke-installer/app/installer/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,31 @@ package installer
import (
"context"
"fmt"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
applicationv1 "tkestack.io/tke/api/application/v1"
"tkestack.io/tke/cmd/tke-installer/app/config"
"tkestack.io/tke/cmd/tke-installer/app/installer/constants"
helmaction "tkestack.io/tke/pkg/application/helm/action"
helmutil "tkestack.io/tke/pkg/application/helm/util"
"tkestack.io/tke/pkg/util/apiclient"
)

func (t *TKE) completePlatformApps() error {
func (t *TKE) completeExpansionApps() error {

if len(t.Config.PlatformApps) == 0 {
if len(t.Config.ExpansionApps) == 0 {
return nil
}

for _, platformApp := range t.Config.PlatformApps {
if !platformApp.Enable {
for _, expansionApp := range t.Config.ExpansionApps {
if !expansionApp.Enable {
continue
}
err := t.completeChart(&platformApp.Chart)
err := t.completeChart(&expansionApp.Chart)
if err != nil {
return fmt.Errorf("bad platform app config. %v, %v", platformApp.Name, err)
return fmt.Errorf("bad platform app config. %v, %v", expansionApp.Name, err)
}
}

Expand Down Expand Up @@ -79,7 +85,7 @@ func (t *TKE) completeChart(chart *config.Chart) error {

func (t *TKE) installApplications(ctx context.Context) error {

if len(t.Config.PlatformApps) == 0 {
if len(t.Config.ExpansionApps) == 0 {
return nil
}

Expand All @@ -97,38 +103,38 @@ func (t *TKE) installApplications(ctx context.Context) error {
return fmt.Errorf("list all applications failed %v", err)
}

for _, platformApp := range t.Config.PlatformApps {
if !platformApp.Enable {
for _, expansionApp := range t.Config.ExpansionApps {
if !expansionApp.Enable {
continue
}
if t.applicationAlreadyInstalled(platformApp, apps.Items) {
t.log.Infof("application already exists. we don't override applications while installing. %v/%v", platformApp.Chart.TargetNamespace, platformApp.Chart.Name)
if t.applicationAlreadyInstalled(expansionApp, apps.Items) {
t.log.Infof("application already exists. we don't override applications while installing. %v/%v", expansionApp.Chart.TargetNamespace, expansionApp.Chart.Name)
continue
}
err := t.installApplication(ctx, platformApp)
err := t.installApplication(ctx, expansionApp)
if err != nil {
return fmt.Errorf("install application failed. %v, %v", platformApp.Name, err)
return fmt.Errorf("install application failed. %v, %v", expansionApp.Name, err)
}
t.log.Infof("finish application installation %v", platformApp.Name)
t.log.Infof("finish application installation %v", expansionApp.Name)
}

return nil
}

func (t *TKE) applicationAlreadyInstalled(platformApp config.PlatformApp, installedApps []applicationv1.App) bool {
func (t *TKE) applicationAlreadyInstalled(expansionApp config.ExpansionApp, installedApps []applicationv1.App) bool {

for _, installedApp := range installedApps {
// if there's an existed application with the same namespace+name, we consider it as already exists
if platformApp.Name == installedApp.Spec.Name && platformApp.Chart.TargetNamespace == installedApp.Namespace {
if expansionApp.Name == installedApp.Spec.Name && expansionApp.Chart.TargetNamespace == installedApp.Namespace {
return true
}
}
return false
}

func (t *TKE) installApplication(ctx context.Context, platformApp config.PlatformApp) error {
func (t *TKE) installApplication(ctx context.Context, expansionApp config.ExpansionApp) error {

chart := platformApp.Chart
chart := expansionApp.Chart

rawValues, err := chart.Values.YAML()
if err != nil {
Expand All @@ -143,7 +149,7 @@ func (t *TKE) installApplication(ctx context.Context, platformApp config.Platfor
Spec: applicationv1.AppSpec{
Type: constants.DefaultApplicationInstallDriverType,
TenantID: chart.TenantID,
Name: platformApp.Name,
Name: expansionApp.Name,
TargetCluster: chart.TargetCluster,
Chart: applicationv1.Chart{
TenantID: chart.TenantID,
Expand All @@ -163,3 +169,123 @@ func (t *TKE) installApplication(ctx context.Context, platformApp config.Platfor
}
return nil
}
func (t *TKE) initPlatformApps(ctx context.Context) error {
defaultPlatformApps := []config.PlatformApp{}
if t.Para.Config.Auth.TKEAuth != nil {
authAPIOptions, err := t.getTKEAuthAPIOptions(ctx)
if err != nil {
return fmt.Errorf("get tke-auth-api options failed: %v", err)
}
tkeAuth := config.PlatformApp{
HelmInstallOptions: helmaction.InstallOptions{
Namespace: t.namespace,
ReleaseName: "tke-auth",
Values: map[string]interface{}{
"api": authAPIOptions,
"controller": t.getTKEAuthControllerOptions(ctx),
},
DependencyUpdate: false,
ChartPathOptions: helmaction.ChartPathOptions{},
},
LocalChartPath: constants.ChartDirName + "tke-auth/",
Enable: true,
ConditionFunc: func() (bool, error) {
apiOk, err := apiclient.CheckDeployment(ctx, t.globalClient, t.namespace, "tke-auth-api")
if err != nil {
return false, nil
}
controllerOk, err := apiclient.CheckDeployment(ctx, t.globalClient, t.namespace, "tke-auth-controller")
if err != nil {
return false, nil
}
return apiOk && controllerOk, nil
},
}
defaultPlatformApps = append(defaultPlatformApps, tkeAuth)
}
platformAPIOptions, err := t.getTKEPlatformAPIOptions(ctx)
if err != nil {
return fmt.Errorf("get tke-platform-api options failed: %v", err)
}
tkePlatform := config.PlatformApp{
HelmInstallOptions: helmaction.InstallOptions{
Namespace: t.namespace,
ReleaseName: "tke-platform",
Values: map[string]interface{}{
"api": platformAPIOptions,
"controller": t.getTKEPlatformControllerOptions(ctx),
},
DependencyUpdate: false,
ChartPathOptions: helmaction.ChartPathOptions{},
},
LocalChartPath: constants.ChartDirName + "tke-platform/",
Enable: true,
ConditionFunc: func() (bool, error) {
apiOk, err := apiclient.CheckDeployment(ctx, t.globalClient, t.namespace, "tke-platform-api")
if err != nil {
return false, nil
}
controllerOk, err := apiclient.CheckDeployment(ctx, t.globalClient, t.namespace, "tke-platform-controller")
if err != nil {
return false, nil
}
return apiOk && controllerOk, nil
},
}
defaultPlatformApps = append(defaultPlatformApps, tkePlatform)
t.Config.PlatformApps = append(defaultPlatformApps, t.Config.PlatformApps...)
return nil
}

func (t *TKE) installPlatformApps(ctx context.Context) error {

if len(t.Config.PlatformApps) == 0 {
return nil
}
for i, platformApp := range t.Config.PlatformApps {
if !platformApp.Enable || platformApp.Installed {
continue
}
t.log.Infof("Start instal platform app %s in %s namespace", platformApp.HelmInstallOptions.ReleaseName, platformApp.HelmInstallOptions.Namespace)
err := t.installPlatformApp(ctx, platformApp)
if err != nil {
t.log.Errorf("Install %s failed", platformApp.HelmInstallOptions.ReleaseName)
}
t.Config.PlatformApps[i].Installed = true
t.log.Infof("End instal platform app %s in %s namespace", platformApp.HelmInstallOptions.ReleaseName, platformApp.HelmInstallOptions.Namespace)
}

return nil
}

func (t *TKE) installPlatformApp(ctx context.Context, platformApp config.PlatformApp) error {
platformApp.HelmInstallOptions.Timeout = 10 * time.Minute
if len(platformApp.RawValues) != 0 || len(platformApp.Values) != 0 {
values, err := helmutil.MergeValues(platformApp.Values, platformApp.RawValues, string(platformApp.RawValuesType))
if err != nil {
return err
}
platformApp.HelmInstallOptions.Values = values
}
if len(platformApp.LocalChartPath) != 0 {
if _, err := t.helmClient.InstallWithLocal(&platformApp.HelmInstallOptions, platformApp.LocalChartPath); err != nil {
uninstallOptions := helmaction.UninstallOptions{
Timeout: 10 * time.Minute,
ReleaseName: platformApp.HelmInstallOptions.ReleaseName,
Namespace: platformApp.HelmInstallOptions.Namespace,
}
reponse, err := t.helmClient.Uninstall(&uninstallOptions)
if err != nil {
return fmt.Errorf("clean %s failed %v", reponse.Release.Name, err)
}
return err
}
}
if platformApp.ConditionFunc != nil {
err := wait.PollImmediate(5*time.Second, 10*time.Minute, platformApp.ConditionFunc)
if err != nil {
return err
}
}
return nil
}
13 changes: 7 additions & 6 deletions cmd/tke-installer/app/installer/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package installer
import (
"context"
"fmt"
"helm.sh/helm/v3/pkg/chartutil"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"os"
"testing"

"helm.sh/helm/v3/pkg/chartutil"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
registryv1 "tkestack.io/tke/api/registry/v1"
"tkestack.io/tke/cmd/tke-installer/app/config"
helmaction "tkestack.io/tke/pkg/application/helm/action"
Expand Down Expand Up @@ -61,21 +62,21 @@ func TestTKE_installApplication(t *testing.T) {
TargetNamespace: "default",
Values: chartutil.Values{},
}
platformApp := config.PlatformApp{
expansionApp := config.ExpansionApp{
Name: name,
Enable: true,
Chart: *chart,
}

if tke.applicationAlreadyInstalled(platformApp, apps.Items) {
if tke.applicationAlreadyInstalled(expansionApp, apps.Items) {
t.Log("already installed")
} else {
err = tke.installApplication(context.Background(), platformApp)
err = tke.installApplication(context.Background(), expansionApp)
if err != nil {
t.Fatal(err)
}
}
b, err := json.MarshalIndent([]config.PlatformApp{
b, err := json.MarshalIndent([]config.ExpansionApp{
{
Name: name,
Enable: true,
Expand Down
Loading