Skip to content

Commit

Permalink
feat: implement role commands in xlinectl
Browse files Browse the repository at this point in the history
Signed-off-by: bsbds <[email protected]>
  • Loading branch information
bsbds committed Oct 10, 2023
1 parent c7526ff commit 51c19bc
Show file tree
Hide file tree
Showing 14 changed files with 603 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions xline-client/src/types/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl From<AuthUserRevokeRoleRequest> for xlineapi::AuthUserRevokeRoleRequest {
}

/// Request for `AuthRoleAdd`
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct AuthRoleAddRequest {
/// Inner request
pub(crate) inner: xlineapi::AuthRoleAddRequest,
Expand All @@ -239,7 +239,7 @@ impl From<AuthRoleAddRequest> for xlineapi::AuthRoleAddRequest {
}

/// Request for `AuthRoleGet`
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct AuthRoleGetRequest {
/// Inner request
pub(crate) inner: xlineapi::AuthRoleGetRequest,
Expand All @@ -265,7 +265,7 @@ impl From<AuthRoleGetRequest> for xlineapi::AuthRoleGetRequest {
}

/// Request for `AuthRoleDelete`
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct AuthRoleDeleteRequest {
/// Inner request
pub(crate) inner: xlineapi::AuthRoleDeleteRequest,
Expand All @@ -291,7 +291,7 @@ impl From<AuthRoleDeleteRequest> for xlineapi::AuthRoleDeleteRequest {
}

/// Request for `AuthRoleGrantPermission`
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct AuthRoleGrantPermissionRequest {
/// Inner request
pub(crate) inner: xlineapi::AuthRoleGrantPermissionRequest,
Expand Down Expand Up @@ -321,7 +321,7 @@ impl From<AuthRoleGrantPermissionRequest> for xlineapi::AuthRoleGrantPermissionR
}

/// Request for `AuthRoleRevokePermission`
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct AuthRoleRevokePermissionRequest {
/// Inner request
pub(crate) inner: xlineapi::AuthRoleRevokePermissionRequest,
Expand Down
1 change: 1 addition & 0 deletions xlinectl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ thiserror = "1.0.37"
tokio = { version = "1", features = ["rt"] }
tonic = "0.9.2"
utils = { path = "../utils" }
xline = { path = "../xline" }
xline-client = { path = "../xline-client" }
xlineapi = { path = "../xlineapi" }
151 changes: 149 additions & 2 deletions xlinectl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,18 +436,165 @@ auth status
```

### ROLE
Role related commands

### ROLE ADD
Create a new role

#### Usage

```bash
add <name>
```

#### Output

```
Role added
```

#### Examples

```bash
# add a new role named 'foo'
./xlinectl --user=root:root role add foo
Role added
```

### ROLE GET
List role information

#### Usage

```bash
get <name>
```

#### Output

```
Permmision: <perm_type0>
<key0>
[range_end0]
Permmision: <perm_type1>
<key1>
[range_end1]
...
```

#### Examples

```bash
./xlinectl --user=root:root grant_perm foo Read key
./xlinectl --user=root:root grant_perm foo ReadWrite key1
# Get role named 'foo'
./xlinectl --user=root:root role get foo
Permission: Read
key
Permission: Read
key1
```

### ROLE DELETE
Delete a role

#### Usage

```bash
delete <name>
```

#### Output

```
Role deleted
```

#### Examples
```bash
./xlinectl --user=root:root role add foo
# delete the role named `foo`
./xlinectl --user=root:root role delete foo
Role deleted
```

### ROLE LIST
List all roles

#### Usage

```bash
list
```

#### Output

```
<role0>
<role1>
...
```

#### Examples

```bash
./xlinectl --user=root:root role add foo
./xlinectl --user=root:root role add foo1
# list all roles
./xlinectl --user=root:root role list
foo
foo1
```

### ROLE GRANT-PERMISSION
Grant permission to a role, including Read, Write or ReadWrite

#### Usage

```bash
grant_perm [options] <name> <perm_type> <key> [range_end]
```

#### Options
- prefix -- Get keys with matching prefix
- from_key -- Get keys that are greater than or equal to the given key using byte compare (conflicts with `range_end`)

#### Output

```
Permission granted
```

#### Examples

```bash
# Grant read permission to role 'foo' for key 'bar' with read permission
./xlinectl --user=root:root role grant_perm foo READ bar
Permission granted
```

### ROLE REVOKE-PERMISSION
Revoke permission from a role

#### Usage

```bash
revoke_perm <name> <key> [range_end]
```

#### Output

```
Permission revoked
```

#### Examples

```bash
# Revoke permission from role 'foo' for the range from 'bar' to 'bar2'
./xlinectl --user=root:root role revoke_perm foo bar bar2
Permission revoked
```

### USER

Expand Down Expand Up @@ -502,8 +649,8 @@ get [options] <name>

#### Examples
```bash
./etcdctl --user=root:root user grant_role foo role0
./etcdctl --user=root:root user grant_role foo role1
./xlinectl --user=root:root user grant_role foo role0
./xlinectl --user=root:root user grant_role foo role1
# Get a user named `foo`
./xlinectl --user=root:root user get foo
role0
Expand Down
2 changes: 2 additions & 0 deletions xlinectl/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub(crate) mod get;
pub(crate) mod lease;
/// Put command
pub(crate) mod put;
/// Role command
pub(crate) mod role;
/// Snapshot command
pub(crate) mod snapshot;
/// User command
Expand Down
46 changes: 46 additions & 0 deletions xlinectl/src/command/role/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use clap::{arg, ArgMatches, Command};
use xline_client::{error::Result, types::auth::AuthRoleAddRequest, Client};

use crate::utils::printer::Printer;

/// Definition of `add` command
pub(super) fn command() -> Command {
Command::new("add")
.about("Create a new role")
.arg(arg!(<name> "The name of the role"))
}

/// Build request from matches
pub(super) fn build_request(matches: &ArgMatches) -> AuthRoleAddRequest {
let name = matches.get_one::<String>("name").expect("required");
AuthRoleAddRequest::new(name)
}

/// Execute the command
pub(super) async fn execute(client: &mut Client, matches: &ArgMatches) -> Result<()> {
let req = build_request(matches);
let resp = client.auth_client().role_add(req).await?;
resp.print();

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::test_case_struct;

test_case_struct!(AuthRoleAddRequest);

#[test]
fn valid() {
let test_cases = vec![TestCase::new(
vec!["add", "Admin"],
Some(AuthRoleAddRequest::new("Admin")),
)];

for case in test_cases {
case.run_test();
}
}
}
46 changes: 46 additions & 0 deletions xlinectl/src/command/role/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use clap::{arg, ArgMatches, Command};
use xline_client::{error::Result, types::auth::AuthRoleDeleteRequest, Client};

use crate::utils::printer::Printer;

/// Definition of `delete` command
pub(super) fn command() -> Command {
Command::new("delete")
.about("delete a role")
.arg(arg!(<name> "The name of the role"))
}

/// Build request from matches
pub(super) fn build_request(matches: &ArgMatches) -> AuthRoleDeleteRequest {
let name = matches.get_one::<String>("name").expect("required");
AuthRoleDeleteRequest::new(name)
}

/// Execute the command
pub(super) async fn execute(client: &mut Client, matches: &ArgMatches) -> Result<()> {
let req = build_request(matches);
let resp = client.auth_client().role_delete(req).await?;
resp.print();

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::test_case_struct;

test_case_struct!(AuthRoleDeleteRequest);

#[test]
fn valid() {
let test_cases = vec![TestCase::new(
vec!["delete", "Admin"],
Some(AuthRoleDeleteRequest::new("Admin")),
)];

for case in test_cases {
case.run_test();
}
}
}
46 changes: 46 additions & 0 deletions xlinectl/src/command/role/get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use clap::{arg, ArgMatches, Command};
use xline_client::{error::Result, types::auth::AuthRoleGetRequest, Client};

use crate::utils::printer::Printer;

/// Definition of `get` command
pub(super) fn command() -> Command {
Command::new("get")
.about("Get a new role")
.arg(arg!(<name> "The name of the role"))
}

/// Build request from matches
pub(super) fn build_request(matches: &ArgMatches) -> AuthRoleGetRequest {
let name = matches.get_one::<String>("name").expect("required");
AuthRoleGetRequest::new(name)
}

/// Execute the command
pub(super) async fn execute(client: &mut Client, matches: &ArgMatches) -> Result<()> {
let req = build_request(matches);
let resp = client.auth_client().role_get(req).await?;
resp.print();

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::test_case_struct;

test_case_struct!(AuthRoleGetRequest);

#[test]
fn valid() {
let test_cases = vec![TestCase::new(
vec!["get", "Admin"],
Some(AuthRoleGetRequest::new("Admin")),
)];

for case in test_cases {
case.run_test();
}
}
}
Loading

0 comments on commit 51c19bc

Please sign in to comment.