Skip to content

Commit 6959f3c

Browse files
authored
Use KibbleConfigParser in setup script (#83)
* Use KibbleConfigParser in setup script * fixup! Use KibbleConfigParser in setup script
1 parent 5471c07 commit 6959f3c

File tree

8 files changed

+118
-118
lines changed

8 files changed

+118
-118
lines changed

docker-compose-dev.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
build:
88
context: .
99
dockerfile: Dockerfile.dev
10-
command: bash -c "python kibble/setup/setup.py -e elasticsearch -a -k"
10+
command: bash -c "python kibble/setup/setup.py --autoadmin --skiponexist"
1111
volumes:
1212
- .:/kibble/
1313
depends_on:

kibble.ini

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[accounts]
2+
allowSignup = True
3+
verify = True
4+
5+
[api]
6+
# Kibble elasticsearch database revision
7+
database = 2
8+
# Version f the API
9+
version = 0.1.0
10+
11+
[elasticsearch]
12+
# Elasticsearch database name
13+
dbname = kibble
14+
# Connection uri used to determine host and port of elasticsearch instance
15+
conn_uri = elasticsearch:9200
16+
# Number of shards in es cluster
17+
shards = 5
18+
# Number of replicase in es cluster
19+
replicas = 1
20+
ssl = False
21+
uri =
22+
auth =
23+
24+
[mail]
25+
mailhost = localhost:25
26+
sender = Kibble <[email protected]>

kibble/configuration.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,20 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17-
17+
import os
1818
from configparser import ConfigParser
1919

20+
DEFAULT_KIBBLE_CONFIG_LOCATION = os.path.join(
21+
os.path.dirname(os.path.realpath(__file__)), os.pardir, "kibble.ini"
22+
)
23+
2024

2125
class KibbleConfigParser(ConfigParser):
26+
"""Custom Kibble config parser"""
27+
2228
def __init__(self):
2329
super().__init__()
2430

25-
def get_int(self, section: str, key: str) -> int:
26-
try:
27-
return int(self.get(section, key))
28-
except Exception:
29-
raise TypeError("Unable to convert value to int")
3031

31-
def get_bool(self, section: str, key: str) -> bool:
32-
try:
33-
return bool(self.get(section, key))
34-
except Exception:
35-
raise TypeError("Unable to convert value to bool")
32+
conf = KibbleConfigParser()
33+
conf.read(DEFAULT_KIBBLE_CONFIG_LOCATION)

kibble/setup/kibble.ini

-16
This file was deleted.

kibble/setup/setup.py

+22-89
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@
2222
from getpass import getpass
2323

2424
import tenacity
25-
import yaml
2625
import bcrypt
2726
import json
2827
from elasticsearch import Elasticsearch
2928

30-
from kibble.settings import KIBBLE_YAML
29+
from kibble.configuration import conf
3130

32-
KIBBLE_VERSION = "0.1.0" # ABI/API compat demarcation.
33-
KIBBLE_DB_VERSION = 2 # Second database revision
31+
32+
KIBBLE_VERSION = conf.get("api", "version")
33+
KIBBLE_DB_VERSION = conf.get("api", "database") # database revision
3434

3535
if sys.version_info <= (3, 3):
3636
print("This script requires Python 3.4 or higher")
@@ -42,60 +42,53 @@ def get_parser():
4242
arg_parser = argparse.ArgumentParser()
4343
arg_parser.add_argument(
4444
"-e",
45-
"--hostname",
46-
help="Pre-defined hostname for ElasticSearch (docker setups). Default: localhost",
47-
default="localhost",
48-
)
49-
arg_parser.add_argument(
50-
"-p",
51-
"--port",
52-
help="Pre-defined port for ES (docker setups). Default: 9200",
53-
default=9200,
45+
"--conn-uri",
46+
help="Pre-defined connection uri for ElasticSearch.",
47+
default=conf.get("elasticsearch", "conn_uri"),
5448
)
5549
arg_parser.add_argument(
5650
"-d",
5751
"--dbname",
58-
help="Pre-defined Database prefix (docker setups). Default: kibble",
59-
default="kibble",
52+
help="Pre-defined Database prefix. Default: kibble",
53+
default=conf.get("elasticsearch", "dbname"),
6054
)
6155
arg_parser.add_argument(
6256
"-s",
6357
"--shards",
64-
help="Predefined number of ES shards (docker setups), Default: 5",
65-
default=5,
58+
help="Predefined number of ES shards, Default: 5",
59+
default=conf.get("elasticsearch", "shards"),
6660
)
6761
arg_parser.add_argument(
6862
"-r",
6963
"--replicas",
70-
help="Predefined number of replicas for ES (docker setups). Default: 1",
71-
default=1,
64+
help="Predefined number of replicas for ES. Default: 1",
65+
default=conf.get("elasticsearch", "replicas"),
7266
)
7367
arg_parser.add_argument(
7468
"-m",
7569
"--mailhost",
76-
help="Pre-defined mail server host (docker setups). Default: localhost:25",
77-
default="localhost:25",
70+
help="Pre-defined mail server host. Default: localhost:25",
71+
default=conf.get("mail", "mailhost"),
7872
)
7973
arg_parser.add_argument(
8074
"-a",
8175
"--autoadmin",
8276
action="store_true",
83-
help="Generate generic admin account (docker setups). Default: False",
77+
help="Generate generic admin account. Default: False",
8478
default=False,
8579
)
8680
arg_parser.add_argument(
8781
"-k",
8882
"--skiponexist",
8983
action="store_true",
90-
help="Skip DB creation if DBs exist (docker setups). Defaul: True",
84+
help="Skip DB creation if DBs exist. Defaul: True",
9185
default=True,
9286
)
9387
return arg_parser
9488

9589

9690
def create_es_index(
97-
hostname: str,
98-
port: int,
91+
conn_uri: str,
9992
dbname: str,
10093
shards: int,
10194
replicas: int,
@@ -114,11 +107,7 @@ def create_es_index(
114107
with open(mappings_json, "r") as f:
115108
mappings = json.load(f)
116109

117-
es = Elasticsearch(
118-
[{"host": hostname, "port": port, "use_ssl": False, "url_prefix": ""}],
119-
max_retries=5,
120-
retry_on_timeout=True,
121-
)
110+
es = Elasticsearch([conn_uri], max_retries=5, retry_on_timeout=True)
122111

123112
es_version = es.info()["version"]["number"]
124113
es6 = int(es_version.split(".")[0]) >= 6
@@ -223,51 +212,6 @@ def create_es_index(
223212
print("Account created!")
224213

225214

226-
def get_kibble_yaml() -> str:
227-
"""Resolve path to kibble config yaml"""
228-
kibble_yaml = KIBBLE_YAML
229-
if os.path.exists(kibble_yaml):
230-
print(f"{kibble_yaml} already exists! Writing to {kibble_yaml}.tmp instead")
231-
kibble_yaml = kibble_yaml + ".tmp"
232-
return kibble_yaml
233-
234-
235-
def save_config(mlserver: str, hostname: str, port: int, dbname: str):
236-
"""Save kibble config to yaml file"""
237-
if ":" in mlserver:
238-
try:
239-
mailhost, mailport = mlserver.split(":")
240-
except ValueError:
241-
raise ValueError(
242-
"mailhost argument must be in form of `host:port` or `host`"
243-
)
244-
else:
245-
mailhost = mlserver
246-
mailport = 25
247-
248-
config = {
249-
"api": {"version": KIBBLE_VERSION, "database": KIBBLE_DB_VERSION},
250-
"elasticsearch": {
251-
"host": hostname,
252-
"port": port,
253-
"ssl": False,
254-
"dbname": dbname,
255-
},
256-
"mail": {
257-
"mailhost": mailhost,
258-
"mailport": int(mailport),
259-
"sender": "Kibble <[email protected]>",
260-
},
261-
"accounts": {"allowSignup": True, "verify": True},
262-
}
263-
264-
kibble_yaml = get_kibble_yaml()
265-
print(f"Writing Kibble config to {kibble_yaml}")
266-
with open(kibble_yaml, "w") as f:
267-
f.write(yaml.dump(config, default_flow_style=False))
268-
f.close()
269-
270-
271215
def get_user_input(msg: str, secure: bool = False):
272216
value = None
273217
while not value:
@@ -279,8 +223,7 @@ def print_configuration(args):
279223
print(
280224
"Configuring Apache Kibble elasticsearch instance with the following arguments:"
281225
)
282-
print(f"- hostname: {args.hostname}")
283-
print(f"- port: {int(args.port)}")
226+
print(f"- conn_uri: {args.conn_uri}")
284227
print(f"- dbname: {args.dbname}")
285228
print(f"- shards: {int(args.shards)}")
286229
print(f"- replicas: {int(args.replicas)}")
@@ -311,7 +254,7 @@ def main():
311254

312255
# Create Elasticsearch index
313256
# Retry in case ES is not yet up
314-
print(f"Elasticsearch: {args.hostname}:{args.port}")
257+
print(f"Elasticsearch: {args.conn_uri}")
315258
for attempt in tenacity.Retrying(
316259
retry=tenacity.retry_if_exception_type(exception_types=Exception),
317260
wait=tenacity.wait_fixed(10),
@@ -321,8 +264,7 @@ def main():
321264
with attempt:
322265
print("Trying to create ES index...")
323266
create_es_index(
324-
hostname=args.hostname,
325-
port=int(args.port),
267+
conn_uri=args.conn_uri,
326268
dbname=args.dbname,
327269
shards=int(args.shards),
328270
replicas=int(args.replicas),
@@ -331,15 +273,6 @@ def main():
331273
skiponexist=args.skiponexist,
332274
)
333275
print()
334-
335-
# Create Kibble configuration file
336-
save_config(
337-
mlserver=args.mailhost,
338-
hostname=args.hostname,
339-
port=int(args.port),
340-
dbname=args.dbname,
341-
)
342-
print()
343276
print("All done, Kibble should...work now :)")
344277

345278

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
spec.loader.exec_module(mod) # type: ignore
2929
version = mod.version # type: ignore
3030

31-
DEVEL_REQUIREMENTS = ["pre-commit==2.7.1", "black==20.8b1"]
31+
DEVEL_REQUIREMENTS = ["black==20.8b1", "pre-commit==2.7.1", "pytest==6.1.1"]
3232

3333
INSTALL_REQUIREMENTS = [
3434
"bcrypt==3.2.0",

tests/__init__.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.

tests/test_configuration.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
import pytest
19+
20+
from kibble.configuration import conf
21+
22+
23+
class TestDefaultConfig:
24+
@pytest.mark.parametrize(
25+
"section, key, value",
26+
[
27+
("accounts", "allowSignup", True),
28+
("accounts", "verify", True),
29+
("api", "database", 2),
30+
("api", "version", "0.1.0"),
31+
("elasticsearch", "conn_uri", "elasticsearch:9200"),
32+
("mail", "mailhost", "localhost:25"),
33+
],
34+
)
35+
def test_default_values(self, section, key, value):
36+
if isinstance(value, bool):
37+
config_value = conf.getboolean(section, key)
38+
elif isinstance(value, int):
39+
config_value = conf.getint(section, key)
40+
else:
41+
config_value = conf.get(section, key)
42+
43+
assert config_value == value

0 commit comments

Comments
 (0)