Compare commits

..

No commits in common. "4bce096e1fdd09c1bea9123161752bf7f57fece0" and "53a614bd7eb3ef1d874d3570443230df7585b9d1" have entirely different histories.

58 changed files with 765 additions and 2219 deletions

View File

@ -70,10 +70,6 @@ clean:
@rm -rf workspace_* @rm -rf workspace_*
.PHONY: test .PHONY: test
test_%:
go test oc-deploy/$(subst test_,,$@) -coverprofile=.coverage.out -v
@go tool cover -html=.coverage.out -o .coverage.html
test: test:
@go test ./... -coverprofile=.coverage.out -v @go test ./... -coverprofile=.coverage.out -v
go tool cover -html=.coverage.out -o .coverage.html go tool cover -html=.coverage.out -o .coverage.html

View File

@ -16,70 +16,58 @@ var (
modules []string modules []string
) )
func cobraInstallCmd() *cobra.Command {
return &cobra.Command{
Use: "install",
Short: "install",
Long: `deploy Charts`,
Args: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return InstallCmd(context, version, modules)
},
Example: "oc-deploy install --version 1.0 --context ex1",
}
}
func cobraUninstallCmd() *cobra.Command{
return &cobra.Command{
Use: "uninstall",
Short: "undeploy",
Long: `Undeploy`,
Args: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return UninstallCmd(context)
},
Example: "oc-deploy uninstall --context ex1",
}
}
func cobraGenerateCmd() *cobra.Command{
return &cobra.Command{
Use: "generate",
Short: "generate",
Long: "Value",
Args: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return GenerateCmd(context, version)
},
Example: "oc-deploy generate --version 1.0 --context ex1",
}
}
func Execute() { func Execute() {
log.Log().Debug().Msg("Execute") log.Log().Debug().Msg("Execute")
var rootCmd = &cobra.Command{Use: "oc-deploy"} var rootCmd = &cobra.Command{Use: "oc-deploy"}
var cmdInstall = cobraInstallCmd() var cmdInstall = &cobra.Command{
var cmdUninstall = cobraUninstallCmd() Use: "install",
var cmdGenerate = cobraGenerateCmd() Short: "deploy",
Long: `deploy Charts`,
Args: cobra.MaximumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
InstallCmd(context, version, modules)
},
Example: "oc-deploy install --version 1.0 --context ex1",
}
cmdInstall.Flags().StringVarP(&context, "context", "c", "opencloud", "Nom du context") var cmdUninstall = &cobra.Command{
cmdInstall.Flags().StringVarP(&version, "version", "v", "latest", "Version") Use: "uninstall",
cmdInstall.Flags().StringArrayVarP(&modules, "modules", "m", []string{}, "modules, ...") Short: "undeploy",
Long: `Undeploy`,
Args: cobra.MaximumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
UninstallCmd(context)
},
Example: "oc-deploy uninstall --context ex1",
}
cmdUninstall.Flags().StringVarP(&context, "context", "c", "opencloud", "Nom du context") var cmdGenerate = &cobra.Command{
Use: "generate",
Short: "generate",
Long: "Value",
Args: cobra.MaximumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
GenerateCmd(context, version)
},
Example: "oc-deploy generate --version 1.0 --context ex1",
}
cmdGenerate.Flags().StringVarP(&context, "context", "c", "opencloud", "Nom du context") cmdInstall.Flags().StringVarP(&context, "context", "c", "opencloud", "Nom du context")
cmdGenerate.Flags().StringVarP(&version, "version", "v", "latest", "Version") cmdInstall.Flags().StringVarP(&version, "version", "v", "latest", "Version")
cmdInstall.Flags().StringArrayVarP(&modules, "modules", "m", []string{}, "modules, ...")
rootCmd.AddCommand(cmdInstall) cmdUninstall.Flags().StringVarP(&context, "context", "c", "opencloud", "Nom du context")
rootCmd.AddCommand(cmdUninstall)
rootCmd.AddCommand(cmdGenerate)
cobra.CheckErr(rootCmd.Execute()) cmdGenerate.Flags().StringVarP(&context, "context", "c", "opencloud", "Nom du context")
cmdGenerate.Flags().StringVarP(&version, "version", "v", "latest", "Version")
rootCmd.AddCommand(cmdInstall)
rootCmd.AddCommand(cmdUninstall)
rootCmd.AddCommand(cmdGenerate)
cobra.CheckErr(rootCmd.Execute())
} }

View File

@ -1,9 +0,0 @@
package cmd
import (
"testing"
)
func TestExecute(t *testing.T) {
Execute()
}

View File

@ -8,7 +8,7 @@ import (
"oc-deploy/generate" "oc-deploy/generate"
) )
func GenerateCmd(project string, version string) error { func GenerateCmd(project string, version string) {
log.Log().Info().Msg("Generate >> ") log.Log().Info().Msg("Generate >> ")
version, err := versionOc.GetFromFile(version) version, err := versionOc.GetFromFile(version)
@ -24,5 +24,4 @@ func GenerateCmd(project string, version string) error {
} }
log.Log().Info().Msg(" >> Value : " + fic) log.Log().Info().Msg(" >> Value : " + fic)
return err
} }

View File

@ -7,7 +7,7 @@ import (
"oc-deploy/install" "oc-deploy/install"
) )
func InstallCmd(context string, version string, modules []string) error { func InstallCmd(context string, version string, modules []string) {
log.Log().Info().Msg("Install >> ") log.Log().Info().Msg("Install >> ")
log.Log().Info().Msg(" << Contexte : " + context) log.Log().Info().Msg(" << Contexte : " + context)
@ -47,5 +47,4 @@ func InstallCmd(context string, version string, modules []string) error {
log.Log().Fatal().Msg(" >> " + err.Error()) log.Log().Fatal().Msg(" >> " + err.Error())
} }
return err
} }

View File

@ -1,41 +0,0 @@
package cmd
import (
"bytes"
"github.com/spf13/cobra"
"testing"
"github.com/stretchr/testify/assert"
)
func TestInstallCommand(t *testing.T) {
cmd := cobraInstallCmd()
inMock := false
cmd.RunE = func(cmd *cobra.Command, args []string) error {
inMock = true
return nil
}
cmd.Execute()
assert.Truef(t, inMock, "TestInstallCommand")
}
func TestInstallCommandErr(t *testing.T) {
cmd := cobraUninstallCmd()
inMock := false
cmd.RunE = func(cmd *cobra.Command, args []string) error {
inMock = true
return nil
}
cmd.SetArgs([]string{"bad"})
b := bytes.NewBufferString("")
cmd.SetOut(b)
err := cmd.Execute()
assert.Falsef(t, inMock, "TestInstallCommand args")
assert.NotNilf(t, err, "TestInstallCommand args")
}

View File

