-
Notifications
You must be signed in to change notification settings - Fork 148
/
utils.go
147 lines (130 loc) · 5.14 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright 2019 The Kanister Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package app
import (
"context"
"fmt"
"os"
"github.com/kanisterio/kanister/pkg/aws/ec2"
"github.com/kanisterio/kanister/pkg/aws/rds"
"github.com/pkg/errors"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/rand"
)
const (
dbTemplateURI = "https://raw.githubusercontent.com/openshift/origin/%s/examples/db-templates/%s-%s-template.json"
// PersistentStorage can be used if we want to deploy database with Persistent Volumes
PersistentStorage storage = "persistent" //nolint:varcheck
// EphemeralStorage can be used if we don't want to deploy database with Persistent
EphemeralStorage storage = "ephemeral"
// TemplateVersionOCP3_11 stores version of db template 3.11
TemplateVersionOCP3_11 DBTemplate = "release-3.11"
// TemplateVersionOCP4_4 stores version of db template 4.4
TemplateVersionOCP4_4 DBTemplate = "release-4.4"
// TemplateVersionOCP4_5 stores version of db template 4.5
TemplateVersionOCP4_5 DBTemplate = "release-4.5"
// TemplateVersionOCP4_10 stores version of db template 4.10
TemplateVersionOCP4_10 DBTemplate = "release-4.10"
// TemplateVersionOCP4_11 stores version of db template 4.11
TemplateVersionOCP4_11 DBTemplate = "release-4.11"
// TemplateVersionOCP4_12 stores version of db template 4.12
TemplateVersionOCP4_12 DBTemplate = "release-4.12"
// TemplateVersionOCP4_13 stores version of db template 4.13
TemplateVersionOCP4_13 DBTemplate = "release-4.13"
// TemplateVersionOCP4_14 stores version of db template 4.14
TemplateVersionOCP4_14 DBTemplate = "release-4.14"
)
type storage string
// DBTemplate is type of openshift db template version
type DBTemplate string
// appendRandString, appends a random string to the passed string value
func appendRandString(name string) string {
return fmt.Sprintf("%s-%s", name, rand.String(5))
}
// getOpenShiftDBTemplate accepts the application name and returns the
// db template for that application
// https://github.com/openshift/origin/tree/master/examples/db-templates
func getOpenShiftDBTemplate(appName string, templateVersion DBTemplate, storageType storage) string {
return fmt.Sprintf(dbTemplateURI, templateVersion, appName, storageType)
}
// getLabelOfApp returns label of the passed application this label can be
// used to delete all the resources that were created while deploying this application
func getLabelOfApp(appName string, storageType storage) string {
return fmt.Sprintf("app=%s-%s", appName, storageType)
}
// bastionDebugWorkloadSpec creates Deployment Resource Manifest from which RDS database queries can be executed
func bastionDebugWorkloadSpec(ctx context.Context, name string, image string, namespace string) *appsv1.Deployment {
return &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"app": name}},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": name,
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: name,
Image: image,
Command: []string{"sh", "-c", "tail -f /dev/null"},
},
},
},
},
},
}
}
// vpcIdForRDSInstance gets the VPC ID from env var `VPC_ID` if set, or from the default VPC
func vpcIDForRDSInstance(ctx context.Context, ec2Cli *ec2.EC2) (string, error) {
vpcID := os.Getenv("VPC_ID")
// VPCId is not provided, use Default VPC
if vpcID != "" {
return vpcID, nil
}
defaultVpc, err := ec2Cli.DescribeDefaultVpc(ctx)
if err != nil {
return "", err
}
if len(defaultVpc.Vpcs) == 0 {
return "", fmt.Errorf("No default VPC found")
}
return *defaultVpc.Vpcs[0].VpcId, nil
}
// dbSubnetGroup gets the DBSubnetGroup based on VPC ID
func dbSubnetGroup(ctx context.Context, ec2Cli *ec2.EC2, rdsCli *rds.RDS, vpcID, name, subnetGroupDescription string) (string, error) {
// describe subnets in the VPC
resp, err := ec2Cli.DescribeSubnets(ctx, vpcID)
if err != nil {
return "", errors.Wrapf(err, "Failed to describe subnets")
}
// Extract subnet IDs from the response
var subnetIDs []string
for _, subnet := range resp.Subnets {
subnetIDs = append(subnetIDs, *subnet.SubnetId)
}
// create a subnetgroup with subnets in the VPC
subnetGroup, err := rdsCli.CreateDBSubnetGroup(ctx, fmt.Sprintf("%s-subnetgroup", name), subnetGroupDescription, subnetIDs)
if err != nil {
return "", errors.Wrapf(err, "Failed to create subnet group")
}
return *subnetGroup.DBSubnetGroup.DBSubnetGroupName, nil
}