Skip to content

Commit ec01078

Browse files
authored
Merge pull request #58 from x0rw/feature/acl-access-control-list
Add initial ACL support to consul-rs
2 parents 342360f + 06b26fe commit ec01078

21 files changed

+798
-40
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
env:
3434
# We pass the config as a JSON here to simulate one service with 3 nodes.
3535
# TODO: Ideally, we should use the same setup in local environment (`testdata/config.hcl`) in GHA test.
36-
CONSUL_LOCAL_CONFIG: '{"acl": [{"default_policy": "allow", "enable_token_persistence": true, "enabled": true}], "services": [ {"address": "1.1.1.1", "checks": [], "id": "test-service-1", "name": "test-service", "port": 20001, "tags": ["first"]}, {"address": "2.2.2.2", "checks": [], "id": "test-service-2", "name": "test-service", "port": 20002, "tags": ["second"]}, {"address": "3.3.3.3", "checks": [], "id": "test-service-3", "name": "test-service", "port": 20003, "tags": ["third"]} ]}'
36+
CONSUL_LOCAL_CONFIG: '{"acl":[{"enabled":true,"default_policy":"allow","enable_token_persistence":true,"tokens":[{"initial_management":"8fc9e787-674f-0709-cfd5-bfdabd73a70d"}]}],"services":[{"id":"test-service-1","name":"test-service","address":"1.1.1.1","port":20001,"checks":[],"tags":["first"]},{"id":"test-service-2","name":"test-service","address":"2.2.2.2","port":20002,"checks":[],"tags":["second"]},{"id":"test-service-3","name":"test-service","address":"3.3.3.3","port":20003,"checks":[],"tags":["third"]}]}'
3737

3838
env:
3939
CONSUL_HTTP_ADDR: http://consul:8500
@@ -42,4 +42,4 @@ jobs:
4242
- uses: actions/checkout@v2
4343

4444
- name: Test
45-
run: cargo test ${{ matrix.features }}
45+
run: cargo test "${{ matrix.features }}"

.github/workflows/publish.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ jobs:
1313
env:
1414
# We pass the config as a JSON here to simulate one service with 3 nodes.
1515
# TODO: Ideally, we should use the same setup in local environment (`testdata/config.hcl`) in GHA test.
16-
CONSUL_LOCAL_CONFIG: '{"acl": [{"default_policy": "allow", "enable_token_persistence": true, "enabled": true}], "services": [ {"address": "1.1.1.1", "checks": [], "id": "test-service-1", "name": "test-service", "port": 20001, "tags": ["first"]}, {"address": "2.2.2.2", "checks": [], "id": "test-service-2", "name": "test-service", "port": 20002, "tags": ["second"]}, {"address": "3.3.3.3", "checks": [], "id": "test-service-3", "name": "test-service", "port": 20003, "tags": ["third"]} ]}'
16+
CONSUL_LOCAL_CONFIG: '{"acl":[{"enabled":true,"default_policy":"allow","enable_token_persistence":true,"tokens":[{"initial_management":"8fc9e787-674f-0709-cfd5-bfdabd73a70d"}]}],"services":[{"id":"test-service-1","name":"test-service","address":"1.1.1.1","port":20001,"checks":[],"tags":["first"]},{"id":"test-service-2","name":"test-service","address":"2.2.2.2","port":20002,"checks":[],"tags":["second"]},{"id":"test-service-3","name":"test-service","address":"3.3.3.3","port":20003,"checks":[],"tags":["third"]}]}'
1717
env:
1818
CONSUL_HTTP_ADDR: http://consul:8500
19-
19+
strategy:
20+
matrix:
21+
features: [""]
2022
steps:
2123
- uses: actions/checkout@v2
2224

23-
- name: Test
24-
run: cargo test
25+
- name: Tests
26+
run: cargo test "${{ matrix.features }}"
2527

2628
dry-run:
2729
runs-on: ubuntu-latest

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ Cargo.lock
1111