@ -11,8 +11,8 @@ import (
"oc-deploy/install" "oc-deploy/install"
) )
func UninstallCmd(context string) error { func UninstallCmd(context string) {
log.Log().Info().Msg("Uninstall >> ") log.Log().Info().Msg("Unnstall >> ")
log.Log().Info().Msg(" << Contexte : " + context) log.Log().Info().Msg(" << Contexte : " + context)
@ -40,6 +40,4 @@ func UninstallCmd(context string) error {
if err != nil { if err != nil {
log.Log().Fatal().Msg(" >> " + err.Error()) log.Log().Fatal().Msg(" >> " + err.Error())
} }
return err
} }

View File

@ -1,41 +0,0 @@
package cmd
import (
"bytes"
"github.com/spf13/cobra"
"testing"
"github.com/stretchr/testify/assert"
)
func TestUninstallCommand(t *testing.T) {
cmd := cobraUninstallCmd()
inMock := false
cmd.RunE = func(cmd *cobra.Command, args []string) error {
inMock = true
return nil
}
cmd.Execute()
assert.Truef(t, inMock, "TestUninstallCommand")
}
func TestUninstallCommandErr(t *testing.T) {
cmd := cobraUninstallCmd()
inMock := false
cmd.RunE = func(cmd *cobra.Command, args []string) error {
inMock = true
return nil
}
cmd.SetArgs([]string{"bad"})
b := bytes.NewBufferString("")
cmd.SetOut(b)
err := cmd.Execute()
assert.Falsef(t, inMock, "TestUninstallCommand args")
assert.NotNilf(t, err, "TestUninstallCommand args")
}

View File

@ -1,162 +1,159 @@
package helm package helm
import ( import (
"fmt" "fmt"
"strconv" "strconv"
"os" "os"
"strings" "os/exec"
"errors" "strings"
"path/filepath" "errors"
"encoding/json" "path/filepath"
log "oc-deploy/log_wrapper" "encoding/json"
) log "oc-deploy/log_wrapper"
)
type HelmChart struct {
Bin string type HelmChart struct {
Name string Bin string
Chart string Name string
Version string Chart string
Url string Version string
Url string
Workspace string
Opts string Workspace string
Values string Opts string
FileValues string Values string
} FileValues string
}
type installInfoOutput struct {
Description string `json:"description"` type installInfoOutput struct {
Notes string `json:"notes"` Description string `json:"description"`
Status string `json:"status"` Notes string `json:"notes"`
} Status string `json:"status"`
}
type installOutput struct {
Info installInfoOutput `json:"info"` type installOutput struct {
} Info installInfoOutput `json:"info"`
}
func (this HelmCommand) ChartInstall(data HelmChart) (string, error) {
bin := this.Bin func (this HelmChart) Install() (string, error) {
bin := this.Bin
existe, err := this.chartExists(data)
if err != nil { existe, err := this.exists()
return "", err if err != nil {
} return "", err
}
if existe {
return "Existe déjà", nil if existe {
} return "Existe déjà", nil
}
ficChart := data.Chart
// Recherche locale ficChart := this.Chart
if _, err := os.Stat(ficChart); err != nil { // Recherche locale
} else { if _, err := os.Stat(ficChart); err != nil {
// Recherche voa le Workspace } else {
ficChart := filepath.Join(data.Workspace, data.Chart) // Recherche voa le Workspace
if _, err := os.Stat(ficChart); err == nil { ficChart := filepath.Join(this.Workspace, this.Chart)
} else { if _, err := os.Stat(ficChart); err == nil {
if data.Url != "" { } else {
fmt.Println("============ 52 Télechargement", data.Url) if this.Url != "" {
} fmt.Println("============ 52 Télechargement", this.Url)
} }
} }
}
msg := fmt.Sprintf("%s install %s %s %s --output json", bin, data.Name, ficChart, data.Opts)
msg := fmt.Sprintf("%s install %s %s %s --output json", bin, this.Name, ficChart, this.Opts)
if data.Version != "" {
msg = fmt.Sprintf("%s --version %s", msg, data.Version) if this.Version != "" {
} msg = fmt.Sprintf("%s --version %s", msg, this.Version)
}
if data.FileValues != "" {
fic := filepath.Join(data.Workspace, data.FileValues) if this.FileValues != "" {
if _, err := os.Stat(fic); err != nil { fic := filepath.Join(this.Workspace, this.FileValues)
log.Log().Warn().Msg(fic) if _, err := os.Stat(fic); err != nil {
} else { log.Log().Warn().Msg(fic)
msg = fmt.Sprintf("%s --values %s", msg, fic) } else {
} msg = fmt.Sprintf("%s --values %s", msg, fic)
} }
}
msg = strings.Replace(msg, " ", " ", -1)
msg = strings.Replace(msg, " ", " ", -1)
log.Log().Debug().Msg(msg)
log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...) cmd_args := strings.Split(msg, " ")
stdout, err := cmd.CombinedOutput()
cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
if err != nil { stdout, err := cmd.CombinedOutput()
res := string(stdout)
res = strings.TrimSuffix(res, "\n") if err != nil {
return "", errors.New(res) res := string(stdout)
} res = strings.TrimSuffix(res, "\n")
return "", errors.New(res)
var objmap installOutput }
err = json.Unmarshal(stdout, &objmap) var objmap installOutput
if err != nil {
return "", err err = json.Unmarshal(stdout, &objmap)
} if err != nil {
return "", err
res := objmap.Info.Status }
return res, nil res := objmap.Info.Status
}
return res, nil
func (this HelmCommand) ChartUninstall(data HelmChart) (string, error) { }
bin := this.Bin
func (this HelmChart) Uninstall() (string, error) {
log.Log().Info().Msg(" >> Chart : " + data.Name) bin := this.Bin
existe, err := this.chartExists(data) log.Log().Info().Msg(" >> Chart : " + this.Name)
if err != nil {
return "", err existe, err := this.exists()
} if err != nil {
if ! existe { return "", err
return "Non présent", nil }
} if ! existe {
return "Non présent", nil
msg := fmt.Sprintf("%s uninstall %s", bin, data.Name) }
log.Log().Debug().Msg(msg)
msg := fmt.Sprintf("%s uninstall %s", bin, this.Name)
cmd_args := strings.Split(msg, " ") log.Log().Debug().Msg(msg)
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() cmd := exec.Command(bin, "uninstall", this.Name)
stdout, err := cmd.CombinedOutput()
res := string(stdout)
res = strings.TrimSuffix(res, "\n") return string(stdout), err
}
log.Log().Debug().Msg(res)
// ../bin/helm list --filter phpmyadminm --short
return res, err func (this HelmChart) exists() (bool, error) {
} bin := this.Bin
// ../bin/helm list --filter phpmyadminm --short msg := fmt.Sprintf("%s list --filter %s --no-headers", bin, this.Name)
func (this HelmCommand) chartExists(data HelmChart) (bool, error) { log.Log().Debug().Msg(msg)
bin := this.Bin
cmd_args := strings.Split(msg, " ")
msg := fmt.Sprintf("%s list --filter %s --no-headers", bin, data.Name)
log.Log().Debug().Msg(msg) cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
cmd_args := strings.Split(msg, " ") if err != nil {
cmd := this.Exec(cmd_args[0], cmd_args[1:]...) log.Log().Debug().Msg(string(stdout))
stdout, err := cmd.CombinedOutput() return false, errors.New(string(stdout))
if err != nil { }
log.Log().Debug().Msg(string(stdout))
return false, errors.New(string(stdout)) res := string(stdout)
} res = strings.TrimSuffix(res, "\n")
res := string(stdout) log.Log().Debug().Msg(string(stdout))
res = strings.TrimSuffix(res, "\n") log.Log().Debug().Msg(strconv.FormatBool(res != ""))
log.Log().Debug().Msg(string(stdout)) return res != "", nil
log.Log().Debug().Msg(strconv.FormatBool(res != "")) }
return res != "", nil func (this HelmChart) GetRessources() (map[string]string, error) {
} hs := HelmStatus{Name: this.Name}
hs.New(this.Bin)
// func (this HelmChart) GetRessources() (map[string]string, error) { data, _ := hs.getRessources()
// hs := HelmStatus{Name: this.Name}
// hs.New(this.Bin) return data, nil
// data, _ := hs.getRessources() }
// return data, nil
// }

View File

@ -1,30 +0,0 @@
package helm
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestHelmChartExists(t *testing.T){
cmd := getCmdHelm(true, `oc-catalog default 1 2024-09-06 16:01:49.17368605 +0200 CEST deployed oc-catalog-0.1.0 1.0`)
data := HelmChart{Name: "oc-catalog"}
res, err := cmd.chartExists(data)
assert.Nilf(t, err, "error message %s", err)
assert.Truef(t, res, "TestHelmVersion error")
}
func TestHelmChartNotExists(t *testing.T){
cmd := getCmdHelm(true, "\n")
data := HelmChart{Name: "phpmyadmin"}
res, err := cmd.chartExists(data)
assert.Nilf(t, err, "error message %s", err)
assert.Falsef(t, res, "TestHelmVersion error")
}

16
src/helm/command.go Normal file
View File

@ -0,0 +1,16 @@
package helm
import (
)
type HelmCommandInterface interface {
Status(string) (string, error)
AddRepository(HelmRepo) (string, error)
}
type HelmCommandData struct {
Bin string
}
type RealHelmCommand HelmCommandData

View File

@ -1,22 +0,0 @@
package helm
import (
"os/exec"
)
type HelmCommand struct {
Bin string
Exec func(string,...string) commandExecutor
}
////
type commandExecutor interface {
Output() ([]byte, error)
CombinedOutput() ([]byte, error)
}
func (this *HelmCommand) New() {
this.Exec = func(name string, arg ...string) commandExecutor {
return exec.Command(name, arg...)
}
}

View File

@ -1,17 +0,0 @@
package helm
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestHelm(t *testing.T) {
cmd := HelmCommand{}
cmd.New()
assert.NotNilf(t, cmd.Exec, "TestHelm %s", "New")
cmd.Exec("pwd")
}

View File

@ -1,9 +1,8 @@
package helm package helm
import ( import (
"os" "os"
"strings" "testing"
"testing"
"path/filepath" "path/filepath"
) )
@ -12,73 +11,14 @@ var TEST_SRC_DIR = filepath.Join("../../test", "helm")
var TEST_BIN_DIR = filepath.Join("../../test", "bin") var TEST_BIN_DIR = filepath.Join("../../test", "bin")
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
folderPath := TEST_DEST_DIR folderPath := TEST_DEST_DIR
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.MkdirAll(folderPath, os.ModePerm) os.MkdirAll(folderPath, os.ModePerm)
// call flag.Parse() here if TestMain uses flags // call flag.Parse() here if TestMain uses flags
exitCode := m.Run() exitCode := m.Run()
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.Exit(exitCode) os.Exit(exitCode)
} }
// Mock
type MockCommandExecutor struct {
// Used to stub the return of the Output method
// Could add other properties depending on testing needs
output string
}
// Implements the commandExecutor interface
func (m *MockCommandExecutor) Output() ([]byte, error) {
return []byte(m.output), nil
}
func (m *MockCommandExecutor) CombinedOutput() ([]byte, error) {
return []byte(m.output), nil
}
//
func getCmdHelm(mock bool, output string) (HelmCommand) {
if mock == true {
mock := func(name string, args ...string) commandExecutor {
return &MockCommandExecutor{output: output}
}
cmd := HelmCommand{Bin: "mock", Exec: mock}
return cmd
} else {
bin := filepath.Join(TEST_BIN_DIR, "helm")
os.Chmod(bin, 0700)
cmd := HelmCommand{Bin: bin}
cmd.New()
return cmd
}
}
func getCmdsHelm(mock bool, outputs map[string]string) (HelmCommand) {
if mock == true {
mock := func(name string, args ...string) commandExecutor {
cmd := strings.TrimSuffix(strings.Join(args," "), " ")
output := outputs[cmd]
return &MockCommandExecutor{output: output}
}
cmd := HelmCommand{Bin: "mock", Exec: mock}
return cmd
} else {
bin := filepath.Join(TEST_BIN_DIR, "helm")
os.Chmod(bin, 0700)
cmd := HelmCommand{Bin: bin}
cmd.New()
return cmd
}
}

View File

@ -1,98 +1,96 @@
package helm package helm
import ( import (
"fmt" "fmt"
"strings" "strings"
"encoding/json" "os/exec"
"encoding/json"
log "oc-deploy/log_wrapper"
"oc-deploy/utils" log "oc-deploy/log_wrapper"
) "oc-deploy/utils"
)
type HelmRepo struct {
Name string type HelmRepo struct {
Repository string // Url du dépôt Name string
ForceUpdate bool Repository string // Url du dépôt
Opts string ForceUpdate bool
} Opts string
}
func (this HelmCommand) AddRepository(repo HelmRepo) (string, error) {
func (this RealHelmCommand) AddRepository(repo HelmRepo) (string, error) {
helm_bin := this.Bin
helm_bin := this.Bin
force_update := "--force-update=false"
if repo.ForceUpdate { force_update := "--force-update=false"
force_update = "--force-update=true" if repo.ForceUpdate {
} else { force_update = "--force-update=true"
list, _ := this.ListRepository() } else {
if utils.StringInSlice(repo.Name, list) { list, _ := this.ListRepository()
return "Existe déjà", nil if utils.StringInSlice(repo.Name, list) {
} return "Existe déjà", nil
} }
}
msg := fmt.Sprintf("%s repo add %s %s %s %s", helm_bin, repo.Name, repo.Repository, force_update, repo.Opts)
log.Log().Debug().Msg(msg) msg := fmt.Sprintf("%s repo add %s %s %s %s", helm_bin, repo.Name, repo.Repository, force_update, repo.Opts)
log.Log().Debug().Msg(msg)
msg = strings.TrimSuffix(msg, " ")
cmd_args := strings.Split(msg, " ")
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...) cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
res := string(stdout) res := string(stdout)
res = strings.TrimSuffix(res, "\n") res = strings.TrimSuffix(res, "\n")
return res, err return res, err
} }
type parseList struct { type parseList struct {
Name string `json:"name"` Name string `json:"name"`
} }
func (this HelmCommand) ListRepository() ([]string, error) { func (this RealHelmCommand) ListRepository() ([]string, error) {
helm_bin := this.Bin helm_bin := this.Bin
res := make([]string, 0, 0) res := make([]string, 0, 0)
msg := fmt.Sprintf("%s repo list -o json", helm_bin) msg := fmt.Sprintf("%s repo list -o json", helm_bin)
log.Log().Debug().Msg(msg) log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ") cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...) cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return res, err return res, err
} }
var objmap []parseList var objmap []parseList
err = json.Unmarshal(stdout, &objmap) err = json.Unmarshal([]byte(stdout), &objmap)
if err != nil { if err != nil {
return res, err return res, err
} }
for _, ele := range objmap { for _, ele := range objmap {
res = append(res, ele.Name) res = append(res, ele.Name)
} }
return res, err return res, err
} }
// helm repo remove [NAME] // helm repo remove [NAME]
func (this HelmCommand) RemoveRepository(repo HelmRepo) (string, error) { func (this RealHelmCommand) RemoveRepository(repo HelmRepo) (string, error) {
helm_bin := this.Bin helm_bin := this.Bin
msg := fmt.Sprintf("%s repo remove %s", helm_bin, repo.Name) msg := fmt.Sprintf("%s repo remove %s", helm_bin, repo.Name)
log.Log().Debug().Msg(msg) log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ") cmd := exec.Command(helm_bin, "repo", "remove", repo.Name)
stdout, err := cmd.CombinedOutput()
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() res := string(stdout)
res = strings.TrimSuffix(res, "\n")
res := string(stdout)
res = strings.TrimSuffix(res, "\n") return res, err
}
return res, err
}

