Skip to content

Commit

Permalink
feat: complete majority of the API
Browse files Browse the repository at this point in the history
Authored By: Duke Nguyen <[email protected]>
Co-Authored By: Caspian Baska <[email protected]>
  • Loading branch information
dukenguyenxyz authored and caspiano committed Nov 15, 2021
1 parent ed7b097 commit b43427e
Show file tree
Hide file tree
Showing 15 changed files with 377 additions and 130 deletions.
60 changes: 31 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,44 @@ client.range("/service/hello").kvs.try(&.first?) #=> #<Etcd::Model::KV @key="/se

## TODO

- Auth.
- Specs (auth, cluster, maintenance, kv.compaction, kv.txn)
- Multi-node.
- Use enum instead of String

### Auth

- [ ] authenticate
- [ ] disable
- [ ] enable
- [ ] role/add
- [ ] role/delete
- [ ] role/get
- [ ] role/grant
- [ ] role/list
- [ ] role/revoke
- [ ] user/add
- [ ] user/changepw
- [ ] user/delete
- [ ] user/get
- [ ] user/grant
- [ ] user/list
- [ ] user/revoke
- [x] authenticate
- [x] disable
- [x] enable
- [x] role/add
- [x] role/delete
- [x] role/get
- [x] role/grant
- [x] role/list
- [x] role/revoke
- [x] user/add
- [x] user/changepw
- [x] user/delete
- [x] user/get
- [x] user/grant
- [x] user/list
- [x] user/revoke

### Cluster

- [ ] member/add
- [ ] member/list
- [ ] member/promote
- [ ] member/remove
- [ ] member/update
- [x] member/add
- [x] member/list
- [x] member/promote
- [x] member/remove
- [x] member/update

### Kv

- [x] put
- [x] range
- [x] deleterange
- [ ] compaction
- [ ] txn
- [x] compaction
- [x] txn

### Lease

Expand All @@ -82,12 +83,12 @@ client.range("/service/hello").kvs.try(&.first?) #=> #<Etcd::Model::KV @key="/se

### Maintenance

- [ ] alarm
- [ ] defragment
- [ ] hash
- [ ] snapshot
- [x] alarm
- [x] defragment
- [x] hash
- [x] snapshot
- [x] status
- [ ] transfer-leadership
- [x] transfer-leadership

### Watch

Expand All @@ -108,3 +109,4 @@ client.range("/service/hello").kvs.try(&.first?) #=> #<Etcd::Model::KV @key="/se
## Contributors

