Skip to content

Commit 97fbce2

Browse files
brigibodrov
authored andcommitted
concord-server: generate admin token on start (#1559)
1 parent 54a47cd commit 97fbce2

File tree

19 files changed

+293
-30
lines changed

19 files changed

+293
-30
lines changed

examples/ansible_project/README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ and necessary runtime dependencies.
4545
```
4646
curl -v \
4747
-H "Content-Type: application/json" \
48-
-H "Authorization: auBy4eDWrKWsyhiDp3AQiw" \
48+
-H "Authorization: API_TOKEN" \
4949
-d '{ "name": "myProject", "cfg": { "template": "ansible" }, "repositories": { "myRepo": {"url": "[email protected]:my/repo.git", "secret": "mySecret" } } }' \
5050
http://localhost:8001/api/v1/org/Default/project
5151
```
@@ -64,7 +64,7 @@ The `secret` parameters is the name of the key created on the step 2.
6464
```
6565
curl -v \
6666
-H "Content-Type: application/json" \
67-
-H "Authorization: auBy4eDWrKWsyhiDp3AQiw" \
67+
-H "Authorization: API_TOKEN" \
6868
-d '{ "username": "myUser" }' \
6969
http://localhost:8001/api/v1/user
7070
```
@@ -83,15 +83,15 @@ Use the `username` value of the user created in the previous step.
8383
```
8484
curl -v \
8585
-H "Content-Type: application/json" \
86-
-H "Authorization: auBy4eDWrKWsyhiDp3AQiw" \
86+
-H "Authorization: API_TOKEN" \
8787
-d '{ "username": "myUser" }' \
8888
http://localhost:8001/api/v1/apikey
8989
```
9090

9191
```json
9292
{
9393
"ok": true,
94-
"key": "auBy4eDWrKWsyhiDp3AQiw"
94+
"key": "API_TOKEN"
9595
}
9696
```
9797

@@ -124,7 +124,7 @@ Make a call:
124124

125125
```
126126
curl -v \
127-
-H "Authorization: auBy4eDWrKWsyhiDp3AQiw" \
127+
-H "Authorization: API_TOKEN" \
128128
-F org=Default \
129129
-F project=myProject \
130130
-F repo=myRepo \
@@ -154,7 +154,7 @@ You can download Ansible play's statistics with this request:
154154

155155
```
156156
curl -v \
157-
-H "Authorization: auBy4eDWrKWsyhiDp3AQiw" \
157+
-H "Authorization: API_TOKEN" \
158158
http://localhost:8001/api/v1/process/33c8f91e-db14-11e6-8d94-a3efec7ccd7b/attachment/ansible_stats.json
159159
```
160160

examples/ansible_remote/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Example of running an Ansible playbook on a remote host without creating a proje
66

77
1. Upload the remote ssh key to the server:
88
```
9-
curl -H "Authorization: auBy4eDWrKWsyhiDp3AQiw" \
9+
curl -H "Authorization: API_TOKEN" \
1010
-F private=@/path/to/id_rsa \
1111
-F public=@/path/to/id_rsa.pub \
1212
-F storePassword=mySecretPassword \

examples/secrets/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Example of using "secrets" in processes.
66

77
1. create a new SSH key pair:
88
```
9-
$ curl -H "Authorization: auBy4eDWrKWsyhiDp3AQiw" -F storePassword=12345678 -F name=myKey -F type=KEY_PAIR 'http://localhost:8001/api/v1/org/Default/secret'
9+
$ curl -H "Authorization: API_TOKEN" -F storePassword=12345678 -F name=myKey -F type=KEY_PAIR 'http://localhost:8001/api/v1/org/Default/secret'
1010
{
1111
"name" : "myKey",
1212
"publicKey" : "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCmV6+q6Uh8j8GYl0nzcwTGpjBwY1Dvv3QIAfmdwC8N6HredMl5hV3RCtpplYR7aItTorWVUYF1MMmXYKr6tjgU9hha2N2NogRjgPWzSVuR8GVa7CF155NB4nlUxt5cGidLj5Uwmy/uQm4Mni5pg/kZMGyIf+gMmcuQXDG3TOHwmJ48HOrpqxkUKaft3SYYOy7F8TjWFnmyXNlMCskSEJd5XdLDhyuDhDEXGpDSsT1brsq0WRXtFyBDjjNeYfI4J9jyOCpAXzbDCt7eYoYK+kod/b6RV8nbaxWALx2fwJS0bDhV3a9chwEyat24Ml66Z5LfCabCE7SGpFhTas56xYkH concord-server",
@@ -19,7 +19,7 @@ The `storePassword` value is the password you must use to decrypt/export the sec
1919

2020
2. create a new username/password pair:
2121
```
22-
$ curl -H "Authorization: auBy4eDWrKWsyhiDp3AQiw" -F username=myUser -F password=myPassword -F storePassword=12345678 -F name=myCreds -F type=USERNAME_PASSWORD 'http://localhost:8001/api/v1/org/Default/secret'
22+
$ curl -H "Authorization: API_TOKEN" -F username=myUser -F password=myPassword -F storePassword=12345678 -F name=myCreds -F type=USERNAME_PASSWORD 'http://localhost:8001/api/v1/org/Default/secret'
2323
{
2424
"exportPassword" : "12345678",
2525
"ok" : true
@@ -30,7 +30,7 @@ For the sake of the example, the same `storePassword` value is used.
3030

3131
3. create a plain value secret:
3232
```
33-
$ curl -H "Authorization: auBy4eDWrKWsyhiDp3AQiw" -F secret='my horrible secret' -F storePassword=12345678 -F name=myValue -F type=DATA 'http://localhost:8001/api/v1/org/Default/secret'
33+
$ curl -H "Authorization: API_TOKEN" -F secret='my horrible secret' -F storePassword=12345678 -F name=myValue -F type=DATA 'http://localhost:8001/api/v1/org/Default/secret'
3434
{
3535
"exportPassword" : "12345678",
3636
"ok" : true

it/common/src/main/java/com/walmartlabs/concord/it/common/ServerClient.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
public class ServerClient {
4040

4141
/**
42-
* As defined in db/src/main/resources/com/walmartlabs/concord/server/db/v0.0.1.xml
42+
* As defined in server.conf
4343
*/
4444
public static final String DEFAULT_API_KEY = "auBy4eDWrKWsyhiDp3AQiw";
4545

it/console/src/test/resources/server.conf

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
concord-server {
2+
db {
3+
changeLogParameters {
4+
defaultAdminToken = "auBy4eDWrKWsyhiDp3AQiw"
5+
}
6+
}
7+
28
secretStore {
39
serverPassword = "aXRpdGl0"
410
secretStoreSalt = "aXRpdGl0"

it/server/src/test/resources/server.conf

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
concord-server {
2+
db {
3+
changeLogParameters {
4+
defaultAdminToken = "auBy4eDWrKWsyhiDp3AQiw"
5+
}
6+
}
7+
28
secretStore {
39
serverPassword = "aXRpdGl0"
410
secretStoreSalt = "aXRpdGl0"

server/db/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
<groupId>com.walmartlabs.concord.server</groupId>
2828
<artifactId>concord-server-sdk</artifactId>
2929
</dependency>
30+
<dependency>
31+
<groupId>com.walmartlabs.concord.server</groupId>
32+
<artifactId>liquibase-ext</artifactId>
33+
</dependency>
3034
<dependency>
3135
<groupId>org.postgresql</groupId>
3236
<artifactId>postgresql</artifactId>
@@ -163,6 +167,7 @@
163167
<username>${db.username}</username>
164168
<password>${db.password}</password>
165169
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
170+
<contexts>codegen</contexts>
166171
</configuration>
167172
</plugin>
168173
<plugin>

server/db/src/main/java/com/walmartlabs/concord/db/DataSourceUtils.java

+42-15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import javax.sql.DataSource;
4141
import java.sql.Connection;
42+
import java.util.Map;
4243

4344
public final class DataSourceUtils {
4445

@@ -47,7 +48,6 @@ public final class DataSourceUtils {
4748
private static final int MIGRATION_MAX_RETRIES = 10;
4849
private static final int MIGRATION_RETRY_DELAY = 10000;
4950

50-
5151
public static DataSource createDataSource(DatabaseConfiguration cfg,
5252
String poolName,
5353
String username,
@@ -70,11 +70,28 @@ public static DataSource createDataSource(DatabaseConfiguration cfg,
7070
}
7171

7272
public static void migrateDb(DataSource ds, DatabaseChangeLogProvider p) {
73+
migrateDb(ds, p, null);
74+
}
75+
76+
/**
77+
* Migrate a database using the provided changelog and Liquibase parameters.
78+
*
79+
* @param dataSource datasource to use for migration
80+
* @param changeLogProvider provider of the changelog
81+
* @param changeLogParams Liquibase parameters to use during the migration
82+
*/
83+
public static void migrateDb(DataSource dataSource,
84+
DatabaseChangeLogProvider changeLogProvider,
85+
Map<String, Object> changeLogParams) {
86+
7387
int retries = MIGRATION_MAX_RETRIES;
7488
for (int i = 0; i < retries; i++) {
75-
try (Connection c = ds.getConnection()) {
76-
log.info("get -> performing '{}' migration...", p);
77-
migrateDb(c, p.getChangeLogPath(), p.getChangeLogTable(), p.getLockTable());
89+
try (Connection c = dataSource.getConnection()) {
90+
log.info("get -> performing '{}' migration...", changeLogProvider);
91+
String logPath = changeLogProvider.getChangeLogPath();
92+
String logTable = changeLogProvider.getChangeLogTable();
93+
String lockTable = changeLogProvider.getLockTable();
94+
migrateDb(c, logPath, logTable, lockTable, changeLogParams);
7895
log.info("get -> done");
7996
break;
8097
} catch (Exception e) {
@@ -93,17 +110,6 @@ public static void migrateDb(DataSource ds, DatabaseChangeLogProvider p) {
93110
}
94111
}
95112

96-
private static void migrateDb(Connection conn, String logPath, String logTable, String lockTable) throws Exception {
97-
LogFactory.getInstance().setDefaultLoggingLevel(LogLevel.WARNING);
98-
99-
Database db = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn));
100-
db.setDatabaseChangeLogTableName(logTable);
101-
db.setDatabaseChangeLogLockTableName(lockTable);
102-
103-
Liquibase lb = new Liquibase(logPath, new ClassLoaderResourceAccessor(), db);
104-
lb.update((String) null);
105-
}
106-
107113
public static Configuration createJooqConfiguration(DataSource ds) {
108114
Settings settings = new Settings();
109115
settings.setRenderSchema(false);
@@ -115,6 +121,27 @@ public static Configuration createJooqConfiguration(DataSource ds) {
115121
.set(SQLDialect.POSTGRES);
116122
}
117123

124+
private static void migrateDb(Connection conn,
125+
String logPath,
126+
String logTable,
127+
String lockTable,
128+
Map<String, Object> params) throws Exception {
129+
130+
LogFactory.getInstance().setDefaultLoggingLevel(LogLevel.WARNING);
131+
132+
Database db = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn));
133+
db.setDatabaseChangeLogTableName(logTable);
134+
db.setDatabaseChangeLogLockTableName(lockTable);
135+
136+
Liquibase lb = new Liquibase(logPath, new ClassLoaderResourceAccessor(), db);
137+
138+
if (params != null) {
139+
params.forEach(lb::setChangeLogParameter);
140+
}
141+
142+
lb.update((String) null);
143+
}
144+
118145
private DataSourceUtils() {
119146
}
120147
}

server/db/src/main/java/com/walmartlabs/concord/db/DatabaseConfiguration.java

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* =====
2121
*/
2222

23+
import java.util.Collections;
24+
import java.util.Map;
25+
2326
public interface DatabaseConfiguration {
2427

2528
default String driverClassName() {
@@ -35,4 +38,8 @@ default String driverClassName() {
3538
int maxPoolSize();
3639

3740
long maxLifetime();
41+
42+
default Map<String, Object> changeLogParameters() {
43+
return Collections.emptyMap();
44+
}
3845
}

server/db/src/main/java/com/walmartlabs/concord/db/DatabaseModule.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public DataSource appDataSource(@MainDB DatabaseConfiguration cfg,
4949
// can't inject a set of objects with the same qualifier, filter manually
5050
.filter(p -> p.getClass().getAnnotation(MainDB.class) != null)
5151
.sorted(Comparator.comparingInt(DatabaseChangeLogProvider::order))
52-
.forEach(p -> DataSourceUtils.migrateDb(ds, p));
52+
.forEach(p -> DataSourceUtils.migrateDb(ds, p, cfg.changeLogParameters()));
5353

5454
return ds;
5555
}

server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<databaseChangeLog
33
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
44
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
66

77
<include file="v0.0.1.xml" relativeToChangelogFile="true"/>
88
<include file="v0.2.0.xml" relativeToChangelogFile="true"/>
@@ -82,5 +82,6 @@
8282
<include file="v1.40.0.xml" relativeToChangelogFile="true"/>
8383
<include file="v1.41.0.xml" relativeToChangelogFile="true"/>
8484
<include file="v1.43.0.xml" relativeToChangelogFile="true"/>
85+
<include file="v1.45.0.xml" relativeToChangelogFile="true"/>
8586

8687
</databaseChangeLog>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<databaseChangeLog
3+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
6+
7+
<changeSet id="1450000" author="[email protected]" runInTransaction="false" context="!codegen">
8+
<sql>
9+
delete from API_KEYS where KEY_ID = 'd5165ca8-e8de-11e6-9bf5-136b5db23c32'
10+
</sql>
11+
12+
<customChange class="com.walmartlabs.concord.server.liquibase.ext.ApiTokenCreator">
13+
<!-- default admin user ID -->
14+
<param name="userId" value="230c5c9c-d9a7-11e6-bcfd-bb681c07b26c"/>
15+
<!-- value from concord-server.conf -->
16+
<param name="token" value="${defaultAdminToken}"/>
17+
</customChange>
18+
</changeSet>
19+
</databaseChangeLog>

server/dist/src/main/resources/concord-server.conf

+9
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ concord-server {
5252

5353
# maximum lifetime of a connection in the pool, ms
5454
maxLifetime = 300000 # 5 min
55+
56+
# parameters using during the DB schema migration
57+
changeLogParameters {
58+
# the default admin API token value
59+
# must be a valid base64 value
60+
# if empty a new random token will be generated
61+
# applied only once on the first DB migration
62+
defaultAdminToken = ""
63+
}
5564
}
5665

5766
# "remember me" cookie support

server/impl/src/main/java/com/walmartlabs/concord/server/cfg/MainDBConfiguration.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
* Licensed under the Apache License, Version 2.0 (the "License");
1010
* you may not use this file except in compliance with the License.
1111
* You may obtain a copy of the License at
12-
*
12+
*
1313
* http://www.apache.org/licenses/LICENSE-2.0
14-
*
14+
*
1515
* Unless required by applicable law or agreed to in writing, software
1616
* distributed under the License is distributed on an "AS IS" BASIS,
1717
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,6 +27,7 @@
2727
import javax.inject.Inject;
2828
import javax.inject.Named;
2929
import javax.inject.Singleton;
30+
import java.util.Map;
3031

3132
@Named
3233
@Singleton
@@ -53,6 +54,10 @@ public class MainDBConfiguration implements DatabaseConfiguration {
5354
@Config("db.maxLifetime")
5455
private long maxLifetime;
5556

57+
@Inject
58+
@Config("db.changeLogParameters")
59+
private Map<String, Object> changeLogParameters;
60+
5661
@Override
5762
public String url() {
5863
return url;
@@ -77,4 +82,9 @@ public int maxPoolSize() {
7782
public long maxLifetime() {
7883
return maxLifetime;
7984
}
85+
86+
@Override
87+
public Map<String, Object> changeLogParameters() {
88+
return changeLogParameters;
89+
}
8090
}

server/liquibase-ext/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Liquibase Extensions
2+
3+
This module contains Concord-specific [Liquibase](https://www.liquibase.org/) extensions.

server/liquibase-ext/pom.xml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>com.walmartlabs.concord.server</groupId>
8+
<artifactId>parent</artifactId>
9+
<version>1.44.1-SNAPSHOT</version>
10+
<relativePath>../pom.xml</relativePath>
11+
</parent>
12+
13+
<artifactId>liquibase-ext</artifactId>
14+
<packaging>takari-jar</packaging>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>org.liquibase</groupId>
19+
<artifactId>liquibase-core</artifactId>
20+
</dependency>
21+
</dependencies>
22+
23+
<build>
24+
<plugins>
25+
<plugin>
26+
<groupId>io.takari.maven.plugins</groupId>
27+
<artifactId>takari-lifecycle-plugin</artifactId>
28+
</plugin>
29+
</plugins>
30+
</build>
31+
</project>

0 commit comments

Comments
 (0)