View File

@ -1,72 +1,39 @@
package helm package helm
import ( import (
"testing" "fmt"
// "os"
"github.com/stretchr/testify/assert" // "path/filepath"
)
"testing"
func TestHelmListRepository(t *testing.T){
"github.com/stretchr/testify/assert"
cmd := getCmdHelm(true, `[{"name":"bitnami","url":"https://charts.bitnami.com/bitnami"}]`) )
res, err := cmd.ListRepository() func TestHelmRepoAdd(t *testing.T) {
assert.Nilf(t, err, "error message %s", err) repo := HelmRepo{
assert.Equal(t, "bitnami", res[0], "TestHelmVersion error") Bin: "./helm",
} Name: "repooc",
Repository: "https://url",
func TestHelmRemoveRepository(t *testing.T){ ForceUpdate: true,
Opts: ""}
cmd := getCmdHelm(true, `"bitnami" has been removed from your repositories`) fmt.Println(" TestHelmRepoAdd ", repo)
repo := HelmRepo{Name: "bitnami"} res, err := repo.AddRepository()
res, err := cmd.RemoveRepository(repo) fmt.Println("TestHelmRepoAdd.24", res, err)
}
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, `"bitnami" has been removed from your repositories`, res, "TestHelmRemoveRepository error") // helm : not found
} func TestHelmRepoAddErr(t *testing.T) {
func TestHelmRemoveRepository2(t *testing.T){ repo := HelmRepo{
Bin: "./helm",
cmd := getCmdHelm(true, `Error: no repositories configured`) Name: "repooc",
Repository: "https://url",
repo := HelmRepo{Name: "bitnami"} ForceUpdate: true,
res, err := cmd.RemoveRepository(repo) Opts: ""}
assert.Nilf(t, err, "error message %s", err) _, err := repo.AddRepository()
assert.Equal(t, `Error: no repositories configured`, res, "TestHelmRemoveRepository error") assert.NotNilf(t, err, "error message %s", "./helm")
} }
func TestHelmAddRepositoryNew(t *testing.T){
cmd_output := map[string]string{
"repo list -o json": `[{"name":"repo1","url":"https://repo.com"}]`,
"repo add repo2 https://repo2.com --force-update=false": `"repo2" has been added to your repositories"`,
}
cmd := getCmdsHelm(true, cmd_output)
repo := HelmRepo{Name: "repo2", Repository: "https://repo2.com", ForceUpdate: false}
res, err := cmd.AddRepository(repo)
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, `"repo2" has been added to your repositories"`, res, "TestHelmAddRepositoryNew error")
}
func TestHelmAddRepositoryExists(t *testing.T){
cmd_output := map[string]string{
"repo list -o json": `[{"name":"repo1","url":"https://repo.com"}]`,
"version --short": "v3.15.4+gfa9efb0",
}
cmd := getCmdsHelm(true, cmd_output)
repo := HelmRepo{Name: "repo1", Repository: "https://repo.com", ForceUpdate: false}
res, err := cmd.AddRepository(repo)
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, `Existe déjà`, res, "TestHelmRemoveRepository error")
}

View File

@ -4,6 +4,20 @@ import (
// "fmt" // "fmt"
"encoding/json" "encoding/json"
) )
type HelmStatus struct {
Name string // Nom
command HelmCommandInterface
}
func (this *HelmStatus) New(bin string) {
this.command = RealHelmCommand{Bin: bin}
}
func (this *HelmStatus) NewMock(mock HelmCommandInterface) {
this.command = mock
}
//// ////
type parseStatusInfoResourcesMetadata struct { type parseStatusInfoResourcesMetadata struct {
@ -43,11 +57,11 @@ type parseStatus struct {
Info parseStatusInfo `json:"info"` Info parseStatusInfo `json:"info"`
} }
func (this HelmCommand) GetRessources(data HelmChart) (map[string]string, error) { func (this HelmStatus) getRessources() (map[string]string, error) {
res := make(map[string]string) res := make(map[string]string)
status, err := this.Status(data) status, err := this.command.Status(this.Name)
if err != nil { if err != nil {
return res, err return res, err
} }

View File

@ -9,16 +9,20 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestHelmRessources(t *testing.T){ type MockCommandStatus HelmCommandData
fileName := filepath.Join(TEST_SRC_DIR, "helm_status.json") func TestHelmStatus(t *testing.T){
res_json, _ := os.ReadFile(fileName)
cmd := getCmdHelm(true, string(res_json)) hs := HelmStatus{Name: "oc-catalog"}
hs.NewMock(MockCommandStatus{})
data := HelmChart{Name: "test1"} data, _ := hs.getRessources()
res, err := cmd.GetRessources(data) assert.Equal(t, "StatefulSet", data["oc-catalog-oc-catalog"], "TestHelmStatus error")
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, "StatefulSet", res["oc-catalog-oc-catalog"], "TestHelmStatus error")
} }
// Mock
func (this MockCommandStatus) Status(name string) (string, error) {
fileName := filepath.Join(TEST_SRC_DIR, "helm_status.json")
data, _ := os.ReadFile(fileName)
return string(data), nil
}

View File

@ -3,25 +3,22 @@ package helm
import ( import (
"fmt" "fmt"
"strings" "strings"
"errors" "errors"
"os/exec"
log "oc-deploy/log_wrapper" log "oc-deploy/log_wrapper"
) )
// type HelmData struct { func (this RealHelmCommand) Status(name string) (string, error) {
// Name string
// }
func (this HelmCommand) Status(data HelmChart) (string, error) {
helm_bin := this.Bin helm_bin := this.Bin
msg := fmt.Sprintf("%s status %s --show-resources -o json", helm_bin, data.Name) msg := fmt.Sprintf("%s status %s --show-resources -o json", helm_bin, name)
log.Log().Debug().Msg(msg) log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ") cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...) cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Log().Debug().Msg(string(stdout)) log.Log().Debug().Msg(string(stdout))
@ -30,3 +27,4 @@ func (this HelmCommand) Status(data HelmChart) (string, error) {
return string(stdout), nil return string(stdout), nil
} }

View File

@ -1,20 +1,20 @@
package helm package helm
import ( import (
"strings" "strings"
) "os/exec"
)
func (this HelmCommand) GetVersion() (string, error) { func Version(path string) (string, error) {
cmd := this.Exec(this.Bin, "version", "--short") cmd := exec.Command(path, "version", "--short")
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return "", err return "", err
} }
res := string(stdout) res := string(stdout)
res = strings.TrimSuffix(res, "\n") res = strings.TrimSuffix(res, "\n")
return res, nil return res, nil
} }

View File

@ -1,18 +1,22 @@
package helm package helm
import ( import (
"testing" "os"
"path/filepath"
"github.com/stretchr/testify/assert"
) "testing"
func TestHelmVersion(t *testing.T){ "github.com/stretchr/testify/assert"
)
cmd := getCmdHelm(true, "v3.15.4+gfa9efb0\n")
func TestHelmVersion(t *testing.T){
version, err := cmd.GetVersion()
bin := filepath.Join(TEST_BIN_DIR, "helm")
assert.Nilf(t, err, "error message %s", err) os.Chmod(bin, 0700)
assert.Equal(t, "v3.15.4+gfa9efb0", version, "TestHelmVersion error") assert.FileExists(t, bin, "TestHelmVersion error")
}
version, err := Version(bin)
assert.Nilf(t, err, "error message %s", bin)
assert.Equal(t, "v3.15.4+gfa9efb0", version, "TestHelmVersion error")
}

View File

