Skip to content

Commit 9ec5714

Browse files
committed
chore(addons: add ydb)
1 parent 8d67e72 commit 9ec5714

36 files changed

Lines changed: 3918 additions & 1 deletion

addons/index.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,7 @@ entries:
6262
description: "ClickHouse is the fastest and most resource efficient open-source database for real-time apps and analytics."
6363
kvrocks:
6464
- version: 2.8
65-
description: "Apache Kvrocks is a distributed key value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol."
65+
description: "Apache Kvrocks is a distributed key value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol."
66+
yugabytedb:
67+
- version: 2024
68+
description: "YugabyteDB is a high-performance distributed SQL database for powering global, internet-scale applications. "
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: v2
2+
name: yugabyte
3+
version: 2024.1.3
4+
appVersion: 2024.1.3.0-b105
5+
kubeVersion: ">=1.17.0-0"
6+
home: https://www.yugabyte.com
7+
description: YugabyteDB is the high-performance distributed SQL database for building global, internet-scale apps.
8+
icon: https://avatars0.githubusercontent.com/u/17074854?s=200&v=4
9+
sources:
10+
- https://github.com/yugabyte/yugabyte-db
11+
maintainers:
12+
- name: Sanketh Indarapu
13+
email: sanketh@yugabyte.com
14+
- name: Govardhan Reddy Jalla
15+
email: gjalla@yugabyte.com
16+
annotations:
17+
charts.openshift.io/name: yugabyte
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
YugabyteDB can be deployed in various Kubernetes configurations (including single zone, multi-zone and multi-cluster) using this Helm Chart. Detailed documentation is available in [YugabyteDB Docs for Kubernetes Deployments](https://docs.yugabyte.com/latest/deploy/kubernetes/).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This chart bootstraps an RF3 YugabyteDB version 2024.1.3.0-b105 cluster using the Helm Package Manager.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
serviceEndpoints:
2+
- name: "yb-master-service"
3+
type: LoadBalancer
4+
app: "yb-master"
5+
ports:
6+
ui: "7000"
7+
8+
- name: "yb-tserver-service"
9+
type: LoadBalancer
10+
app: "yb-tserver"
11+
ports:
12+
yql-port: "9042"
13+
yedis-port: "6379"
14+
ysql-port: "5433"
15+
16+
- name: "yugabyted-ui-service"
17+
type: LoadBalancer
18+
app: "yb-master"
19+
sessionAffinity: ClientIP
20+
ports:
21+
yugabyted-ui: "15433"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
serviceEndpoints:
2+
- name: "yb-master-ui"
3+
type: LoadBalancer
4+
app: "yb-master"
5+
ports:
6+
ui: "7000"
7+
8+
- name: "yql-service"
9+
type: LoadBalancer
10+
app: "yb-tserver"
11+
ports:
12+
yql-port: "9042"
13+
14+
- name: "yedis-service"
15+
type: LoadBalancer
16+
app: "yb-tserver"
17+
ports:
18+
yedis-port: "6379"
19+
20+
- name: "ysql-service"
21+
type: LoadBalancer
22+
app: "yb-tserver"
23+
ports:
24+
ysql-port: "5433"
25+
26+
- name: "yugabyted-ui-service"
27+
type: LoadBalancer
28+
app: "yb-master"
29+
sessionAffinity: ClientIP
30+
ports:
31+
yugabyted-ui: "15433"
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
#!/usr/bin/python
2+
# Copyright (c) YugaByte, Inc.
3+
4+
# This script would generate a kubeconfig for the given servie account
5+
# by fetching the cluster information and also add the service account
6+
# token for the authentication purpose.
7+
8+
import argparse
9+
from subprocess import check_output
10+
from sys import exit
11+
import json
12+
import base64
13+
import tempfile
14+
import time
15+
import os.path
16+
17+
18+
def run_command(command_args, namespace=None, as_json=True, log_command=True):
19+
command = ["kubectl"]
20+
if namespace:
21+
command.extend(["--namespace", namespace])
22+
command.extend(command_args)
23+
if as_json:
24+
command.extend(["-o", "json"])
25+
if log_command:
26+
print("Running command: {}".format(" ".join(command)))
27+
output = check_output(command)
28+
if as_json:
29+
return json.loads(output)
30+
else:
31+
return output.decode("utf8")
32+
33+
34+
def create_sa_token_secret(directory, sa_name, namespace):
35+
"""Creates a service account token secret for sa_name in
36+
namespace. Returns the name of the secret created.
37+
38+
Ref:
39+
https://k8s.io/docs/concepts/configuration/secret/#service-account-token-secrets
40+
41+
"""
42+
token_secret = {
43+
"apiVersion": "v1",
44+
"data": {
45+
"do-not-delete-used-for-yugabyte-anywhere": "MQ==",
46+
},
47+
"kind": "Secret",
48+
"metadata": {
49+
"annotations": {
50+
"kubernetes.io/service-account.name": sa_name,
51+
},
52+
"name": sa_name,
53+
},
54+
"type": "kubernetes.io/service-account-token",
55+
}
56+
token_secret_file_name = os.path.join(directory, "token_secret.yaml")
57+
with open(token_secret_file_name, "w") as token_secret_file:
58+
json.dump(token_secret, token_secret_file)
59+
run_command(["apply", "-f", token_secret_file_name], namespace)
60+
return sa_name
61+
62+
63+
def get_secret_data(secret, namespace):
64+
"""Returns the secret in JSON format if it has ca.crt and token in
65+
it, else returns None. It retries 3 times with 1 second timeout
66+
for the secret to be populated with this data.
67+
68+
"""
69+
secret_data = None
70+
num_retries = 5
71+
timeout = 2
72+
while True:
73+
secret_json = run_command(["get", "secret", secret], namespace)
74+
if "ca.crt" in secret_json["data"] and "token" in secret_json["data"]:
75+
secret_data = secret_json
76+
break
77+
78+
num_retries -= 1
79+
if num_retries == 0:
80+
break
81+
print(
82+
"Secret '{}' is not populated. Sleep {}s, ({} retries left)".format(
83+
secret, timeout, num_retries
84+
)
85+
)
86+
time.sleep(timeout)
87+
return secret_data
88+
89+
90+
def get_secrets_for_sa(sa_name, namespace):
91+
"""Returns a list of all service account token secrets associated
92+
with the given sa_name in the namespace.
93+
94+
"""
95+
secrets = run_command(
96+
[
97+
"get",
98+
"secret",
99+
"--field-selector",
100+
"type=kubernetes.io/service-account-token",
101+
"-o",
102+
'jsonpath="{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name == "'
103+
+ sa_name
104+
+ '")].metadata.name}"',
105+
],
106+
namespace,
107+
as_json=False,
108+
)
109+
return secrets.strip('"').split()
110+
111+
112+
parser = argparse.ArgumentParser(description="Generate KubeConfig with Token")
113+
parser.add_argument("-s", "--service_account", help="Service Account name", required=True)
114+
parser.add_argument("-n", "--namespace", help="Kubernetes namespace", default="kube-system")
115+
parser.add_argument("-c", "--context", help="kubectl context")
116+
parser.add_argument("-o", "--output_file", help="output file path")
117+
args = vars(parser.parse_args())
118+
119+
# if the context is not provided we use the current-context
120+
context = args["context"]
121+
if context is None:
122+
context = run_command(["config", "current-context"], args["namespace"], as_json=False)
123+
124+
cluster_attrs = run_command(
125+
["config", "get-contexts", context.strip(), "--no-headers"], args["namespace"], as_json=False
126+
)
127+
128+
cluster_name = cluster_attrs.strip().split()[2]
129+
endpoint = run_command(
130+
[
131+
"config",
132+
"view",
133+
"-o",
134+
'jsonpath="{.clusters[?(@.name =="' + cluster_name + '")].cluster.server}"',
135+
],
136+
args["namespace"],
137+
as_json=False,
138+
)
139+
service_account_info = run_command(["get", "sa", args["service_account"]], args["namespace"])
140+
141+
tmpdir = tempfile.TemporaryDirectory()
142+
143+
# Get the token and ca.crt from service account secret.
144+
sa_secrets = list()
145+
146+
# Get secrets specified in the service account, there can be multiple
147+
# of them, and not all are service account token secrets.
148+
if "secrets" in service_account_info:
149+
sa_secrets = [secret["name"] for secret in service_account_info["secrets"]]
150+
151+
# Find the existing additional service account token secrets
152+
sa_secrets.extend(get_secrets_for_sa(args["service_account"], args["namespace"]))
153+
154+
secret_data = None
155+
for secret in sa_secrets:
156+
secret_data = get_secret_data(secret, args["namespace"])
157+
if secret_data is not None:
158+
break
159+
160+
# Kubernetes 1.22+ doesn't create the service account token secret by
161+
# default, we have to create one.
162+
if secret_data is None:
163+
print("No usable secret found for '{}', creating one.".format(args["service_account"]))
164+
token_secret = create_sa_token_secret(tmpdir.name, args["service_account"], args["namespace"])
165+
secret_data = get_secret_data(token_secret, args["namespace"])
166+
if secret_data is None:
167+
exit(
168+
"Failed to generate kubeconfig: No usable credentials found for '{}'.".format(
169+
args["service_account"]
170+
)
171+
)
172+
173+
174+
context_name = "{}-{}".format(args["service_account"], cluster_name)
175+
kube_config = args["output_file"]
176+
if not kube_config:
177+
kube_config = "/tmp/{}.conf".format(args["service_account"])
178+
179+
180+
ca_crt_file_name = os.path.join(tmpdir.name, "ca.crt")
181+
ca_crt_file = open(ca_crt_file_name, "wb")
182+
ca_crt_file.write(base64.b64decode(secret_data["data"]["ca.crt"]))
183+
ca_crt_file.close()
184+
185+
# create kubeconfig entry
186+
set_cluster_cmd = [
187+
"config",
188+
"set-cluster",
189+
cluster_name,
190+
"--kubeconfig={}".format(kube_config),
191+
"--server={}".format(endpoint.strip('"')),
192+
"--embed-certs=true",
193+
"--certificate-authority={}".format(ca_crt_file_name),
194+
]
195+
run_command(set_cluster_cmd, as_json=False)
196+
197+
user_token = base64.b64decode(secret_data["data"]["token"]).decode("utf-8")
198+
set_credentials_cmd = [
199+
"config",
200+
"set-credentials",
201+
context_name,
202+
"--token={}".format(user_token),
203+
"--kubeconfig={}".format(kube_config),
204+
]
205+
run_command(set_credentials_cmd, as_json=False, log_command=False)
206+
207+
set_context_cmd = [
208+
"config",
209+
"set-context",
210+
context_name,
211+
"--cluster={}".format(cluster_name),
212+
"--user={}".format(context_name),
213+
"--kubeconfig={}".format(kube_config),
214+
]
215+
run_command(set_context_cmd, as_json=False)
216+
217+
use_context_cmd = ["config", "use-context", context_name, "--kubeconfig={}".format(kube_config)]
218+
run_command(use_context_cmd, as_json=False)
219+
220+
print("Generated the kubeconfig file: {}".format(kube_config))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# OCP compatible values for yugabyte
2+
3+
Image:
4+
repository: "quay.io/yugabyte/yugabyte-ubi"

0 commit comments

Comments
 (0)