@opensoha/contracts 0.1.9 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/auth/catalog_generated.go +3 -3
- package/auth/catalog_test.go +35 -0
- package/auth/permission-catalog.json +19 -151
- package/compat/json-schema-ecosystem-0.1.0.json +1 -1
- package/compat/openapi-loose-boundaries-0.1.0.json +1 -5
- package/fixtures/openapi/DockerHostAgentCredentialsEnvelope/invalid/missing-runtime-token.json +9 -0
- package/fixtures/openapi/DockerHostAgentCredentialsEnvelope/valid/credentials.json +10 -0
- package/fixtures/openapi/DockerHostAgentEnrollmentRequest/invalid/short-token.json +4 -0
- package/fixtures/openapi/DockerHostAgentEnrollmentRequest/valid/enrollment.json +4 -0
- package/fixtures/openapi/DockerHostAgentInstallation/invalid/missing-command.json +6 -0
- package/fixtures/openapi/DockerHostAgentInstallation/valid/installation.json +7 -0
- package/fixtures/openapi/IdentityProvider/invalid/missing-id.json +9 -0
- package/fixtures/openapi/IdentityProvider/valid/current.json +12 -0
- package/fixtures/openapi/IdentityProvider/valid/v0.1.9.json +14 -0
- package/fixtures/openapi/MenuEnvelope/invalid/missing-data.json +1 -0
- package/fixtures/openapi/MenuEnvelope/valid/menu.json +13 -0
- package/fixtures/openapi/MenuInput/invalid/missing-icon.json +5 -0
- package/fixtures/openapi/MenuInput/valid/top-level.json +12 -0
- package/fixtures/openapi/MenuListEnvelope/invalid/items-object.json +3 -0
- package/fixtures/openapi/MenuListEnvelope/valid/tree.json +27 -0
- package/fixtures/openapi/OIDCClient/invalid/missing-grant-types.json +9 -0
- package/fixtures/openapi/OIDCClient/valid/current.json +19 -0
- package/fixtures/openapi/OIDCClient/valid/v0.1.9.json +10 -0
- package/fixtures/openapi/OIDCClientInput/invalid/empty-rules.json +5 -0
- package/fixtures/openapi/OIDCClientInput/valid/regex.json +4 -0
- package/fixtures/openapi/OIDCClientInput/valid/strict.json +4 -0
- package/fixtures/openapi/OIDCClientInput/valid/v0.1.9.json +7 -0
- package/fixtures/openapi/ObservabilityContext/invalid/missing-time-range.json +6 -0
- package/fixtures/openapi/ObservabilityContext/valid/scoped.json +27 -0
- package/fixtures/openapi/ObservabilityDashboardImportResultEnvelope/valid/imported.json +28 -1
- package/fixtures/openapi/ObservabilityDashboardPanelQueryInput/invalid/missing-time-to.json +6 -0
- package/fixtures/openapi/ObservabilityDashboardPanelQueryInput/valid/variables.json +8 -0
- package/fixtures/openapi/ObservabilityMetricCatalogEnvelope/invalid/missing-availability.json +10 -0
- package/fixtures/openapi/ObservabilityMetricCatalogEnvelope/valid/catalog.json +13 -0
- package/fixtures/openapi/ObservabilityQueryResultMeta/invalid/missing-state.json +3 -0
- package/fixtures/openapi/ObservabilityQueryResultMeta/valid/partial.json +15 -0
- package/fixtures/openapi/ObservabilityQuerySnapshot/invalid/missing-context.json +5 -0
- package/fixtures/openapi/ObservabilityQuerySnapshot/valid/prometheus.json +22 -0
- package/fixtures/openapi/ObservabilityServiceEnvelope/invalid/missing-status.json +12 -0
- package/fixtures/openapi/ObservabilityServiceEnvelope/valid/service.json +29 -0
- package/fixtures/openapi/ObservabilityServiceListEnvelope/invalid/missing-meta.json +3 -0
- package/fixtures/openapi/ObservabilityServiceListEnvelope/valid/services.json +39 -0
- package/fixtures/openapi/ObservabilityTopologyEnvelope/invalid/missing-edge-status.json +10 -0
- package/fixtures/openapi/ObservabilityTopologyEnvelope/valid/topology.json +22 -0
- package/fixtures/openapi/ScopeGrantEnvelope/invalid/missing-id.json +13 -0
- package/fixtures/openapi/ScopeGrantEnvelope/valid/platform.json +15 -0
- package/fixtures/openapi/ScopeGrantInput/invalid/missing-subject.json +7 -0
- package/fixtures/openapi/ScopeGrantInput/valid/delivery.json +11 -0
- package/fixtures/openapi/ScopeGrantListEnvelope/invalid/unknown-scope.json +16 -0
- package/fixtures/openapi/ScopeGrantListEnvelope/valid/list.json +18 -0
- package/gen/go/sohaapi/client.go +10 -1
- package/gen/go/sohaapi/client_test.go +47 -0
- package/gen/go/sohaapi/types.go +987 -93
- package/gen/ts/sohaapi/index.ts +1263 -48
- package/go.mod +1 -1
- package/openapi/soha-api.json +2501 -50
- package/openapi/soha-api.yaml +1398 -57
- package/openapi/spec_generated.go +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"items": [
|
|
3
|
+
{
|
|
4
|
+
"id": "settings",
|
|
5
|
+
"path": "/settings",
|
|
6
|
+
"labelZh": "设置中心",
|
|
7
|
+
"labelEn": "Settings",
|
|
8
|
+
"iconKey": "setting",
|
|
9
|
+
"section": "",
|
|
10
|
+
"sortOrder": 10,
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"children": [
|
|
13
|
+
{
|
|
14
|
+
"id": "settings-overview",
|
|
15
|
+
"parentId": "settings",
|
|
16
|
+
"path": "/settings/overview",
|
|
17
|
+
"labelZh": "设置总览",
|
|
18
|
+
"labelEn": "Settings Overview",
|
|
19
|
+
"iconKey": "dashboard",
|
|
20
|
+
"section": "",
|
|
21
|
+
"sortOrder": 10,
|
|
22
|
+
"enabled": true
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "client-2",
|
|
3
|
+
"providerId": "provider-1",
|
|
4
|
+
"clientId": "tenant-app",
|
|
5
|
+
"clientType": "public",
|
|
6
|
+
"redirectUris": [],
|
|
7
|
+
"grantTypes": ["authorization_code"],
|
|
8
|
+
"redirectUriRegexes": ["https://tenant-[a-z0-9]+\\.example\\.com/callback"],
|
|
9
|
+
"postLogoutRedirectUris": ["https://app.example.com/logout/callback"],
|
|
10
|
+
"allowedScopes": ["openid", "profile"],
|
|
11
|
+
"allowedGrantTypes": ["authorization_code"],
|
|
12
|
+
"requirePkce": true,
|
|
13
|
+
"accessTokenTtlSeconds": 900,
|
|
14
|
+
"idTokenTtlSeconds": 900,
|
|
15
|
+
"refreshTokenTtlSeconds": 0,
|
|
16
|
+
"status": "active",
|
|
17
|
+
"createdAt": "2026-08-01T00:00:00Z",
|
|
18
|
+
"updatedAt": "2026-08-01T00:00:00Z"
|
|
19
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "client-1",
|
|
3
|
+
"providerId": "provider-1",
|
|
4
|
+
"clientId": "grafana",
|
|
5
|
+
"redirectUris": ["https://grafana.example.com/login/oauth"],
|
|
6
|
+
"grantTypes": ["authorization_code", "refresh_token"],
|
|
7
|
+
"status": "active",
|
|
8
|
+
"createdAt": "2026-08-01T00:00:00Z",
|
|
9
|
+
"updatedAt": "2026-08-01T00:00:00Z"
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "v1",
|
|
3
|
+
"scope": {
|
|
4
|
+
"workspaceId": "default",
|
|
5
|
+
"clusterId": "cluster-1",
|
|
6
|
+
"environment": "production",
|
|
7
|
+
"namespace": "payments",
|
|
8
|
+
"service": "checkout-api"
|
|
9
|
+
},
|
|
10
|
+
"resource": {
|
|
11
|
+
"kind": "service",
|
|
12
|
+
"name": "checkout-api"
|
|
13
|
+
},
|
|
14
|
+
"timeRange": {
|
|
15
|
+
"from": "2026-08-13T00:00:00Z",
|
|
16
|
+
"to": "2026-08-13T01:00:00Z",
|
|
17
|
+
"timezone": "Asia/Shanghai"
|
|
18
|
+
},
|
|
19
|
+
"filter": {
|
|
20
|
+
"text": "error",
|
|
21
|
+
"labels": {
|
|
22
|
+
"deployment.environment.name": "production"
|
|
23
|
+
},
|
|
24
|
+
"traceId": "trace-1"
|
|
25
|
+
},
|
|
26
|
+
"scopeRestricted": true
|
|
27
|
+
}
|
|
@@ -4,8 +4,32 @@
|
|
|
4
4
|
"id": "dashboard:8b9f35ba-6870-4f34-b45f-6f601d8b8c35",
|
|
5
5
|
"name": "Kubernetes Overview",
|
|
6
6
|
"source": "grafana",
|
|
7
|
+
"sourceFormat": "classic",
|
|
7
8
|
"sourceSchemaVersion": 39,
|
|
9
|
+
"rawJson": "{\"title\":\"Kubernetes Overview\"}",
|
|
8
10
|
"tags": ["kubernetes"],
|
|
11
|
+
"variables": [
|
|
12
|
+
{
|
|
13
|
+
"name": "namespace",
|
|
14
|
+
"label": "Namespace",
|
|
15
|
+
"type": "custom",
|
|
16
|
+
"current": "default",
|
|
17
|
+
"options": ["default", "production"]
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"dataSourceBindings": [
|
|
21
|
+
{
|
|
22
|
+
"type": "prometheus",
|
|
23
|
+
"uid": "prom",
|
|
24
|
+
"dataSourceId": "prometheus-main"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"importWarnings": [
|
|
28
|
+
{
|
|
29
|
+
"code": "datasource_rebound",
|
|
30
|
+
"message": "Grafana data-source prom is mapped to prometheus-main."
|
|
31
|
+
}
|
|
32
|
+
],
|
|
9
33
|
"panels": [
|
|
10
34
|
{
|
|
11
35
|
"id": "1",
|
|
@@ -15,7 +39,10 @@
|
|
|
15
39
|
"targets": [
|
|
16
40
|
{
|
|
17
41
|
"refId": "A",
|
|
18
|
-
"expression": "sum(rate(container_cpu_usage_seconds_total[5m]))"
|
|
42
|
+
"expression": "sum(rate(container_cpu_usage_seconds_total{namespace=\"$namespace\"}[5m]))",
|
|
43
|
+
"dataSourceType": "prometheus",
|
|
44
|
+
"dataSourceUid": "prom",
|
|
45
|
+
"dataSourceId": "prometheus-main"
|
|
19
46
|
}
|
|
20
47
|
],
|
|
21
48
|
"queryable": true
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"items": [
|
|
3
|
+
{
|
|
4
|
+
"key": "http.server.request.duration",
|
|
5
|
+
"label": "HTTP server request duration",
|
|
6
|
+
"description": "Server request duration from OpenTelemetry HTTP semantic conventions.",
|
|
7
|
+
"unit": "s",
|
|
8
|
+
"semanticConvention": "http.server.request.duration",
|
|
9
|
+
"signal": "metrics",
|
|
10
|
+
"available": true
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"state": "partial",
|
|
3
|
+
"scopeRestricted": true,
|
|
4
|
+
"observedAt": "2026-08-13T01:00:02Z",
|
|
5
|
+
"durationMs": 42,
|
|
6
|
+
"warnings": ["One data source timed out."],
|
|
7
|
+
"errors": [
|
|
8
|
+
{
|
|
9
|
+
"code": "query_timeout",
|
|
10
|
+
"message": "The secondary source did not respond before the deadline.",
|
|
11
|
+
"retryable": true,
|
|
12
|
+
"sourceId": "secondary"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "v1",
|
|
3
|
+
"signal": "metrics",
|
|
4
|
+
"dataSourceId": "prometheus-main",
|
|
5
|
+
"backendType": "prometheus",
|
|
6
|
+
"context": {
|
|
7
|
+
"version": "v1",
|
|
8
|
+
"scope": {
|
|
9
|
+
"workspaceId": "default",
|
|
10
|
+
"clusterId": "cluster-1",
|
|
11
|
+
"namespace": "payments",
|
|
12
|
+
"service": "checkout-api"
|
|
13
|
+
},
|
|
14
|
+
"timeRange": {
|
|
15
|
+
"from": "2026-08-13T00:00:00Z",
|
|
16
|
+
"to": "2026-08-13T01:00:00Z"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"queryLanguage": "promql",
|
|
20
|
+
"query": "rate(http_server_request_duration_seconds_count[5m])",
|
|
21
|
+
"createdAt": "2026-08-13T01:00:01Z"
|
|
22
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"id": "checkout-api",
|
|
4
|
+
"name": "checkout-api",
|
|
5
|
+
"environment": "production",
|
|
6
|
+
"namespace": "payments",
|
|
7
|
+
"clusterIds": ["cluster-1"],
|
|
8
|
+
"status": "unknown",
|
|
9
|
+
"instances": [
|
|
10
|
+
{
|
|
11
|
+
"id": "checkout-api-7b8f",
|
|
12
|
+
"name": "checkout-api-7b8f",
|
|
13
|
+
"status": "unknown"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"endpoints": [
|
|
17
|
+
{
|
|
18
|
+
"id": "POST /checkout",
|
|
19
|
+
"name": "/checkout",
|
|
20
|
+
"method": "POST",
|
|
21
|
+
"status": "unknown"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"meta": {
|
|
26
|
+
"state": "success",
|
|
27
|
+
"observedAt": "2026-08-13T01:00:00Z"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"items": [
|
|
3
|
+
{
|
|
4
|
+
"id": "checkout-api",
|
|
5
|
+
"name": "checkout-api",
|
|
6
|
+
"environment": "production",
|
|
7
|
+
"namespace": "payments",
|
|
8
|
+
"clusterIds": ["cluster-1"],
|
|
9
|
+
"status": "degraded",
|
|
10
|
+
"requestRate": 125.5,
|
|
11
|
+
"errorRate": 0.023,
|
|
12
|
+
"latencyP95Ms": 412,
|
|
13
|
+
"lastSeenAt": "2026-08-13T01:00:00Z",
|
|
14
|
+
"instances": [
|
|
15
|
+
{
|
|
16
|
+
"id": "checkout-api-7b8f",
|
|
17
|
+
"name": "checkout-api-7b8f",
|
|
18
|
+
"status": "healthy",
|
|
19
|
+
"lastSeenAt": "2026-08-13T01:00:00Z"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"endpoints": [
|
|
23
|
+
{
|
|
24
|
+
"id": "POST /checkout",
|
|
25
|
+
"name": "/checkout",
|
|
26
|
+
"method": "POST",
|
|
27
|
+
"status": "degraded",
|
|
28
|
+
"requestRate": 125.5,
|
|
29
|
+
"errorRate": 0.023,
|
|
30
|
+
"latencyP95Ms": 412
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"meta": {
|
|
36
|
+
"state": "success",
|
|
37
|
+
"observedAt": "2026-08-13T01:00:00Z"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"nodes": [
|
|
4
|
+
{"serviceId": "checkout-api", "name": "checkout-api", "status": "degraded"},
|
|
5
|
+
{"serviceId": "payment-api", "name": "payment-api", "status": "healthy"}
|
|
6
|
+
],
|
|
7
|
+
"edges": [
|
|
8
|
+
{
|
|
9
|
+
"sourceServiceId": "checkout-api",
|
|
10
|
+
"targetServiceId": "payment-api",
|
|
11
|
+
"status": "degraded",
|
|
12
|
+
"requestRate": 88,
|
|
13
|
+
"errorRate": 0.031,
|
|
14
|
+
"latencyP95Ms": 510
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"beta": true,
|
|
18
|
+
"meta": {
|
|
19
|
+
"state": "success"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"subjectType": "team",
|
|
4
|
+
"subjectId": "platform-team",
|
|
5
|
+
"businessLineId": "",
|
|
6
|
+
"scopeType": "platform",
|
|
7
|
+
"role": "readonly",
|
|
8
|
+
"effect": "allow",
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"createdAt": "2026-08-13T08:00:00Z",
|
|
11
|
+
"updatedAt": "2026-08-13T08:00:00Z"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"id": "grant-123",
|
|
4
|
+
"subjectType": "team",
|
|
5
|
+
"subjectId": "platform-team",
|
|
6
|
+
"businessLineId": "",
|
|
7
|
+
"scopeType": "platform",
|
|
8
|
+
"clusterIds": ["cluster-prod"],
|
|
9
|
+
"role": "readonly",
|
|
10
|
+
"effect": "allow",
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"createdAt": "2026-08-13T08:00:00Z",
|
|
13
|
+
"updatedAt": "2026-08-13T08:00:00Z"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"items": [
|
|
3
|
+
{
|
|
4
|
+
"id": "grant-123",
|
|
5
|
+
"subjectType": "user",
|
|
6
|
+
"subjectId": "user-123",
|
|
7
|
+
"businessLineId": "payments",
|
|
8
|
+
"scopeType": "global",
|
|
9
|
+
"role": "developer",
|
|
10
|
+
"effect": "allow",
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"createdAt": "2026-08-13T08:00:00Z",
|
|
13
|
+
"updatedAt": "2026-08-13T08:00:00Z"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"items": [
|
|
3
|
+
{
|
|
4
|
+
"id": "grant-123",
|
|
5
|
+
"subjectType": "user",
|
|
6
|
+
"subjectId": "user-123",
|
|
7
|
+
"businessLineId": "payments",
|
|
8
|
+
"environmentIds": [],
|
|
9
|
+
"applicationIds": ["checkout-api"],
|
|
10
|
+
"scopeType": "delivery",
|
|
11
|
+
"role": "developer",
|
|
12
|
+
"effect": "allow",
|
|
13
|
+
"enabled": true,
|
|
14
|
+
"createdAt": "2026-08-13T08:00:00Z",
|
|
15
|
+
"updatedAt": "2026-08-13T08:00:00Z"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
package/gen/go/sohaapi/client.go
CHANGED
|
@@ -14,7 +14,7 @@ import (
|
|
|
14
14
|
"time"
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
const defaultUserAgent = "opensoha-contracts/0.1.
|
|
17
|
+
const defaultUserAgent = "opensoha-contracts/0.1.12"
|
|
18
18
|
|
|
19
19
|
type Client struct {
|
|
20
20
|
BaseURL string
|
|
@@ -404,6 +404,15 @@ func (c *Client) ClaimDockerOperation(ctx context.Context, req DockerOperationCl
|
|
|
404
404
|
return out.Data, nil
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
func (c *Client) ExchangeDockerHostAgentEnrollment(ctx context.Context, operationID string, req DockerHostAgentEnrollmentRequest) (DockerHostAgentCredentials, error) {
|
|
408
|
+
var out DockerHostAgentCredentialsEnvelope
|
|
409
|
+
path := "/docker/agent-installations/" + url.PathEscape(strings.TrimSpace(operationID)) + "/enroll"
|
|
410
|
+
if err := c.doJSON(ctx, http.MethodPost, path, false, req, &out); err != nil {
|
|
411
|
+
return DockerHostAgentCredentials{}, err
|
|
412
|
+
}
|
|
413
|
+
return out.Data, nil
|
|
414
|
+
}
|
|
415
|
+
|
|
407
416
|
func (c *Client) GetDockerOperationRunnerStatus(ctx context.Context, operationID string) (DockerOperation, error) {
|
|
408
417
|
var out DockerOperationEnvelope
|
|
409
418
|
path := "/docker/operations/" + url.PathEscape(strings.TrimSpace(operationID)) + "/runner-status"
|
|
@@ -40,6 +40,24 @@ func TestObservabilityCredentialKeyLegacyTypes(t *testing.T) {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
func TestSAMLAttributeMappingLegacyConstants(t *testing.T) {
|
|
44
|
+
targets := map[SAMLAttributeMappingTarget]string{
|
|
45
|
+
Subject: "subject",
|
|
46
|
+
Username: "username",
|
|
47
|
+
Email: "email",
|
|
48
|
+
DisplayName: "displayName",
|
|
49
|
+
Role: "role",
|
|
50
|
+
Organization: "organization",
|
|
51
|
+
Team: "team",
|
|
52
|
+
Project: "project",
|
|
53
|
+
}
|
|
54
|
+
for target, want := range targets {
|
|
55
|
+
if string(target) != want || !target.Valid() {
|
|
56
|
+
t.Fatalf("SAMLAttributeMappingTarget %q is not the compatible value %q", target, want)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
43
61
|
func TestSystemHealthAndReadinessUsePublicRequests(t *testing.T) {
|
|
44
62
|
cases := []struct {
|
|
45
63
|
name string
|
|
@@ -125,6 +143,35 @@ func TestRunnerClaimClientsAcceptNoContent(t *testing.T) {
|
|
|
125
143
|
}
|
|
126
144
|
}
|
|
127
145
|
|
|
146
|
+
func TestExchangeDockerHostAgentEnrollmentIsPublicAndReturnsCredentials(t *testing.T) {
|
|
147
|
+
issuedAt := time.Now().UTC().Truncate(time.Second)
|
|
148
|
+
client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
|
149
|
+
assertPublicRequest(t, r, http.MethodPost, "/api/v1/docker/agent-installations/operation-1/enroll")
|
|
150
|
+
request := decodeJSONRequestBody[DockerHostAgentEnrollmentRequest](t, r)
|
|
151
|
+
if request.AgentID != "host-1" || request.EnrollmentToken != "enrollment-secret-0123456789012345" {
|
|
152
|
+
t.Fatalf("enrollment request = %#v", request)
|
|
153
|
+
}
|
|
154
|
+
w.Header().Set("Cache-Control", "no-store")
|
|
155
|
+
w.WriteHeader(http.StatusCreated)
|
|
156
|
+
writeJSON(t, w, map[string]any{"data": map[string]any{
|
|
157
|
+
"hostId": "host-1", "operationId": "operation-1", "agentId": "host-1",
|
|
158
|
+
"agentBearerToken": "agent-secret-012345678901234567890",
|
|
159
|
+
"runtimeBearerToken": "runtime-secret-012345678901234567",
|
|
160
|
+
"issuedAt": issuedAt,
|
|
161
|
+
}})
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
credentials, err := client.ExchangeDockerHostAgentEnrollment(context.Background(), "operation-1", DockerHostAgentEnrollmentRequest{
|
|
165
|
+
AgentID: "host-1", EnrollmentToken: "enrollment-secret-0123456789012345",
|
|
166
|
+
})
|
|
167
|
+
if err != nil {
|
|
168
|
+
t.Fatalf("exchange enrollment: %v", err)
|
|
169
|
+
}
|
|
170
|
+
if credentials.HostID != "host-1" || credentials.OperationID != "operation-1" || credentials.RuntimeBearerToken == "" || credentials.AgentBearerToken == "" {
|
|
171
|
+
t.Fatalf("credentials = %#v", credentials)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
128
175
|
func TestRedeemSecretLeaseSendsRunnerBindingHeaders(t *testing.T) {
|
|
129
176
|
client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
|
130
177
|
assertCommonRequest(t, r, http.MethodPost, "/api/v1/runner/secret-leases/lease%2Fone/redeem")
|