@ -51,17 +51,15 @@ func (this *InstallClass) Tools() (error) {
func (this *InstallClass) SetCommands() { func (this *InstallClass) SetCommands() {
helm_bin, _ := this.getToolBin("helm") helm_bin, _ := this.getToolBin("helm")
this.commandHelm = helm.HelmCommand{Bin: helm_bin} this.commandHelm = helm.RealHelmCommand{Bin: helm_bin}
this.commandHelm.New()
kubectl_bin, _ := this.getToolBin("kubectl") // kubectl_bin, _ := this.getToolBin("kubectl")
this.commandKubectl = kubectl.KubectlCommand{Bin: kubectl_bin} // this.commandKubectl = helm.RealHelmCommand{Bin: kubectl_bin}
this.commandKubectl.New()
} }
// func (this *InstallClass) SetCommandsMock(mock helm.HelmCommandInterface) { func (this *InstallClass) SetCommandsMock(mock helm.HelmCommandInterface) {
// this.commandHelm = mock this.commandHelm = mock
// } }
func (this *InstallClass) getToolBin(name string) (string, error) { func (this *InstallClass) getToolBin(name string) (string, error) {
for key, value := range this.toolsBin { for key, value := range this.toolsBin {
@ -74,8 +72,9 @@ func (this *InstallClass) getToolBin(name string) (string, error) {
} }
func (this *InstallClass) K8s(context string) (error) { func (this *InstallClass) K8s(context string) (error) {
bin_path, _ := this.getToolBin("kubectl")
kube := this.commandKubectl kube := kubectl.KubeContext{Bin: bin_path}
err := kube.UseContext(context) err := kube.UseContext(context)
if err != nil { if err != nil {

View File

@ -22,8 +22,7 @@ type InstallClass struct {
toolsBin map[string]string toolsBin map[string]string
charts []chart.ChartRepoData charts []chart.ChartRepoData
commandHelm helm.HelmCommand commandHelm helm.HelmCommandInterface
commandKubectl kubectl.KubectlCommand
} }
func (this *InstallClass) NewInstall() (string, error) { func (this *InstallClass) NewInstall() (string, error) {
@ -92,19 +91,19 @@ func (this *InstallClass) ChartRepo() (error) {
func (this *InstallClass) InstallCharts(modules []string) (error) { func (this *InstallClass) InstallCharts(modules []string) (error) {
// helm_bin, _ := this.getToolBin("helm") helm_bin, _ := this.getToolBin("helm")
// kubectl_bin, _ := this.getToolBin("kubectl") kubectl_bin, _ := this.getToolBin("kubectl")
var wg sync.WaitGroup var wg sync.WaitGroup
for _, v := range this.charts { for _, v := range this.charts {
for _, v1 := range v.Charts { for _, v1 := range v.Charts {
if len(modules) == 0 || utils.StringInSlice(v1.Name, modules) { if len(modules) == 0 || stringInSlice(v1.Name, modules) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
this.installChart(v1) this.installChart(helm_bin, kubectl_bin, v1)
} () } ()
} }
} }
@ -113,32 +112,45 @@ func (this *InstallClass) InstallCharts(modules []string) (error) {
return nil return nil
} }
func (this *InstallClass) installChart(chart chart.ChartData) { func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
func (this *InstallClass) installChart(helm_bin string, kubectl_bin string, chart chart.ChartData) {
log.Log().Info().Msg(fmt.Sprintf(" << Chart : %s ", chart.Name)) log.Log().Info().Msg(fmt.Sprintf(" << Chart : %s ", chart.Name))
data := helm.HelmChart{Name: chart.Name, helmchart := helm.HelmChart{Bin: helm_bin,
Chart: chart.Chart, Name: chart.Name,
Url: chart.Url, Chart: chart.Chart,
Version: chart.Version, Url: chart.Url,
Workspace: this.Workspace, Version: chart.Version,
Opts: chart.Opts, Workspace: this.Workspace,
Values: chart.Values, Opts: chart.Opts,
FileValues: chart.FileValues} Values: chart.Values,
FileValues: chart.FileValues}
res, err := this.commandHelm.ChartInstall(data) res, err := helmchart.Install()
if err != nil { if err != nil {
log.Log().Error().Msg(fmt.Sprintf(" >> %s %s (%s)", data.Name, "KO", err)) log.Log().Error().Msg(fmt.Sprintf(" >> %s %s (%s)", helmchart.Name, "KO", err))
return return
} }
log.Log().Info().Msg(fmt.Sprintf(" >> %s (%s)", data.Name, res)) log.Log().Info().Msg(fmt.Sprintf(" >> %s (%s)", helmchart.Name, res))
ressources, _ := this.commandHelm.GetRessources(data) ressources, _ := helmchart.GetRessources()
for key, value := range ressources { for key, value := range ressources {
obj := kubectl.KubectlObject{Name: key, Kind: value} obj := kubectl.KubeObject{Bin: kubectl_bin,
err := this.commandKubectl.Wait(obj) Kind: value,
Name: key}
err := obj.Wait()
if err != nil { if err != nil {
log.Log().Error().Msg(fmt.Sprintf(" >> %s/%s KO (%s)", chart.Name, key, err)) log.Log().Error().Msg(fmt.Sprintf(" >> %s/%s KO (%s)", chart.Name, key, err))
} else { } else {

View File

@ -63,19 +63,13 @@ func (this *InstallClass) uninstallChart(helm_bin string, kubectl_bin string, ch
log.Log().Info().Msg(fmt.Sprintf(" << Chart : %s ", chart.Name)) log.Log().Info().Msg(fmt.Sprintf(" << Chart : %s ", chart.Name))
helmchart := helm.HelmChart{Bin: helm_bin,
Name: chart.Name}
helm_cmd := helm.HelmCommand{Bin: helm_bin} res, err := helmchart.Uninstall()
helm_cmd.New()
data := helm.HelmChart{Name: chart.Name}
// helmchart := helm.HelmChart{Bin: helm_bin,
// Name: chart.Name}
res, err := helm_cmd.ChartUninstall(data)
if err != nil { if err != nil {
log.Log().Error().Msg(fmt.Sprintf(" >> %s %s (%s)", data.Name, "KO", err)) log.Log().Error().Msg(fmt.Sprintf(" >> %s %s (%s)", helmchart.Name, "KO", err))
return return
} }
log.Log().Info().Msg(fmt.Sprintf(" >> %s (%s)", data.Name, res)) log.Log().Info().Msg(fmt.Sprintf(" >> %s (%s)", helmchart.Name, res))
} }

29
src/kubectl/command.go Normal file
View File

@ -0,0 +1,29 @@
package kubectl
// import (
// "fmt"
// )
// type KubectlCommandInterface interface {
// // GetDeployment() (string, error)
// GetDeployment() (string, error)
// }
// type KubectlCommandData struct {
// bin string
// command string
// }
// type Real KubectlCommandStatus KubectlCommandData
// // func (this KubectlCommandStatus) Status() (string, error) {
// // fmt.Println("BIN ", this.bin)
// // fmt.Println("COMMAND status")
// // return "Res de KubectlCommandStatus", nil
// // }
// func (this KubectlCommandStatus) GetDeployment() (string, error) {
// fmt.Println("BIN ", this.bin)
// fmt.Println("COMMAND status")
// return "Res de GetDeployment", nil
// }

View File

@ -1,14 +1,18 @@
package kubectl package kubectl
import ( import (
"fmt" // "fmt"
"strings" "strings"
"errors" "errors"
"os/exec"
"encoding/json" "encoding/json"
log "oc-deploy/log_wrapper" log "oc-deploy/log_wrapper"
) )
type KubeContext struct {
Bin string // Chemin vers le binaire
}
type kubeConfig struct { type kubeConfig struct {
CurrentContext string `json:"current-context"` CurrentContext string `json:"current-context"`
@ -36,14 +40,9 @@ type kubeConfigClusters struct {
Cluster kubeConfigCluster `json:"cluster"` Cluster kubeConfigCluster `json:"cluster"`
} }
func (this KubectlCommand) GetCurrentContext() (string, error) { func (this KubeContext) GetCurrentContext() (string, error) {
bin := this.Bin
msg := fmt.Sprintf("%s config current-context", bin) cmd := exec.Command(this.Bin, "config", "current-context")
log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
res := string(stdout) res := string(stdout)
@ -52,24 +51,16 @@ func (this KubectlCommand) GetCurrentContext() (string, error) {
return res, err return res, err
} }
// currentContext, currentNamespace, currentServer // Current Context
func (this KubectlCommand) GetContext() (string, string, string, error) { // namespace, server
func (this KubeContext) GetContext() (string, string, string, error) {
bin := this.Bin cmd := exec.Command(this.Bin, "config", "view", "-o", "json")
stdout, _ := cmd.CombinedOutput()
msg := fmt.Sprintf("%s config view -o json", bin)
log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
return "", "", "", errors.New(string(stdout))
}
var objmap kubeConfig var objmap kubeConfig
err = json.Unmarshal(stdout, &objmap) err := json.Unmarshal(stdout, &objmap)
if err != nil { if err != nil {
return "", "", "", err return "", "", "", err
} }
@ -94,16 +85,11 @@ func (this KubectlCommand) GetContext() (string, string, string, error) {
return currentContext, currentNamespace, currentServer, nil return currentContext, currentNamespace, currentServer, nil
} }
func (this KubectlCommand) UseContext(newContext string) (error) { func (this KubeContext) UseContext(newContext string) (error) {
bin := this.Bin cmd := exec.Command(this.Bin, "config", "use-context", newContext)
msg := fmt.Sprintf("%s config use-context %s", bin, newContext)
log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Log().Debug().Msg(string(stdout)) log.Log().Debug().Msg(string(stdout))
return errors.New(string(stdout)) return errors.New(string(stdout))
@ -112,14 +98,9 @@ func (this KubectlCommand) UseContext(newContext string) (error) {
return nil return nil
} }
func (this KubectlCommand) Check() (error) { func (this KubeContext) Check() (error) {
bin := this.Bin
msg := fmt.Sprintf("%s cluster-info", bin) cmd := exec.Command(this.Bin, "cluster-info")
log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput() stdout, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Log().Debug().Msg(string(stdout)) log.Log().Debug().Msg(string(stdout))

View File

@ -1,86 +0,0 @@
package kubectl
import (
"os"
"path/filepath"
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
var MOCK_ENABLE = true
func TestKubectCurrentContext(t *testing.T) {
cmd := getCmdKubectl(MOCK_ENABLE, "minikube")
res, err := cmd.GetCurrentContext()
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, "minikube", res, "TestKubectCurrentContext error")
}
func TestKubectContext(t *testing.T) {
fileName := filepath.Join(TEST_SRC_DIR, "context.json")
cmd_json, _ := os.ReadFile(fileName)
cmd := getCmdKubectl(MOCK_ENABLE, string(cmd_json))
currentContext, currentNamespace, currentServer, err := cmd.GetContext()
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, "minikube", currentContext, "TestKubectContext error")
assert.Equal(t, "default", currentNamespace, "TestKubectContext error")
assert.Equal(t, "https://127.0.0.1:38039", currentServer, "TestKubectContext error")
}
func TestKubectUseContext(t *testing.T) {
cmd := getCmdKubectl(MOCK_ENABLE, `Switched to context "minikube".`)
err := cmd.UseContext("minikube")
assert.Nilf(t, err, "error message %s", err)
}
func TestKubectUseContextErr(t *testing.T) {
error := errors.New("exit 1")
cmd := getCmdKubectlError(MOCK_ENABLE, `error: no context exists with the name: "minikube2"`, error)
err := cmd.UseContext("minikube2")
assert.NotNilf(t, err, "error message %s", err)
}
func TestKubectCheck(t *testing.T) {
cmd_txt := `
Kubernetes control plane is running at https://127.0.0.1:38039
CoreDNS is running at https://127.0.0.1:38039/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
`
// error := errors.New("exit 1")
cmd := getCmdKubectl(MOCK_ENABLE, cmd_txt)
err := cmd.Check()
assert.Nilf(t, err, "error message %s", err)
}
func TestKubectCheckErr(t *testing.T) {
cmd_txt := ""
error := errors.New("exit 1")
cmd := getCmdKubectlError(MOCK_ENABLE, cmd_txt, error)
err := cmd.Check()
assert.NotNilf(t, err, "error message %s", "TestKubectCheckErr")
}

View File

@ -1,40 +0,0 @@
package kubectl
import (
"fmt"
"strings"
"errors"
"encoding/json"
log "oc-deploy/log_wrapper"
)
func (this KubectlCommand) getDeployment(data KubectlObject) (map[string]any, error) {
bin := this.Bin
msg := fmt.Sprintf("%s get deployment %s -o json", bin, data.Name)
log.Log().Debug().Msg(msg)
m := make(map[string]any)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
return m, errors.New(string(stdout))
}
var objmap getOutput
json.Unmarshal(stdout, &objmap)
kind := objmap.Kind
status := objmap.Status
m["name"] = data.Name
m["kind"] = kind
m["replicas"] = status.Replicas
m["UnavailableReplicas"] = status.UnavailableReplicas
return m, nil
}

View File

@ -1,29 +0,0 @@
package kubectl
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestKubectDeployment(t *testing.T) {
fileName := filepath.Join(TEST_SRC_DIR, "deployment.json")
cmd_json, _ := os.ReadFile(fileName)
cmd := getCmdKubectl(true, string(cmd_json))
data := KubectlObject{Name: "dep1", Kind: "Deployment"}
res, err := cmd.getDeployment(data)
// map[string]interface {}(map[string]interface {}{"UnavailableReplicas":0, "kind":"Deployment", "name":"dep1", "replicas":1})
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, "Deployment", res["kind"], "TestKubectDeployment error")
assert.Equal(t, 1, res["replicas"], "TestKubectDeployment error")
}

View File

@ -1,22 +0,0 @@
package kubectl
import (
"os/exec"
)
type KubectlCommand struct {
Bin string
Exec func(string,...string) commandExecutor
}
////
type commandExecutor interface {
Output() ([]byte, error)
CombinedOutput() ([]byte, error)
}
func (this *KubectlCommand) New() {
this.Exec = func(name string, arg ...string) commandExecutor {
return exec.Command(name, arg...)
}
}

View File

@ -1,17 +0,0 @@
package kubectl
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestKubectl(t *testing.T) {
cmd := KubectlCommand{}
cmd.New()
assert.NotNilf(t, cmd.Exec, "TestKubectl %s", "New")
cmd.Exec("pwd")
}

View File

@ -1,9 +1,8 @@
package kubectl package kubectl
import ( import (
"os" "os"
"strings" "testing"
"testing"
"path/filepath" "path/filepath"
) )
@ -12,93 +11,14 @@ var TEST_SRC_DIR = filepath.Join("../../test", "kubectl")
var TEST_BIN_DIR = filepath.Join("../../test", "bin") var TEST_BIN_DIR = filepath.Join("../../test", "bin")
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
folderPath := TEST_DEST_DIR folderPath := TEST_DEST_DIR
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.MkdirAll(folderPath, os.ModePerm) os.MkdirAll(folderPath, os.ModePerm)
// call flag.Parse() here if TestMain uses flags // call flag.Parse() here if TestMain uses flags
exitCode := m.Run() exitCode := m.Run()
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.Exit(exitCode) os.Exit(exitCode)
} }
// Mock
type MockCommandExecutor struct {
// Used to stub the return of the Output method
// Could add other properties depending on testing needs
output string
err error
}
// Implements the commandExecutor interface
func (m *MockCommandExecutor) Output() ([]byte, error) {
return []byte(m.output), m.err
}
func (m *MockCommandExecutor) CombinedOutput() ([]byte, error) {
return []byte(m.output), m.err
}
//
func getCmdKubectl(mock bool, output string) (KubectlCommand) {
if mock == true {
mock := func(name string, args ...string) commandExecutor {
return &MockCommandExecutor{output: output}
}
cmd := KubectlCommand{Bin: "mock", Exec: mock}
return cmd
} else {
bin := filepath.Join(TEST_BIN_DIR, "kubectl")
os.Chmod(bin, 0700)
cmd := KubectlCommand{Bin: bin}
cmd.New()
return cmd
}
}
func getCmdsKubectl(mock bool, outputs map[string]string) (KubectlCommand) {
if mock == true {
mock := func(name string, args ...string) commandExecutor {
cmd := strings.TrimSuffix(strings.Join(args," "), " ")
output := outputs[cmd]
return &MockCommandExecutor{output: output}
}
cmd := KubectlCommand{Bin: "mock", Exec: mock}
return cmd
} else {
bin := filepath.Join(TEST_BIN_DIR, "kubectl")
os.Chmod(bin, 0700)
cmd := KubectlCommand{Bin: bin}
cmd.New()
return cmd
}
}
func getCmdKubectlError(mock bool, output string, err error) (KubectlCommand) {
if mock == true {
mock := func(name string, args ...string) commandExecutor {
return &MockCommandExecutor{output: output, err: err}
}
cmd := KubectlCommand{Bin: "mock", Exec: mock}
return cmd
} else {
bin := filepath.Join(TEST_BIN_DIR, "kubectl")
os.Chmod(bin, 0700)
cmd := KubectlCommand{Bin: bin}
cmd.New()
return cmd
}
}

View File

@ -1,56 +1,122 @@
package kubectl package kubectl
import ( import (
"fmt" "fmt"
"time" "strings"
"errors" "errors"
"time"
log "oc-deploy/log_wrapper" "os/exec"
) "encoding/json"
log "oc-deploy/log_wrapper"
)
type KubectlObject struct {
Name string type KubeObject struct {
Kind string Bin string // Chemin vers le binaire
} Name string
Kind string
type getOutput struct { }
Kind string `json:"kind"`
Status getStatusOutput `json:"status"` type getOutput struct {
} Kind string `json:"kind"`
Status getStatusOutput `json:"status"`
type getStatusOutput struct { }
Replicas int `json:"replicas"`
UnavailableReplicas int `json:"unavailableReplicas"` type getStatusOutput struct {
} Replicas int `json:"replicas"`
UnavailableReplicas int `json:"unavailableReplicas"`
func (this KubectlCommand) Get(data KubectlObject) (map[string]any, error) { }
if data.Kind == "Deployment" {return this.getDeployment(data)}
if data.Kind == "StatefulSet" {return this.getStatefulSet(data)} func (this KubeObject) Get() (map[string]any, error) {
return make(map[string]any), fmt.Errorf("Kind %s inconnu", data.Kind) if this.Kind == "Deployment" {return this.getDeployment()}
} if this.Kind == "StatefulSet" {return this.getStatefulSet()}
return make(map[string]any), fmt.Errorf("Kind %s inconnu", this.Kind)
func (this KubectlCommand) Wait(data KubectlObject) (error) { }
boucle := 10 func (this KubeObject) getDeployment() (map[string]any, error) {
sleep := 10000 * time.Millisecond bin := this.Bin
name := this.Name
for _ = range boucle {
msg := fmt.Sprintf("%s get deployment %s -o json", bin, name)
log.Log().Debug().Msg(fmt.Sprintf("Check Deployement %s", data.Name)) log.Log().Debug().Msg(msg)
m, err := this.Get(data) m := make(map[string]any)
if err != nil {
return err cmd_args := strings.Split(msg, " ")
}
ko := m["UnavailableReplicas"].(int) cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
if ko == 0 { stdout, err := cmd.CombinedOutput()
return nil if err != nil {
} return m, errors.New(string(stdout))
}
log.Log().Info().Msg(fmt.Sprintf(" >> %s (Unavailable : %d)...", data.Name, ko))
time.Sleep(sleep) var objmap getOutput
} json.Unmarshal(stdout, &objmap)
return errors.New("Temps d'attente dépassé")
kind := objmap.Kind
status := objmap.Status
m["name"] = name
m["kind"] = kind
m["replicas"] = status.Replicas
m["UnavailableReplicas"] = status.UnavailableReplicas
return m, nil
}
func (this KubeObject) getStatefulSet() (map[string]any, error) {
bin := this.Bin
name := this.Name
msg := fmt.Sprintf("%s get statefulset %s -o json", bin, name)
log.Log().Debug().Msg(msg)
m := make(map[string]any)
cmd_args := strings.Split(msg, " ")
cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
return m, errors.New(string(stdout))
}
var objmap getOutput
json.Unmarshal(stdout, &objmap)
kind := objmap.Kind
status := objmap.Status
m["name"] = name
m["kind"] = kind
m["replicas"] = status.Replicas
m["UnavailableReplicas"] = status.UnavailableReplicas
return m, nil
}
func (this KubeObject) Wait() (error) {
boucle := 10
sleep := 10000 * time.Millisecond
for _ = range boucle {
log.Log().Debug().Msg(fmt.Sprintf("Check Deployement %s", this.Name))
m, err := this.Get()
if err != nil {
return err
}
ko := m["UnavailableReplicas"].(int)
if ko == 0 {
return nil
}
log.Log().Info().Msg(fmt.Sprintf(" >> %s (Unavailable : %d)...", this.Name, ko))
time.Sleep(sleep)
}
return errors.New("Temps d'attente dépassé")
} }

View File

@ -1,28 +0,0 @@
package kubectl
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestKubectStatefulset(t *testing.T) {
fileName := filepath.Join(TEST_SRC_DIR, "statefulset.json")
cmd_json, _ := os.ReadFile(fileName)
cmd := getCmdKubectl(true, string(cmd_json))
data := KubectlObject{Name: "dep1", Kind: "Statefulset"}
res, err := cmd.getDeployment(data)
// map[string]interface {}(map[string]interface {}{"UnavailableReplicas":0, "kind":"StatefulSet", "name":"dep1", "replicas":1})
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, "StatefulSet", res["kind"], "TestKubectDeployment error")
assert.Equal(t, 1, res["replicas"], "TestKubectDeployment error")
}

View File

@ -1,43 +0,0 @@
package kubectl
import (
"fmt"
"strings"
"errors"
"encoding/json"
log "oc-deploy/log_wrapper"
)
func (this KubectlCommand) getStatefulSet(data KubectlObject) (map[string]any, error) {
bin := this.Bin
name := data.Name
msg := fmt.Sprintf("%s get statefulset %s -o json", bin, name)
log.Log().Debug().Msg(msg)
m := make(map[string]any)
cmd_args := strings.Split(msg, " ")
cmd := this.Exec(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
return m, errors.New(string(stdout))
}
var objmap getOutput
json.Unmarshal(stdout, &objmap)
kind := objmap.Kind
status := objmap.Status
m["name"] = name
m["kind"] = kind
m["replicas"] = status.Replicas
m["UnavailableReplicas"] = status.UnavailableReplicas
return m, nil
}

View File

@ -1,29 +1,31 @@
package kubectl package kubectl
import ( import (
"encoding/json" "os/exec"
) "encoding/json"
)
type toolClientVersion struct {
GitVersion string `json:"gitVersion"` type toolClientVersion struct {
} GitVersion string `json:"gitVersion"`
}
type toolVersion struct {
ClientVersion toolClientVersion `json:"clientVersion"` type toolVersion struct {
} ClientVersion toolClientVersion `json:"clientVersion"`
}
func (this KubectlCommand) GetVersion() (string, error) {
func Version(path string) (string, error) {
cmd := this.Exec(this.Bin, "version", "-o", "json", "--client=true")
stdout, err := cmd.CombinedOutput() cmd := exec.Command(path, "version", "-o", "json", "--client=true")
if err != nil { stdout, err := cmd.CombinedOutput()
return "", err
} if err != nil {
return "", err
var objmap toolVersion }
json.Unmarshal(stdout, &objmap) var objmap toolVersion
res := objmap.ClientVersion.GitVersion
json.Unmarshal(stdout, &objmap)
return res, nil res := objmap.ClientVersion.GitVersion
}
return res, nil
}

View File

@ -1,33 +1,22 @@
package kubectl package kubectl
import ( import (
"testing" "os"
"path/filepath"
"github.com/stretchr/testify/assert"
) "testing"
func TestKubectlVersion(t *testing.T) { "github.com/stretchr/testify/assert"
)
cmd_json := `
{ func TestKubectlVersion(t *testing.T){
"clientVersion": {
"major": "1", bin := filepath.Join(TEST_BIN_DIR, "kubectl")
"minor": "30", os.Chmod(bin, 0700)
"gitVersion": "v1.30.3", assert.FileExists(t, bin, "TestKubectlVersion error")
"gitCommit": "6fc0a69044f1ac4c13841ec4391224a2df241460",
"gitTreeState": "clean", version, err := Version(bin)
"buildDate": "2024-07-16T23:54:40Z",
"goVersion": "go1.22.5", assert.Nilf(t, err, "error message %s", bin)
"compiler": "gc", assert.Equal(t, "v1.30.3", version, "TestKubectlVersion error")
"platform": "linux/amd64" }
},
"kustomizeVersion": "v5.0.4-0.20230601165947-6ce0bf390ce3"
}`
cmd := getCmdKubectl(true, cmd_json)
version, err := cmd.GetVersion()
assert.Nilf(t, err, "error message %s", err)
assert.Equal(t, "v1.30.3", version, "TestkubectlVersion error")
}

View File

@ -4,7 +4,6 @@ package log_wrapper
import ( import (
"os" "os"
"path/filepath"
"github.com/rs/zerolog" "github.com/rs/zerolog"
) )
@ -29,10 +28,9 @@ func Log() *zerolog.Logger {
return &mainLogVar return &mainLogVar
} }
func InitLog(filename string) bool { func InitLog(serverName string) bool {
ficlog := filepath.Join(filename + ".log") fAll, _ := os.OpenFile("./" + serverName + ".log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
fAll, _ := os.OpenFile(ficlog, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
output := zerolog.ConsoleWriter{Out: os.Stdout} output := zerolog.ConsoleWriter{Out: os.Stdout}
writerInfo := zerolog.MultiLevelWriter(output) writerInfo := zerolog.MultiLevelWriter(output)

View File

@ -1,21 +0,0 @@
package log_wrapper
import (
// "os"
"path/filepath"
// "errors"
"testing"
"github.com/stretchr/testify/assert"
)
func TestLogWrapper(t *testing.T) {
ficlog := filepath.Join(TEST_DEST_DIR, "test")
InitLog(ficlog)
Log().Info().Msg("KKK")
Log().Error().Msg("KKK")
assert.FileExists(t, ficlog + ".log", "TestLogWrapper")
}

View File

@ -1,21 +0,0 @@
package log_wrapper
import (
"os"
"testing"
)
var TEST_DEST_DIR = "../wrk_log"
func TestMain(m *testing.M) {
folderPath := TEST_DEST_DIR
os.RemoveAll(folderPath)
os.MkdirAll(folderPath, os.ModePerm)
// call flag.Parse() here if TestMain uses flags
exitCode := m.Run()
os.RemoveAll(folderPath)
os.Exit(exitCode)
}

View File

@ -1,9 +0,0 @@
package occonst
import (
"testing"
)
func TestMain(m *testing.M) {
}

View File

@ -1,6 +1,6 @@
package occonst package occonst
var ONLINE_URL = "https://cloud.o-forge.io" const ONLINE_URL = "https://cloud.o-forge.io"
var ONLINE_VERSION = "core/oc-deploy" const ONLINE_VERSION = "core/oc-deploy"
var OFFLINE_DIR = "../../offline" var OFFLINE_DIR = "../../offline"

View File

@ -1,6 +1,8 @@
package tool package tool
import ( import (
"fmt"
// "os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -13,6 +15,7 @@ func TestToolConf(t *testing.T) {
src := filepath.Join(TEST_SRC_DIR, "oc.yml") src := filepath.Join(TEST_SRC_DIR, "oc.yml")
data, err := FromConfigFile(src) data, err := FromConfigFile(src)
fmt.Println("data", src, data, err)
assert.Equal(t, "kubectl", data[0].Name, "TestToolConf error") assert.Equal(t, "kubectl", data[0].Name, "TestToolConf error")
assert.Nilf(t, err, "error message %s", src) assert.Nilf(t, err, "error message %s", src)
} }

View File

@ -8,16 +8,16 @@ import (
"oc-deploy/helm" "oc-deploy/helm"
) )
type HelmInstall struct { type HelmInstallData struct {
obj ToolData obj ToolData
tmp string tmp string
} }
func (this HelmInstall) Get() (ToolData) { func (this HelmInstallData) Get() (ToolData) {
return this.obj return this.obj
} }
func (this HelmInstall) Download() (error) { func (this HelmInstallData) Download() (error) {
bin_dir := this.obj.Bin bin_dir := this.obj.Bin
err2 := os.MkdirAll(bin_dir, os.ModePerm) err2 := os.MkdirAll(bin_dir, os.ModePerm)
@ -35,9 +35,7 @@ func (this HelmInstall) Download() (error) {
r, _ := os.Open(tmp_file) r, _ := os.Open(tmp_file)
err1 := utils.ExtractTarGz(bin_dir, r) err1 := utils.ExtractTarGz(bin_dir, r)
if err1 != nil { if err1 != nil {return err1}
return err1
}
os.Remove(tmp_file) os.Remove(tmp_file)
@ -50,8 +48,6 @@ func (this HelmInstall) Download() (error) {
} }
/////////////// ///////////////
func (this HelmInstall) Version(path string) (string, error) { func (this HelmInstallData) Version(path string) (string, error) {
cmd := helm.HelmCommand{Bin: path} return helm.Version(path)
cmd.New()
return cmd.GetVersion()
} }

View File

@ -1,62 +1 @@
package tool package tool
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/jarcoal/httpmock"
)
func TestToolHelm(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
data := ToolData{Bin: TEST_DEST_DIR,
Name: "helm",
Version: "1.0",
Url: "http://test/%s"}
fileName := filepath.Join(TEST_SRC_DIR, "helm.tgz")
httpRes, _ := os.ReadFile(fileName)
httpmock.RegisterResponder("GET", "http://test/1.0",
httpmock.NewBytesResponder(200, httpRes))
install := HelmInstall{obj: data, tmp: TEST_DEST_DIR}
data2 := install.Get()
assert.Equal(t, data.Name, data2.Name, "TestToolHelm error")
assert.Equal(t, data.Version, data2.Version, "TestToolHelm error")
err := install.Download()
assert.Nilf(t, err, "error message %s", "Download")
dest := filepath.Join(TEST_DEST_DIR, "helm")
assert.FileExists(t, dest, "TestToolHelm Download error")
version, _ := install.Version(dest)
assert.Equal(t, "1.0", version, "TestToolHelm error")
}
func TestToolHelmErr(t *testing.T) {
data := ToolData{Bin: TEST_DEST_DIR,
Name: "test",
Version: "1.0",
Url: "http://test/%s"}
install := HelmInstall{obj: data}
data2 := install.Get()
assert.Equal(t, data.Name, data2.Name, "TestToolHelm error")
err := install.Download()
assert.NotNilf(t, err, "error message %s", "Download")
}

View File

@ -10,15 +10,15 @@ import (
"oc-deploy/kubectl" "oc-deploy/kubectl"
) )
type KubectlInstall struct { type KubecltInstallData struct {
obj ToolData obj ToolData
} }
func (this KubectlInstall) Get() (ToolData) { func (this KubecltInstallData) Get() (ToolData) {
return this.obj return this.obj
} }
func (this KubectlInstall) Download() (error) { func (this KubecltInstallData) Download() (error) {
bin_dir := this.obj.Bin bin_dir := this.obj.Bin
bin := filepath.Join(bin_dir, this.obj.Name) bin := filepath.Join(bin_dir, this.obj.Name)
@ -36,8 +36,6 @@ func (this KubectlInstall) Download() (error) {
} }
/////////////// ///////////////
func (this KubectlInstall) Version(path string) (string, error) { func (this KubecltInstallData) Version(path string) (string, error) {
cmd := kubectl.KubectlCommand{Bin: path} return kubectl.Version(path)
cmd.New()
return cmd.GetVersion()
} }

View File

@ -1,79 +0,0 @@
package tool
import (
"fmt"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/jarcoal/httpmock"
)
func TestToolKubectl(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
data := ToolData{Bin: TEST_DEST_DIR,
Name: "kubectl",
Version: "1.0",
Url: "http://test/%s"}
binContent := `#!/bin/sh
cat <<EOF
{
"clientVersion": {
"major": "1",
"minor": "30",
"gitVersion": "v1.30.3",
"gitCommit": "6fc0a69044f1ac4c13841ec4391224a2df241460",
"gitTreeState": "clean",
"buildDate": "2024-07-16T23:54:40Z",
"goVersion": "go1.22.5",
"compiler": "gc",
"platform": "linux/amd64"
},
"kustomizeVersion": "v5.0.4-0.20230601165947-6ce0bf390ce3"
}
EOF
`
httpmock.RegisterResponder("GET", "http://test/1.0",
httpmock.NewStringResponder(200, binContent))
install := KubectlInstall{obj: data}
data2 := install.Get()
assert.Equal(t, data.Name, data2.Name, "TestToolKubectl error")
assert.Equal(t, data.Version, data2.Version, "TestToolKubectl error")
err := install.Download()
assert.Nilf(t, err, "error message %s", "Download")
dest := filepath.Join(TEST_DEST_DIR, "kubectl")
assert.FileExists(t, dest, "TestToolKubectl Download error")
version, err1 := install.Version(dest)
assert.Equal(t, "v1.30.3", version, "TestToolKubectl error")
fmt.Println(" err1 ", err1)
}
func TestToolKubectlErr(t *testing.T) {
data := ToolData{Bin: TEST_DEST_DIR,
Name: "test",
Version: "1.0",
Url: "http://test/%s"}
install := KubectlInstall{obj: data}
data2 := install.Get()
assert.Equal(t, data.Name, data2.Name, "TestToolKubectl error")
err := install.Download()
assert.NotNilf(t, err, "error message %s", "Download")
}

View File

@ -1,23 +1,24 @@
package tool package tool
import ( import (
"os" "os"
"testing" "testing"
"path/filepath" "path/filepath"
) )
var TEST_DEST_DIR = "../wrk_tool" var TEST_DEST_DIR = "../wrk_tool"
var TEST_SRC_DIR = filepath.Join("../../test", "tool") var TEST_SRC_DIR = filepath.Join("../../test", "tool")
var TEST_BIN_DIR = filepath.Join("../../test", "bin")
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
folderPath := TEST_DEST_DIR folderPath := TEST_DEST_DIR
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.MkdirAll(folderPath, os.ModePerm) os.MkdirAll(folderPath, os.ModePerm)
// call flag.Parse() here if TestMain uses flags // call flag.Parse() here if TestMain uses flags
exitCode := m.Run() exitCode := m.Run()
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.Exit(exitCode) os.Exit(exitCode)
} }

View File

@ -68,9 +68,9 @@ func factory(data ToolData) (Forme, error) {
switch data.Name { switch data.Name {
case "kubectl": case "kubectl":
f = KubectlInstall{obj: data} f = KubecltInstallData{obj: data}
case "helm": case "helm":
f = HelmInstall{obj: data, tmp: "/tmp"} f = HelmInstallData{obj: data, tmp: "/tmp"}
default: default:
return f, fmt.Errorf("Outil Inconnu : %s", data.Name) return f, fmt.Errorf("Outil Inconnu : %s", data.Name)
} }

View File

@ -1,6 +1,7 @@
package utils package utils
import ( import (
// "fmt"
"os" "os"
"io" "io"
"path" "path"
@ -55,7 +56,7 @@ func ExtractTarGz(dest string, gzipStream io.Reader) error {
// return err // return err
// } // }
case tar.TypeReg: case tar.TypeReg:
outName := dest + "/" + path.Base(header.Name) outName := dest + "/" + path.Base( header.Name)
outFile, _ := os.Create(outName) outFile, _ := os.Create(outName)
if err != nil { if err != nil {
return err return err

View File

@ -1,7 +1,8 @@
package utils package utils
// https://pkg.go.dev/github.com/stretchr/testify/assert#Nilf
import ( import (
"os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -25,27 +26,3 @@ func TestDownload(t *testing.T) {
assert.Nilf(t, err, "error message %s", url) assert.Nilf(t, err, "error message %s", url)
assert.FileExists(t, dest, "DownloadFromUrl error") assert.FileExists(t, dest, "DownloadFromUrl error")
} }
func TestExtractTarGz(t *testing.T) {
dest := filepath.Join(TEST_DEST_DIR, "extract")
os.MkdirAll(dest, os.ModePerm)
src := filepath.Join(TEST_SRC_DIR, "fichier1.tgz")
file, _ := os.Open(src)
err := ExtractTarGz(dest, file)
assert.Nilf(t, err, "error message %s", src)
assert.FileExists(t, filepath.Join(dest, "fichier1"), "TestExtractTarGz error")
}
func TestExtractTarGzErr(t *testing.T) {
dest := filepath.Join(TEST_DEST_DIR, "extract")
src := filepath.Join(TEST_SRC_DIR, "fichier1")
file, _ := os.Open(src)
err := ExtractTarGz(dest, file)
assert.NotNilf(t, err, "error message %s", src)
}

View File

@ -1,25 +1,23 @@
package utils package utils
// https://pkg.go.dev/github.com/stretchr/testify/assert
import ( import (
"os" "os"
"testing" "testing"
"path/filepath" "path/filepath"
) )
var TEST_DEST_DIR = "../wrk_utils" var TEST_DEST_DIR = "../wrk_utils"
var TEST_SRC_DIR = filepath.Join("../../test", "utils") var TEST_SRC_DIR = filepath.Join("../../test", "utils")
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
folderPath := TEST_DEST_DIR folderPath := TEST_DEST_DIR
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.MkdirAll(folderPath, os.ModePerm) os.MkdirAll(folderPath, os.ModePerm)
// call flag.Parse() here if TestMain uses flags // call flag.Parse() here if TestMain uses flags
exitCode := m.Run() exitCode := m.Run()
os.RemoveAll(folderPath) os.RemoveAll(folderPath)
os.Exit(exitCode) os.Exit(exitCode)
} }

View File

@ -1,22 +0,0 @@
package utils
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSliceInStringExist(t *testing.T) {
liste := []string{"text1", "text2"}
res := StringInSlice("text1", liste)
assert.Truef(t, res, "error message %s", "text1")
}
func TestSliceInStringNotExist(t *testing.T) {
liste := []string{"text1", "text2"}
res := StringInSlice("text3", liste)
assert.Falsef(t, res, "error message %s", "text3")
}

View File

@ -1,54 +0,0 @@
{
"kind": "Config",
"apiVersion": "v1",
"preferences": {},
"clusters": [
{
"name": "minikube",
"cluster": {
"server": "https://127.0.0.1:38039",
"certificate-authority": "/home/admeju/.minikube/ca.crt",
"extensions": [
{
"name": "cluster_info",
"extension": {
"last-update": "Tue, 10 Sep 2024 10:32:04 UTC",
"provider": "minikube.sigs.k8s.io",
"version": "v1.33.1"
}
}
]
}
}
],
"users": [
{
"name": "minikube",
"user": {
"client-certificate": "/home/admeju/.minikube/profiles/minikube/client.crt",
"client-key": "/home/admeju/.minikube/profiles/minikube/client.key"
}
}
],
"contexts": [
{
"name": "minikube",
"context": {
"cluster": "minikube",
"user": "minikube",
"namespace": "default",
"extensions": [
{
"name": "context_info",
"extension": {
"last-update": "Tue, 10 Sep 2024 10:32:04 UTC",
"provider": "minikube.sigs.k8s.io",
"version": "v1.33.1"
}
}
]
}
}
],
"current-context": "minikube"
}

View File

@ -1,312 +0,0 @@
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"annotations": {
"deployment.kubernetes.io/revision": "1",
"meta.helm.sh/release-name": "phpmyadmin",
"meta.helm.sh/release-namespace": "default"
},
"creationTimestamp": "2024-09-06T12:29:16Z",
"generation": 1,
"labels": {
"app.kubernetes.io/instance": "phpmyadmin",
"app.kubernetes.io/managed-by": "Helm",
"app.kubernetes.io/name": "phpmyadmin",
"app.kubernetes.io/version": "5.2.1",
"helm.sh/chart": "phpmyadmin-17.0.4"
},
"name": "phpmyadmin",
"namespace": "default",
"resourceVersion": "87308",
"uid": "b8518be1-1dd0-45a1-80f3-ddb835a56a5d"
},
"spec": {
"progressDeadlineSeconds": 600,
"replicas": 1,
"revisionHistoryLimit": 10,
"selector": {
"matchLabels": {
"app.kubernetes.io/instance": "phpmyadmin",
"app.kubernetes.io/name": "phpmyadmin"
}
},
"strategy": {
"rollingUpdate": {
"maxSurge": "25%",
"maxUnavailable": "25%"
},
"type": "RollingUpdate"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app.kubernetes.io/instance": "phpmyadmin",
"app.kubernetes.io/managed-by": "Helm",
"app.kubernetes.io/name": "phpmyadmin",
"app.kubernetes.io/version": "5.2.1",
"helm.sh/chart": "phpmyadmin-17.0.4"
}
},
"spec": {
"affinity": {
"podAntiAffinity": {
"preferredDuringSchedulingIgnoredDuringExecution": [
{
"podAffinityTerm": {
"labelSelector": {
"matchLabels": {
"app.kubernetes.io/instance": "phpmyadmin",
"app.kubernetes.io/name": "phpmyadmin"
}
},
"topologyKey": "kubernetes.io/hostname"
},
"weight": 1
}
]
}
},
"automountServiceAccountToken": false,
"containers": [
{
"env": [
{
"name": "BITNAMI_DEBUG",
"value": "false"
},
{
"name": "DATABASE_PORT_NUMBER",
"value": "3306"
},
{
"name": "DATABASE_HOST"
},
{
"name": "PHPMYADMIN_ALLOW_NO_PASSWORD",
"value": "true"
},
{
"name": "PHPMYADMIN_ALLOW_ARBITRARY_SERVER",
"value": "true"
},
{
"name": "DATABASE_ENABLE_SSL",
"value": "no"
}
],
"image": "docker.io/bitnami/phpmyadmin:5.2.1-debian-12-r36",
"imagePullPolicy": "IfNotPresent",
"livenessProbe": {
"failureThreshold": 6,
"initialDelaySeconds": 30,
"periodSeconds": 10,
"successThreshold": 1,
"tcpSocket": {
"port": "http"
},
"timeoutSeconds": 30
},
"name": "phpmyadmin",
"ports": [
{
"containerPort": 8080,
"name": "http",
"protocol": "TCP"
},
{
"containerPort": 8443,
"name": "https",
"protocol": "TCP"
}
],
"readinessProbe": {
"failureThreshold": 6,
"httpGet": {
"path": "/",
"port": "http",
"scheme": "HTTP"
},
"initialDelaySeconds": 30,
"periodSeconds": 10,
"successThreshold": 1,
"timeoutSeconds": 30
},
"resources": {
"limits": {
"cpu": "375m",
"ephemeral-storage": "2Gi",
"memory": "384Mi"
},
"requests": {
"cpu": "250m",
"ephemeral-storage": "50Mi",
"memory": "256Mi"
}
},
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"ALL"
]
},
"privileged": false,
"readOnlyRootFilesystem": true,
"runAsGroup": 1001,
"runAsNonRoot": true,
"runAsUser": 1001,
"seccompProfile": {
"type": "RuntimeDefault"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/opt/bitnami/apache/conf",
"name": "empty-dir",
"subPath": "apache-conf-dir"
},
{
"mountPath": "/opt/bitnami/apache/logs",
"name": "empty-dir",
"subPath": "apache-logs-dir"
},
{
"mountPath": "/opt/bitnami/apache/var/run",
"name": "empty-dir",
"subPath": "apache-tmp-dir"
},
{
"mountPath": "/opt/bitnami/php/etc",
"name": "empty-dir",
"subPath": "php-conf-dir"
},
{
"mountPath": "/opt/bitnami/php/tmp",
"name": "empty-dir",
"subPath": "php-tmp-dir"
},
{
"mountPath": "/opt/bitnami/php/var",
"name": "empty-dir",
"subPath": "php-var-dir"
},
{
"mountPath": "/tmp",
"name": "empty-dir",
"subPath": "tmp-dir"
},
{
"mountPath": "/opt/bitnami/phpmyadmin",
"name": "empty-dir",
"subPath": "app-base-dir"
}
]
}
],
"dnsPolicy": "ClusterFirst",
"hostAliases": [
{
"hostnames": [
"status.localhost"
],
"ip": "127.0.0.1"
}
],
"initContainers": [
{
"args": [
"-ec",
"#!/bin/bash\n\n. /opt/bitnami/scripts/liblog.sh\n. /opt/bitnami/scripts/libfs.sh\n\ninfo \"Copying base dir to empty dir\"\n# In order to not break the application functionality (such as upgrades or plugins) we need\n# to make the base directory writable, so we need to copy it to an empty dir volume\ncp -r --preserve=mode /opt/bitnami/phpmyadmin /emptydir/app-base-dir\n\ninfo \"Copying symlinks to stdout/stderr\"\n# We copy the logs folder because it has symlinks to stdout and stderr\nif ! is_dir_empty /opt/bitnami/apache/logs; then\n cp -r /opt/bitnami/apache/logs /emptydir/apache-logs-dir\nfi\ninfo \"Copying php var directory\"\n# PhpMyAdmin will fail to start if the php var folder is not populated\nif ! is_dir_empty /opt/bitnami/php/var; then\n cp -r /opt/bitnami/php/var /emptydir/php-var-dir\nfi\ninfo \"Copy operation completed\"\n"
],
"command": [
"/bin/bash"
],
"image": "docker.io/bitnami/phpmyadmin:5.2.1-debian-12-r36",
"imagePullPolicy": "IfNotPresent",
"name": "prepare-base-dir",
"resources": {
"limits": {
"cpu": "375m",
"ephemeral-storage": "2Gi",
"memory": "384Mi"
},
"requests": {
"cpu": "250m",
"ephemeral-storage": "50Mi",
"memory": "256Mi"
}
},
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"ALL"
]
},
"privileged": false,
"readOnlyRootFilesystem": true,
"runAsGroup": 1001,
"runAsNonRoot": true,
"runAsUser": 1001,
"seccompProfile": {
"type": "RuntimeDefault"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/emptydir",
"name": "empty-dir"
}
]
}
],
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {
"fsGroup": 1001,
"fsGroupChangePolicy": "Always"
},
"serviceAccount": "phpmyadmin",
"serviceAccountName": "phpmyadmin",
"terminationGracePeriodSeconds": 30,
"volumes": [
{
"emptyDir": {},
"name": "empty-dir"
}
]
}
}
},
"status": {
"availableReplicas": 1,
"conditions": [
{
"lastTransitionTime": "2024-09-06T12:29:17Z",
"lastUpdateTime": "2024-09-06T12:30:08Z",
"message": "ReplicaSet \"phpmyadmin-7f7bbf7bd7\" has successfully progressed.",
"reason": "NewReplicaSetAvailable",
"status": "True",
"type": "Progressing"
},
{
"lastTransitionTime": "2024-09-09T11:54:00Z",
"lastUpdateTime": "2024-09-09T11:54:00Z",
"message": "Deployment has minimum availability.",
"reason": "MinimumReplicasAvailable",
"status": "True",
"type": "Available"
}
],
"observedGeneration": 1,
"readyReplicas": 1,
"replicas": 1,
"updatedReplicas": 1
}
}

View File

@ -1,332 +0,0 @@
{
"apiVersion": "apps/v1",
"kind": "StatefulSet",
"metadata": {
"annotations": {
"meta.helm.sh/release-name": "wordpress",
"meta.helm.sh/release-namespace": "default"
},
"creationTimestamp": "2024-09-09T12:29:35Z",
"generation": 1,
"labels": {
"app.kubernetes.io/component": "primary",
"app.kubernetes.io/instance": "wordpress",
"app.kubernetes.io/managed-by": "Helm",
"app.kubernetes.io/name": "mariadb",
"app.kubernetes.io/version": "11.4.2",
"helm.sh/chart": "mariadb-19.0.3"
},
"name": "wordpress-mariadb",
"namespace": "default",
"resourceVersion": "92784",
"uid": "82197de7-3b4f-4225-b1a2-58e8ac0fad44"
},
"spec": {
"persistentVolumeClaimRetentionPolicy": {
"whenDeleted": "Retain",
"whenScaled": "Retain"
},
"podManagementPolicy": "OrderedReady",
"replicas": 1,
"revisionHistoryLimit": 10,
"selector": {
"matchLabels": {
"app.kubernetes.io/component": "primary",
"app.kubernetes.io/instance": "wordpress",
"app.kubernetes.io/name": "mariadb"
}
},
"serviceName": "wordpress-mariadb",
"template": {
"metadata": {
"annotations": {
"checksum/configuration": "0fdca6295cb246435ed7edb5801c3445ca97c878dcce94b652f2fec128efd78a"
},
"creationTimestamp": null,
"labels": {
"app.kubernetes.io/component": "primary",
"app.kubernetes.io/instance": "wordpress",
"app.kubernetes.io/managed-by": "Helm",
"app.kubernetes.io/name": "mariadb",
"app.kubernetes.io/version": "11.4.2",
"helm.sh/chart": "mariadb-19.0.3"
}
},
"spec": {
"affinity": {
"podAntiAffinity": {
"preferredDuringSchedulingIgnoredDuringExecution": [
{
"podAffinityTerm": {
"labelSelector": {
"matchLabels": {
"app.kubernetes.io/component": "primary",
"app.kubernetes.io/instance": "wordpress",
"app.kubernetes.io/name": "mariadb"
}
},
"topologyKey": "kubernetes.io/hostname"
},
"weight": 1
}
]
}
},
"automountServiceAccountToken": false,
"containers": [
{
"env": [
{
"name": "BITNAMI_DEBUG",
"value": "false"
},
{
"name": "MARIADB_ROOT_PASSWORD",
"valueFrom": {
"secretKeyRef": {
"key": "mariadb-root-password",
"name": "wordpress-mariadb"
}
}
},
{
"name": "MARIADB_USER",
"value": "bn_wordpress"
},
{
"name": "MARIADB_PASSWORD",
"valueFrom": {
"secretKeyRef": {
"key": "mariadb-password",
"name": "wordpress-mariadb"
}
}
},
{
"name": "MARIADB_DATABASE",
"value": "bitnami_wordpress"
}
],
"image": "docker.io/bitnami/mariadb:11.4.2-debian-12-r2",
"imagePullPolicy": "IfNotPresent",
"livenessProbe": {
"exec": {
"command": [
"/bin/bash",
"-ec",
"password_aux=\"${MARIADB_ROOT_PASSWORD:-}\"\nif [[ -f \"${MARIADB_ROOT_PASSWORD_FILE:-}\" ]]; then\n password_aux=$(cat \"$MARIADB_ROOT_PASSWORD_FILE\")\nfi\nmysqladmin status -uroot -p\"${password_aux}\"\n"
]
},
"failureThreshold": 3,
"initialDelaySeconds": 120,
"periodSeconds": 10,
"successThreshold": 1,
"timeoutSeconds": 1
},
"name": "mariadb",
"ports": [
{
"containerPort": 3306,
"name": "mysql",
"protocol": "TCP"
}
],
"readinessProbe": {
"exec": {
"command": [
"/bin/bash",
"-ec",
"password_aux=\"${MARIADB_ROOT_PASSWORD:-}\"\nif [[ -f \"${MARIADB_ROOT_PASSWORD_FILE:-}\" ]]; then\n password_aux=$(cat \"$MARIADB_ROOT_PASSWORD_FILE\")\nfi\nmysqladmin ping -uroot -p\"${password_aux}\"\n"
]
},
"failureThreshold": 3,
"initialDelaySeconds": 30,
"periodSeconds": 10,
"successThreshold": 1,
"timeoutSeconds": 1
},
"resources": {
"limits": {
"cpu": "375m",
"ephemeral-storage": "2Gi",
"memory": "384Mi"
},
"requests": {
"cpu": "250m",
"ephemeral-storage": "50Mi",
"memory": "256Mi"
}
},
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"ALL"
]
},
"privileged": false,
"readOnlyRootFilesystem": true,
"runAsGroup": 1001,
"runAsNonRoot": true,
"runAsUser": 1001,
"seLinuxOptions": {},
"seccompProfile": {
"type": "RuntimeDefault"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/bitnami/mariadb",
"name": "data"
},
{
"mountPath": "/opt/bitnami/mariadb/conf/my.cnf",
"name": "config",
"subPath": "my.cnf"
},
{
"mountPath": "/tmp",
"name": "empty-dir",
"subPath": "tmp-dir"
},
{
"mountPath": "/opt/bitnami/mariadb/conf",
"name": "empty-dir",
"subPath": "app-conf-dir"
},
{
"mountPath": "/opt/bitnami/mariadb/tmp",
"name": "empty-dir",
"subPath": "app-tmp-dir"
},
{
"mountPath": "/opt/bitnami/mariadb/logs",
"name": "empty-dir",
"subPath": "app-logs-dir"
}
]
}
],
"dnsPolicy": "ClusterFirst",
"initContainers": [
{
"args": [
"-ec",
"#!/bin/bash\n\n. /opt/bitnami/scripts/libfs.sh\n# We copy the logs folder because it has symlinks to stdout and stderr\nif ! is_dir_empty /opt/bitnami/mariadb/logs; then\n cp -r /opt/bitnami/mariadb/logs /emptydir/app-logs-dir\nfi\n"
],
"command": [
"/bin/bash"
],
"image": "docker.io/bitnami/mariadb:11.4.2-debian-12-r2",
"imagePullPolicy": "IfNotPresent",
"name": "preserve-logs-symlinks",
"resources": {
"limits": {
"cpu": "375m",
"ephemeral-storage": "2Gi",
"memory": "384Mi"
},
"requests": {
"cpu": "250m",
"ephemeral-storage": "50Mi",
"memory": "256Mi"
}
},
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"ALL"
]
},
"privileged": false,
"readOnlyRootFilesystem": true,
"runAsGroup": 1001,
"runAsNonRoot": true,
"runAsUser": 1001,
"seLinuxOptions": {},
"seccompProfile": {
"type": "RuntimeDefault"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/emptydir",
"name": "empty-dir"
}
]
}
],
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {
"fsGroup": 1001,
"fsGroupChangePolicy": "Always"
},
"serviceAccount": "wordpress-mariadb",
"serviceAccountName": "wordpress-mariadb",
"terminationGracePeriodSeconds": 30,
"volumes": [
{
"emptyDir": {},
"name": "empty-dir"
},
{
"configMap": {
"defaultMode": 420,
"name": "wordpress-mariadb"
},
"name": "config"
}
]
}
},
"updateStrategy": {
"type": "RollingUpdate"
},
"volumeClaimTemplates": [
{
"apiVersion": "v1",
"kind": "PersistentVolumeClaim",
"metadata": {
"creationTimestamp": null,
"labels": {
"app.kubernetes.io/component": "primary",
"app.kubernetes.io/instance": "wordpress",
"app.kubernetes.io/name": "mariadb"
},
"name": "data"
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "8Gi"
}
},
"volumeMode": "Filesystem"
},
"status": {
"phase": "Pending"
}
}
]
},
"status": {
"availableReplicas": 1,
"collisionCount": 0,
"currentReplicas": 1,
"currentRevision": "wordpress-mariadb-599b74c5bc",
"observedGeneration": 1,
"readyReplicas": 1,
"replicas": 1,
"updateRevision": "wordpress-mariadb-599b74c5bc",
"updatedReplicas": 1
}
}

Binary file not shown.

Binary file not shown.