- [Caspian Baska](https://github.com/caspiano) - creator and maintainer
- [Duke Nguyen](https://github.com/dukeraphaelng) - maintainer
1 change: 1 addition & 0 deletions shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: etcd
version: 1.2.5
crystal: ">= 0.35"
license: MIT

authors:
- Caspian Baska <[email protected]>
- Duke Nguyen <[email protected]>
Expand Down
6 changes: 3 additions & 3 deletions spec/kv_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module Etcd
client = Etcd.from_env
response = client.kv.put("#{TEST_PREFIX}/hello", "world")

response.should be_a Model::PutResponse
response.should be_a Model::Put
end

it "queries a range of keys" do
Expand All @@ -64,7 +64,7 @@ module Etcd
client.kv.put(key, value)
response = client.kv.range(key)

response.should be_a Model::RangeResponse
response.should be_a Model::Range
values = response.kvs || [] of Model::Kv
value_present = values.any? { |r| r.key == key && r.value == value }
value_present.should be_true
Expand All @@ -82,7 +82,7 @@ module Etcd
client.kv.put(key1, value1, lease: lease.id)
response = client.kv.range_prefix(key0)

response.should be_a Model::RangeResponse
response.should be_a Model::Range
values = response.kvs || [] of Model::Kv
key_present = values.any? { |r| r.key == key1 && r.value == value1 }
key_present.should be_true
Expand Down
97 changes: 69 additions & 28 deletions src/etcd/auth.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,82 +5,123 @@ class Etcd::Auth
end

# auth/authenticate
def authenticate
raise "unimplemented"
def authenticate(name : String, password : String)
validate!(name)

response = client.api.post("/auth/auth/authenticate", {name: name, password: password}).body
Model::Token.from_json(response).token
end

# auth/disable
def disable
raise "unimplemented"
client.api.post("/auth/auth/disable").success?
end

# auth/enable
def enable
raise "unimplemented"
client.api.post("/auth/auth/enable").success?
end

# auth/role/add
def role_add
raise "unimplemented"
def role_add(name : String)
validate!(name)

client.api.post("/auth/role/add", {name: name}).success?
end

# auth/role/delete
def role_delete
raise "unimplemented"
def role_delete(role : String)
client.api.post("/auth/role/delete", {role: role}).success?
end

# auth/role/get
def role_get
raise "unimplemented"
def role_get(role : String)
response = client.api.post("/auth/role/get", {role: role}).body
Model::Permissions.from_json(response).perm
end

# auth/role/grant
def role_grant
raise "unimplemented"
def role_grant(name : String, perm_key : String, range_end : String)
validate!(name)

options = {
:name => name,
:perm => {
:key => perm_key,
:permType => "READ",
:range_end => range_end,
},
}

client.api.post("/auth/role/grant", options).success?
end

# auth/role/list
def role_list
raise "unimplemented"
response = client.api.post("/auth/role/list").body
Roles.from_json(response).roles
end

# auth/role/revoke
def role_revoke
raise "unimplemented"
def role_revoke(key : String, range_end : String, role : String)
client.api.post("/auth/role/revoke").success?
end

# auth/user/add
def user_add
raise "unimplemented"
def user_add(name : String, password : String, no_password : Bool)
validate!(name)

options = {
:name => name,
:options => {
:no_password => no_password,
},
:password => password,
}

client.api.post("/auth/user/add", options).success?
end

# auth/user/changepw
def user_changepw
raise "unimplemented"
def user_changepw(name : String, password : String)
validate!(name)

client.api.post("/auth/user/changepw", {name: name, password: password}).success?
end

# auth/user/delete
def user_delete
raise "unimplemented"
def user_delete(name : String)
validate!(name)

client.api.post("/auth/user/delete", {name: name}).success?
end

# auth/user/get
def user_get
raise "unimplemented"
def user_get(name : String)
validate!(name)

response = client.api.post("/auth/user/get", {name: name}).body
Model::Roles.from_json(response).roles
end

# auth/user/grant
def user_grant
raise "unimplemented"
def user_grant(role : String, user : String)
client.api.post("/auth/user/grant").success?
end

# auth/user/list
def user_list
raise "unimplemented"
response = client.api.post("/auth/user/list").body
Model::Users.from_json(response).users
end

# auth/user/revoke
def user_revoke
raise "unimplemented"
def user_revoke(name : String, role : String)
validate!(name)
client.api.post("/auth/user/revoke").success?
end

private def validate!(name : String)
raise ArgumentError.new("Arg name is empty") if name.empty?
end
end
28 changes: 19 additions & 9 deletions src/etcd/cluster.cr
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
module Etcd::Cluster
private getter client : Etcd::Client

def initialize(@client = Etcd::Client.new)
end

# POST cluster/member/add
def member_add
raise "unimplemented"
def member_add(is_learner : Bool, peer_urls : Array(String))
response = client.api.post("/cluster/member/add", {is_learner: is_learner, peerURLs: peer_urls}).body
Model::Cluster::MemberAdd.from_json(response)
end

# POST cluster/member/list
def member_list
raise "unimplemented"
response = client.api.post("/cluster/member/list").body
Model::Cluster::Members.from_json(response).members
end

# POST cluster/member/promote
def member_promote
raise "unimplemented"
def member_promote(id : UInt64)
response = client.api.post("/cluster/member/promote", {ID: id}).body
Model::Cluster::Members.from_json(response).members
end

# POST cluster/member/remove
def member_remove
raise "unimplemented"
def member_remove(id : UInt64)
response = client.api.post("/cluster/member/remove", {ID: id}).body
Model::Cluster::Members.from_json(response).members
end

# POST cluster/member/update
def member_update
raise "unimplemented"
def member_update(id : UInt64, peer_urls : Array(String))
response = client.api.post("/cluster/member/update", {ID: id, peerURLs: peer_urls}).body
Model::Cluster::Members.from_json(response).members
end
end
Loading

0 comments on commit b43427e

Please sign in to comment.