1212
# Ignore auto-generated files from JetBrain products
1313
.idea/
14+
15+
# Ignore .swp generated by vim
16+
**/*.swp

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ ureq = { version = "3", features = ["json"] }
3434

3535
[dev-dependencies]
3636
tokio-test = "0.4" # Explicitly add if missing
37+

examples/create_acl_policy.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use rs_consul::{Config, Consul, CreateACLPolicyRequest};
2+
3+
#[tokio::main] // Enables async main
4+
async fn main() {
5+
let consul_config = Config {
6+
address: "http://localhost:8500".to_string(),
7+
token: Some(String::from("8fc9e787-674f-0709-cfd5-bfdabd73a70d")), // use bootstraped
8+
// token (with write perm)
9+
..Default::default()
10+
};
11+
let consul = Consul::new(consul_config);
12+
let policy_payload = CreateACLPolicyRequest {
13+
name: "dev-policy-test-1".to_owned(),
14+
description: Some("this is not a test policy".to_owned()),
15+
rules: Some("".to_owned()),
16+
};
17+
consul.create_acl_policy(&policy_payload).await.unwrap();
18+
}

examples/create_acl_token.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// curl --request PUT \
3+
// --url http://localhost:8500/v1/acl/token \
4+
// --header "X-Consul-Token: 8fc9e787-674f-0709-cfd5-bfdabd73a70d" \
5+
// --header "Content-Type: application/json" \
6+
// --data '{
7+
// "Description": "Minimal token for read-only access",
8+
// "Policies": [
9+
// {
10+
// "Name": "dev-policy-test-1"
11+
// }
12+
// ]
13+
// }'
14+
//
15+
16+
use rs_consul::{Config, Consul, CreateACLTokenPayload};
17+
#[tokio::main] // Enables async main
18+
async fn main() {
19+
let consul_config = Config {
20+
address: "http://localhost:8500".to_string(),
21+
token: Some(String::from("8fc9e787-674f-0709-cfd5-bfdabd73a70d")), // use bootstraped
22+
// token (with write perm)
23+
..Default::default()
24+
};
25+
let consul = Consul::new(consul_config);
26+
let token_payload = CreateACLTokenPayload {
27+
description: Some("Test token".to_owned()),
28+
..Default::default()
29+
};
30+
let result = consul.create_acl_token(&token_payload).await.unwrap();
31+
println!(
32+
"
33+
Token created successfully:
34+
accessor_id: {}
35+
secret_id: {}
36+
description: {}
37+
policies: {:#?}
38+
local: {}
39+
create_time:{}
40+
hash: {}
41+
",
42+
result.accessor_id,
43+
result.secret_id,
44+
result.description,
45+
result.policies,
46+
result.local,
47+
result.create_time,
48+
result.hash,
49+
);
50+
}

examples/delete_acl_token.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use rs_consul::{Config, Consul};
2+
3+
#[tokio::main] // Enables async main
4+
async fn main() {
5+
let consul_config = Config {
6+
address: "http://localhost:8500".to_string(),
7+
token: Some(String::from("8fc9e787-674f-0709-cfd5-bfdabd73a70d")), // use bootstraped
8+
// token (with write perm)
9+
..Default::default()
10+
};
11+
let consul = Consul::new(consul_config);
12+
let _res = consul
13+
.delete_acl_token("58df5025-134c-8999-6bc3-992fe268a39e".to_string())
14+
.await
15+
.unwrap();
16+
17+
println!("Token deleted successfully");
18+
}

examples/get_acl_policies.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use rs_consul::{Config, Consul};
2+
3+
#[tokio::main] // Enables async main
4+
async fn main() {
5+
let consul_config = Config {
6+
address: "http://localhost:8500".to_string(),
7+
token: Some(String::from("8fc9e787-674f-0709-cfd5-bfdabd73a70d")), // use bootstraped
8+
// token (with write perm)
9+
..Default::default()
10+
};
11+
let consul = Consul::new(consul_config);
12+
let acl_policies = consul.get_acl_policies().await.unwrap();
13+
14+
println!("{} Policies found", acl_policies.len());
15+
for (i, policy) in acl_policies.iter().enumerate() {
16+
println!(
17+
"id #{}\n\
18+
├─ ID: {}\n\
19+
├─ Name: {}\n\
20+
└─ Description: {}",
21+
i + 1,
22+
policy.id,
23+
policy.name,
24+
policy.description,
25+
);
26+
println!("\n=========\n")
27+
}
28+
}

examples/get_acl_tokens.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use rs_consul::{Config, Consul};
2+
3+
#[tokio::main] // Enables async main
4+
async fn main() {
5+
let consul_config = Config {
6+
address: "http://localhost:8500".to_string(),
7+
token: Some(String::from("8fc9e787-674f-0709-cfd5-bfdabd73a70d")), // use bootstraped
8+
// token (with write perm)
9+
..Default::default()
10+
};
11+
let consul = Consul::new(consul_config);
12+
let acl_tokens = consul.get_acl_tokens().await.unwrap();
13+
14+
println!("{} Tokens found", acl_tokens.len());
15+
for (i, token) in acl_tokens.iter().enumerate() {
16+
println!(
17+
"Token #{}\n\
18+
├─ Accessor ID: {}\n\
19+
├─ Secret ID: {}\n\
20+
├─ Description: {}\n\
21+
└─ Policies: {}",
22+
i + 1,
23+
token.accessor_id,
24+
token.secret_id,
25+
token.description,
26+
token
27+
.policies
28+
.iter()
29+
.map(|p| format!(" ({:?})", p))
30+
.collect::<Vec<_>>()
31+
.join(", ")
32+
);
33+
println!("\n=========\n")
34+
}
35+
}

examples/lock.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use rs_consul::{Config, Consul, types::*};
2+
3+
#[tokio::main] // Enables async main
4+
async fn main() {
5+
let consul_config = Config {
6+
address: "http://localhost:8500".to_string(),
7+
token: None, // Token is None in developpement mode
8+
..Default::default()
9+
};
10+
let consul = Consul::new(consul_config);
11+
12+
let node_id = "root-node";
13+
let service_name = "new-service-1";
14+
let payload = RegisterEntityPayload {
15+
ID: None,
16+
Node: node_id.to_string(),
17+
Address: "127.0.0.1".to_string(),
18+
Datacenter: None,
19+
TaggedAddresses: Default::default(),
20+
NodeMeta: Default::default(),
21+
Service: Some(RegisterEntityService {
22+
ID: None,
23+
Service: service_name.to_string(),
24+
Tags: vec![],
25+
TaggedAddresses: Default::default(),
26+
Meta: Default::default(),
27+
Port: Some(42424),
28+
Namespace: None,
29+
}),
30+
Checks: vec![],
31+
SkipNodeUpdate: None,
32+
};
33+
consul.register_entity(&payload).await.unwrap();
34+
}

0 commit comments

Comments
 (0)