what doesnt do anything must go
that sounds like someone
This commit is contained in:
@@ -100,7 +100,7 @@ wakey-control-plane state-stats
|
||||
List/revoke enroll tokens from CLI:
|
||||
|
||||
```sh
|
||||
wakey-control-plane list-enroll-tokens --include-expired
|
||||
wakey-control-plane list-enroll-tokens
|
||||
wakey-control-plane revoke-enroll-token --token enr-...
|
||||
wakey-control-plane revoke-agent --agent-id agent-...
|
||||
```
|
||||
@@ -108,7 +108,7 @@ wakey-control-plane revoke-agent --agent-id agent-...
|
||||
Machine-readable output is available:
|
||||
|
||||
```sh
|
||||
wakey-control-plane list-enroll-tokens --include-expired --json
|
||||
wakey-control-plane list-enroll-tokens --json
|
||||
wakey-control-plane state-stats --json
|
||||
```
|
||||
|
||||
@@ -189,7 +189,7 @@ During daemon control/state operations:
|
||||
Control-plane admin API includes token management endpoints:
|
||||
|
||||
- `POST /api/v1/control/enroll-token?ttl_seconds=<n>`
|
||||
- `GET /api/v1/control/enroll-tokens?include_expired=true|false`
|
||||
- `GET /api/v1/control/enroll-tokens`
|
||||
- `DELETE /api/v1/control/enroll-tokens/{token}`
|
||||
- `GET /api/v1/control/audit/events?agent_id=<id>&event_type=<type>&limit=<n>`
|
||||
- `GET /api/v1/control/alerts?lookback_seconds=900`
|
||||
|
||||
+2
-6
@@ -111,12 +111,8 @@ export function fetchAudit(limit = 50): Promise<AuditEvent[]> {
|
||||
return request<AuditEvent[]>(`/api/v1/control/audit/events?limit=${limit}`);
|
||||
}
|
||||
|
||||
export function fetchEnrollTokens(
|
||||
includeExpired = false,
|
||||
): Promise<EnrollTokenStatus[]> {
|
||||
return request<EnrollTokenStatus[]>(
|
||||
`/api/v1/control/enroll-tokens?include_expired=${includeExpired ? "true" : "false"}`,
|
||||
);
|
||||
export function fetchEnrollTokens(): Promise<EnrollTokenStatus[]> {
|
||||
return request<EnrollTokenStatus[]>(`/api/v1/control/enroll-tokens`);
|
||||
}
|
||||
|
||||
export function issueEnrollToken(
|
||||
|
||||
@@ -10,13 +10,6 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
function formatUnix(unix: number): string {
|
||||
return new Date(unix * 1000).toLocaleString();
|
||||
@@ -24,7 +17,6 @@ function formatUnix(unix: number): string {
|
||||
|
||||
export function TokensPage() {
|
||||
const [tokens, setTokens] = useState<EnrollTokenStatus[]>([]);
|
||||
const [includeExpired, setIncludeExpired] = useState(false);
|
||||
const [ttlSeconds, setTtlSeconds] = useState("86400");
|
||||
const [status, setStatus] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
@@ -39,7 +31,7 @@ export function TokensPage() {
|
||||
setBusy(true);
|
||||
setError("");
|
||||
try {
|
||||
const next = await fetchEnrollTokens(includeExpired);
|
||||
const next = await fetchEnrollTokens();
|
||||
setTokens(next);
|
||||
} catch (err) {
|
||||
setError(String(err));
|
||||
@@ -85,7 +77,7 @@ export function TokensPage() {
|
||||
|
||||
useEffect(() => {
|
||||
void load();
|
||||
}, [includeExpired]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className="grid gap-3 xl:grid-cols-2">
|
||||
@@ -102,21 +94,6 @@ export function TokensPage() {
|
||||
</Button>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<label className="grid gap-1 text-sm text-muted-foreground">
|
||||
<span>Include expired</span>
|
||||
<Select
|
||||
value={includeExpired ? "yes" : "no"}
|
||||
onValueChange={(value) => setIncludeExpired(value === "yes")}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Choose option" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="no">No</SelectItem>
|
||||
<SelectItem value="yes">Yes</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{activeCount} active, {tokens.length} shown
|
||||
</p>
|
||||
|
||||
@@ -32,11 +32,6 @@ pub struct IssueEnrollTokenQuery {
|
||||
pub ttl_seconds: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ListEnrollTokenQuery {
|
||||
pub include_expired: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct EnrollTokenStatus {
|
||||
pub enroll_token: String,
|
||||
@@ -200,10 +195,8 @@ pub async fn issue_enroll_token(
|
||||
|
||||
pub async fn list_enroll_tokens(
|
||||
State(state): State<AppState>,
|
||||
Query(query): Query<ListEnrollTokenQuery>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
let include_expired = query.include_expired.unwrap_or(false);
|
||||
match state.store.list_enroll_tokens(include_expired).await {
|
||||
match state.store.list_enroll_tokens().await {
|
||||
Ok(tokens) => {
|
||||
if let Err(err) = state
|
||||
.store
|
||||
@@ -217,7 +210,6 @@ pub async fn list_enroll_tokens(
|
||||
latency_ms: None,
|
||||
message: "listed enroll tokens".into(),
|
||||
metadata: serde_json::json!({
|
||||
"include_expired": include_expired,
|
||||
"count": tokens.len(),
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -160,9 +160,6 @@ pub struct ListEnrollTokensArgs {
|
||||
#[arg(long)]
|
||||
pub public_url: Option<String>,
|
||||
|
||||
#[arg(long)]
|
||||
pub include_expired: bool,
|
||||
|
||||
#[arg(long)]
|
||||
pub json: bool,
|
||||
|
||||
|
||||
@@ -74,10 +74,7 @@ pub async fn issue_enroll_token(args: IssueEnrollTokenArgs) -> Result<()> {
|
||||
pub async fn list_enroll_tokens(args: ListEnrollTokensArgs) -> Result<()> {
|
||||
let settings = config::resolve_list_enroll_token_settings(&args)?;
|
||||
if let Some(base) = settings.public_url.as_deref() {
|
||||
let url = format!(
|
||||
"{}/api/v1/control/enroll-tokens?include_expired={}",
|
||||
base, args.include_expired
|
||||
);
|
||||
let url = format!("{}/api/v1/control/enroll-tokens", base);
|
||||
let response = reqwest::get(&url)
|
||||
.await
|
||||
.with_context(|| format!("failed to call {url}"))?;
|
||||
@@ -118,7 +115,7 @@ pub async fn list_enroll_tokens(args: ListEnrollTokensArgs) -> Result<()> {
|
||||
settings.state_file.display()
|
||||
)
|
||||
})?;
|
||||
let tokens = store.list_enroll_tokens(args.include_expired).await?;
|
||||
let tokens = store.list_enroll_tokens().await?;
|
||||
if args.json {
|
||||
println!(
|
||||
"{}",
|
||||
|
||||
@@ -152,7 +152,7 @@ impl Store {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn list_enroll_tokens(&self, include_expired: bool) -> Result<Vec<EnrollTokenInfo>> {
|
||||
pub async fn list_enroll_tokens(&self) -> Result<Vec<EnrollTokenInfo>> {
|
||||
let now = now_unix();
|
||||
let mut out = Vec::new();
|
||||
for item in self.enroll_tokens.iter() {
|
||||
@@ -160,9 +160,6 @@ impl Store {
|
||||
let expires_at_unix =
|
||||
decode_expiry(value.as_ref()).context("failed decoding token expiry")?;
|
||||
let expired = expires_at_unix <= now;
|
||||
if !include_expired && expired {
|
||||
continue;
|
||||
}
|
||||
let enroll_token =
|
||||
String::from_utf8(token.to_vec()).context("invalid utf-8 enroll token in db")?;
|
||||
out.push(EnrollTokenInfo {
|
||||
@@ -836,9 +833,11 @@ mod tests {
|
||||
assert!(cleared);
|
||||
|
||||
let listed = store.list_agents_with_nicknames().await;
|
||||
assert!(listed
|
||||
.iter()
|
||||
.any(|(id, name)| id == &issued.agent_id && name.is_none()));
|
||||
assert!(
|
||||
listed
|
||||
.iter()
|
||||
.any(|(id, name)| id == &issued.agent_id && name.is_none())
|
||||
);
|
||||
|
||||
cleanup_dir(&dir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user