Skip to content

Commit 8e16661

Browse files
Fix get schema of multiple databases (#1416)
Co-authored-by: YourTechBud <[email protected]>
1 parent e7b0b04 commit 8e16661

File tree

12 files changed

+227
-23
lines changed

12 files changed

+227
-23
lines changed

gateway/modules/schema/operations.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ func (s *Schema) GetSchemaForDB(ctx context.Context, dbAlias, col, format string
2828
}
2929
} else if dbAlias != "*" {
3030
for _, dbSchema := range s.dbSchemas {
31-
if err := s.getSchemaResponse(ctx, format, dbAlias, dbSchema.Table, false, alreadyAddedTables, &schemaResponse); err != nil {
32-
return nil, err
31+
if dbAlias == dbSchema.DbAlias {
32+
if err := s.getSchemaResponse(ctx, format, dbAlias, dbSchema.Table, false, alreadyAddedTables, &schemaResponse); err != nil {
33+
return nil, err
34+
}
3335
}
3436
}
3537
} else {

space-cli/cmd/model/service.go

+42-10
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ package model
22

33
// Service describes a service's configurations
44
type Service struct {
5-
ID string `json:"id,omitempty" yaml:"id,omitempty"`
6-
Name string `json:"name,omitempty" yaml:"name,omitempty"`
7-
ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"`
8-
Version string `json:"version,omitempty" yaml:"version,omitempty"`
9-
Scale ScaleConfig `json:"scale" yaml:"scale"`
10-
Labels map[string]string `json:"labels" yaml:"labels"`
11-
Tasks []Task `json:"tasks" yaml:"tasks"`
12-
Affinity []Affinity `json:"affinity" yaml:"affinity"`
13-
Whitelist []Whitelist `json:"whitelists" yaml:"whitelists"`
14-
Upstreams []Upstream `json:"upstreams" yaml:"upstreams"`
5+
ID string `json:"id,omitempty" yaml:"id,omitempty"`
6+
Name string `json:"name,omitempty" yaml:"name,omitempty"`
7+
ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"`
8+
Version string `json:"version,omitempty" yaml:"version,omitempty"`
9+
Scale *ScaleConfig `json:"scale,omitempty" yaml:"scale,omitempty"`
10+
AutoScale *AutoScaleConfig `json:"autoScale,omitempty" yaml:"autoScale,omitempty"`
11+
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
12+
Tasks []Task `json:"tasks" yaml:"tasks"`
13+
Affinity []Affinity `json:"affinity,omitempty" yaml:"affinity,omitempty"`
14+
Whitelist []Whitelist `json:"whitelists" yaml:"whitelists"`
15+
Upstreams []Upstream `json:"upstreams" yaml:"upstreams"`
16+
StatsInclusionPrefixes string `json:"statsInclusionPrefixes" yaml:"statsInclusionPrefixes"`
1517
}
1618

1719
// ScaleConfig describes the config used to scale a service
@@ -23,6 +25,36 @@ type ScaleConfig struct {
2325
Mode string `json:"mode" yaml:"mode"`
2426
}
2527

28+
// AutoScaleConfig describes the config used to scale a service
29+
type AutoScaleConfig struct {
30+
PollingInterval int32 `json:"pollingInterval" yaml:"pollingInterval"` // Default 15 (in seconds)
31+
CoolDownInterval int32 `json:"coolDownInterval" yaml:"coolDownInterval"` // Default 120 (in seconds)
32+
33+
MinReplicas int32 `json:"minReplicas" yaml:"minReplicas"` // Default 1
34+
MaxReplicas int32 `json:"maxReplicas" yaml:"maxReplicas"` // Default 100
35+
36+
Triggers []AutoScaleTrigger `json:"triggers,omitempty" yaml:"triggers,omitempty"`
37+
}
38+
39+
// AutoScaleTrigger describes the config of a scaler
40+
type AutoScaleTrigger struct {
41+
Name string `json:"name" yaml:"name"`
42+
Type string `json:"type" yaml:"type"`
43+
MetaData map[string]string `json:"metadata" yaml:"metadata"`
44+
AuthenticatedRef *AutoScaleAuthRef `json:"authRef" yaml:"authRef"` // Authentication ref is optional
45+
}
46+
47+
// AutoScaleAuthRef describes the authentication reference for a scaler
48+
type AutoScaleAuthRef struct {
49+
SecretMapping []AutoScaleAuthRefMapping `json:"secretMapping" yaml:"secretMapping"`
50+
}
51+
52+
// AutoScaleAuthRefMapping describes the mapping between the keys of the secret and parameters of the scaler
53+
type AutoScaleAuthRefMapping struct {
54+
Parameter string `json:"param" yaml:"param"`
55+
Key string `json:"key" yaml:"key"`
56+
}
57+
2658
// Task describes the configuration of a task
2759
type Task struct {
2860
ID string `json:"id" yaml:"id"`

space-cli/cmd/modules/addons/database.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func addDatabase(chartReleaseName, dbType, setValuesFlag, valuesYamlFile, chartL
8787

8888
case <-ticker.C:
8989
utils.LogInfo("Database has been provisioned on kubernetes cluster")
90-
utils.LogInfo("But it is taking to much time to start, check if you have enough resource on the cluster or")
90+
utils.LogInfo("But it is taking to much time to start, check if you have enough resource on the cluster")
9191
return nil
9292
}
9393
}

space-cli/cmd/modules/operations/commands.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ func Commands() []*cobra.Command {
130130
RunE: actionList,
131131
}
132132

133+
var inspect = &cobra.Command{
134+
Use: "inspect",
135+
Short: "View applied config file for space cloud cluster",
136+
PreRun: nil,
137+
RunE: actionInspect,
138+
}
139+
133140
var apply = &cobra.Command{
134141
Use: "apply",
135142
Short: "Applies a config file or directory",
@@ -179,7 +186,7 @@ func Commands() []*cobra.Command {
179186
if err := stop.RegisterFlagCompletionFunc("cluster-name", clusterNameAutoComplete); err != nil {
180187
utils.LogDebug("Unable to provide suggetion for flag ('project')", nil)
181188
}
182-
return []*cobra.Command{setup, list, update, destroy, apply, start, stop}
189+
return []*cobra.Command{setup, list, update, inspect, destroy, apply, start, stop}
183190

184191
}
185192

@@ -199,6 +206,14 @@ func actionSetup(cmd *cobra.Command, args []string) error {
199206
return Setup(setValue, valuesYamlFile, chartDir)
200207
}
201208

209+
func actionInspect(cmd *cobra.Command, args []string) error {
210+
clusterID := ""
211+
if len(args) == 1 {
212+
clusterID = args[0]
213+
}
214+
return Inspect(clusterID)
215+
}
216+
202217
func actionList(cmd *cobra.Command, args []string) error {
203218
return List()
204219
}

space-cli/cmd/modules/operations/destroy.go

+63-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
package operations
22

33
import (
4+
"context"
45
"fmt"
6+
"log"
7+
"os"
8+
"time"
59

610
"github.com/AlecAivazis/survey/v2"
11+
"helm.sh/helm/v3/pkg/action"
12+
"helm.sh/helm/v3/pkg/cli"
13+
v1 "k8s.io/api/core/v1"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
715

816
"github.com/spaceuptech/space-cloud/space-cli/cmd/model"
917
"github.com/spaceuptech/space-cloud/space-cli/cmd/modules/project"
@@ -43,8 +51,7 @@ func Destroy() error {
4351
if !ok {
4452
continue
4553
}
46-
47-
if err := project.DeleteProject(projectID); err != nil {
54+
if err := deleteProject(projectID); err != nil {
4855
return err
4956
}
5057
}
@@ -59,3 +66,57 @@ func Destroy() error {
5966
utils.LogInfo("Space cloud cluster has been destroyed successfully 😢")
6067
return nil
6168
}
69+
70+
func deleteProject(projectID string) error {
71+
// delete project from kubernetes
72+
if err := project.DeleteProject(projectID); err != nil {
73+
return err
74+
}
75+
76+
settings := cli.New()
77+
actionConfig := new(action.Configuration)
78+
if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
79+
return err
80+
}
81+
82+
kubeClint, err := actionConfig.KubernetesClientSet()
83+
if err != nil {
84+
return err
85+
}
86+
87+
// wait for project to get deleted in kubernetes
88+
ticker := time.NewTicker(10 * time.Second)
89+
defer ticker.Stop()
90+
maxCount := 18 // wait for 3 minutes, 10 seconds * 18 = 180 seconds
91+
counter := 0
92+
utils.LogInfo(fmt.Sprintf("Waiting for project (%s) to get deleted, this might take up to 3 minutes", projectID))
93+
94+
for range ticker.C {
95+
namespacesList, err := kubeClint.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{LabelSelector: "app.kubernetes.io/managed-by=space-cloud"})
96+
if err != nil {
97+
return err
98+
}
99+
doesExists := false
100+
var ns v1.Namespace
101+
for _, namespace := range namespacesList.Items {
102+
if namespace.Name == projectID {
103+
doesExists = true
104+
ns = namespace
105+
break
106+
}
107+
}
108+
if !doesExists {
109+
utils.LogInfo(fmt.Sprintf("Successfully deleted project (%s)", projectID))
110+
return nil
111+
}
112+
113+
counter++
114+
if counter == maxCount {
115+
utils.LogInfo(fmt.Sprintf("Deleting project (%s) is taking to much time, skipping project (%s)", projectID, projectID))
116+
return nil
117+
}
118+
119+
utils.LogInfo(fmt.Sprintf("Project deletion status (%s)", ns.Status.Phase))
120+
}
121+
return nil
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package operations
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ghodss/yaml"
7+
8+
"github.com/spaceuptech/space-cloud/space-cli/cmd/model"
9+
"github.com/spaceuptech/space-cloud/space-cli/cmd/utils"
10+
)
11+
12+
// Inspect prints values file used for setting up cluster
13+
func Inspect(clusterID string) error {
14+
if clusterID == "" {
15+
charList, err := utils.HelmList(model.HelmSpaceCloudNamespace)
16+
if err != nil {
17+
return err
18+
}
19+
if len(charList) < 1 {
20+
utils.LogInfo("space cloud cluster not found, setup a new cluster using the setup command")
21+
return nil
22+
}
23+
clusterID = charList[0].Name
24+
}
25+
26+
chartInfo, err := utils.HelmGet(clusterID)
27+
if err != nil {
28+
return err
29+
}
30+
31+
data, err := yaml.Marshal(chartInfo.Config)
32+
if err != nil {
33+
return err
34+
}
35+
fmt.Println(string(data))
36+
return nil
37+
}

space-cli/cmd/modules/operations/update.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ func Update(setValuesFlag, valuesYamlFile, chartLocation string) error {
2222
return nil
2323
}
2424

25+
clusterID := charList[0].Name
2526
isOk := false
2627
prompt := &survey.Confirm{
27-
Message: fmt.Sprintf("Space cloud cluster with id (%s) will be upgraded, Do you want to continue", charList[0].Name),
28+
Message: fmt.Sprintf("Space cloud cluster with id (%s) will be upgraded, Do you want to continue", clusterID),
2829
}
2930
if err := survey.AskOne(prompt, &isOk); err != nil {
3031
return err
@@ -44,7 +45,14 @@ func Update(setValuesFlag, valuesYamlFile, chartLocation string) error {
4445
return fmt.Errorf("you cannot set a new cluster id (%s) while upgrading an existing cluster, revmove the value & try again", value)
4546
}
4647

47-
_, err = utils.HelmUpgrade(charList[0].Name, chartLocation, model.HelmSpaceCloudChartDownloadURL, "", valuesFileObj)
48+
// set clusterId of existing cluster
49+
charInfo, err := utils.HelmGet(clusterID)
50+
if err != nil {
51+
return err
52+
}
53+
valuesFileObj["clusterId"] = charInfo.Config["clusterId"]
54+
55+
_, err = utils.HelmUpgrade(clusterID, chartLocation, model.HelmSpaceCloudChartDownloadURL, "", valuesFileObj)
4856
if err != nil {
4957
return err
5058
}

space-cli/cmd/modules/services/generate.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,22 @@ func GenerateService(projectID, dockerImage string) (*model.SpecObject, error) {
108108
"version": serviceVersion,
109109
},
110110
Spec: &model.Service{
111+
StatsInclusionPrefixes: "http.inbound,cluster_manager,listener_manager",
112+
AutoScale: &model.AutoScaleConfig{
113+
PollingInterval: int32(15),
114+
CoolDownInterval: int32(120),
115+
MinReplicas: int32(replicaMin),
116+
MaxReplicas: int32(replicaMax),
117+
Triggers: []model.AutoScaleTrigger{
118+
{
119+
Name: "Request per second",
120+
Type: "requests-per-second",
121+
MetaData: map[string]string{"target": "50"},
122+
AuthenticatedRef: nil,
123+
},
124+
},
125+
},
111126
Labels: map[string]string{},
112-
Scale: model.ScaleConfig{Replicas: int32(replicaMin), MinReplicas: int32(replicaMin), MaxReplicas: int32(replicaMax), Concurrency: 50, Mode: "parallel"},
113127
Tasks: []model.Task{
114128
{
115129
ID: serviceID,

space-cli/cmd/modules/services/generate_test.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
"github.com/AlecAivazis/survey/v2"
10+
"github.com/go-test/deep"
1011
"github.com/stretchr/testify/mock"
1112

1213
"github.com/spaceuptech/space-cloud/space-cli/cmd/model"
@@ -443,8 +444,22 @@ func TestGenerateService(t *testing.T) {
443444
"version": "v1",
444445
},
445446
Spec: &model.Service{
446-
Labels: map[string]string{},
447-
Scale: model.ScaleConfig{Replicas: int32(10), MinReplicas: int32(10), MaxReplicas: int32(90), Concurrency: 50, Mode: "parallel"},
447+
Labels: map[string]string{},
448+
StatsInclusionPrefixes: "http.inbound,cluster_manager,listener_manager",
449+
AutoScale: &model.AutoScaleConfig{
450+
PollingInterval: int32(15),
451+
CoolDownInterval: int32(120),
452+
MinReplicas: int32(10),
453+
MaxReplicas: int32(90),
454+
Triggers: []model.AutoScaleTrigger{
455+
{
456+
Name: "Request per second",
457+
Type: "requests-per-second",
458+
MetaData: map[string]string{"target": "50"},
459+
AuthenticatedRef: nil,
460+
},
461+
},
462+
},
448463
Tasks: []model.Task{
449464
{
450465
ID: "service",
@@ -483,11 +498,12 @@ func TestGenerateService(t *testing.T) {
483498

484499
got, err := GenerateService(tt.args.projectID, tt.args.dockerImage)
485500
if (err != nil) != tt.wantErr {
501+
486502
t.Errorf("GenerateService() error = %v, wantErr %v", err, tt.wantErr)
487503
return
488504
}
489-
if !reflect.DeepEqual(got, tt.want) {
490-
t.Errorf("GenerateService() = %v, want %v", got, tt.want)
505+
if arr := deep.Equal(got, tt.want); len(arr) != 0 {
506+
t.Errorf("GenerateService() = %v", arr)
491507
}
492508

493509
mockSurvey.AssertExpectations(t)

space-cli/cmd/utils/helm.go

+16
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ func HelmUninstall(releaseName string) error {
5656
return nil
5757
}
5858

59+
// HelmGet gets chart info
60+
func HelmGet(releaseName string) (*release.Release, error) {
61+
settings := cli.New()
62+
actionConfig := new(action.Configuration)
63+
if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
64+
return nil, err
65+
}
66+
67+
iCli := action.NewGet(actionConfig)
68+
info, err := iCli.Run(releaseName)
69+
if err != nil {
70+
return nil, err
71+
}
72+
return info, nil
73+
}
74+
5975
// HelmList uninstall helm chart
6076
func HelmList(filterRegex string) ([]*release.Release, error) {
6177
settings := cli.New()

space-cli/go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/briandowns/spinner v1.9.0
88
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce
99
github.com/ghodss/yaml v1.0.0
10+
github.com/go-test/deep v1.0.7
1011
github.com/google/go-cmp v0.4.1
1112
github.com/google/uuid v1.1.1
1213
github.com/olekukonko/tablewriter v0.0.4

space-cli/go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZp
286286
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
287287
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
288288
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
289+
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
290+
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
289291
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
290292
github.com/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8=
291293
github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w=

0 commit comments

Comments
 (0)