@bifos/nhncloud-cli 0.10.1 → 0.12.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bifos/nhncloud-cli",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "description": "CLI tool for NHN Cloud services — AI agent & terminal friendly",
5
5
  "keywords": [
6
6
  "nhncloud",
@@ -1,65 +1,37 @@
1
1
  ---
2
2
  name: nhncloud-cli
3
- description: NHN Cloud 서비스 CLI. commands --json catalog, configure, Log & Crash(logncrash search/send/export), Deploy(deploy run/artifacts/server-groups/histories/binary-groups/binaries/upload/download), Compute(instance), VPC/network, Block Storage(volume), Floating IP(floatingip), NHN Container Registry(ncr), NHN Kubernetes Service(nks supports/cluster/nodegroup/addon/kubeconfig), NHN Container Service(ncs template/workload 조회·생성·변경·실행제어, malware 검사 설정·결과 조회) 등 NHN Cloud API를 터미널과 AI 에이전트에서 호출한다.
3
+ description: >-
4
+ NHN Cloud 리소스를 nhncloud CLI로 조회·생성·변경·삭제하거나,
5
+ configure·profile·출력 형식·종료 코드·명령 문법을 확인할 때 사용한다.
6
+ Log & Crash, Deploy, Compute, Network, Block Storage, Floating IP,
7
+ Load Balancer, NCR, NKS, NCS 작업을 서비스별 참조와 명령 카탈로그로 안내한다.
4
8
  ---
5
9
 
6
10
  # nhncloud-cli
7
11
 
8
- NHN Cloud 서비스를 AWS CLI 방식으로 호출하는 TypeScript CLI다.
9
- 이 파일은 router다.
10
- 작업하려는 서비스에 맞는 reference를 먼저 읽고, 필요한 명령은 `--json`으로 확인한다.
11
-
12
- ## 먼저 읽을 것
13
-
14
- | 상황 | 읽을 reference |
15
- |------|----------------|
16
- | 명령 경로, 인수, option metadata 확인 | `nhncloud commands --json` 실행 후 필요한 reference 선택 |
17
- | 설치, configure, profile, 출력 모드, 에러 코드, 자동화 기본 규칙 | [common.md](references/common.md) |
18
- | Log & Crash 검색, scroll export, 로그 전송 | [logncrash.md](references/logncrash.md) |
19
- | Deploy 실행, 배포 조회, 바이너리 업로드/다운로드 | [deploy.md](references/deploy.md) |
20
- | Compute instance, network, volume, floatingip | [iaas.md](references/iaas.md) |
21
- | NCR 레지스트리, 이미지, 태그 조회 | [ncr.md](references/ncr.md) |
22
- | NKS 클러스터, 노드 그룹, 애드온, kubeconfig | [nks.md](references/nks.md) |
23
- | NCS template, workload 조회·생성·변경·실행제어, malware 검사 설정·결과 조회 | [ncs.md](references/ncs.md) |
24
- | 인증 실패, profile 누락, region mismatch, JSON shape 혼동, scroll 제한 | [troubleshooting.md](references/troubleshooting.md) |
25
-
26
- ## 공통 우선 규칙
27
-
28
- - 구조화 출력이 필요하면 `--json`을 우선 사용한다.
29
- - 스크립트 체이닝은 해당 명령이 `--quiet` 식별자 출력을 문서화했는지 확인한 뒤 사용한다.
30
- - profile은 기본값에 의존하지 말고 가능하면 `--profile <name>`을 명시한다.
31
- - IaaS 계열(`instance`, `network`, `volume`, `floatingip`, `nks`)은 region이 중요하면 `--region <region>`을 명시한다.
32
- - 삭제, 제거, 비용 발생, 리소스 생성 같은 파괴적/쓰기 명령은 `--yes` 없으면 대화형 confirm이 있을 수 있다.
33
- - 데이터는 stdout, 진행 상황과 에러는 stderr에 출력한다.
34
- - 비밀값, appkey, tenantId, 실제 instance/network id는 문서나 이슈에 그대로 쓰지 않고 placeholder를 사용한다.
35
-
36
- ## 빠른 시작
37
-
38
- ```bash
39
- npm install -g @bifos/nhncloud-cli
40
- nhncloud configure
41
- nhncloud logncrash search --query '*' --from 1h --to now --json
42
- ```
43
-
44
- ## 주요 명령군
45
-
46
- | 명령군 | 용도 |
47
- |--------|------|
48
- | `configure` | 자격증명 설정 마법사와 비대화형 profile 저장 |
49
- | `logncrash` | 로그 검색, 대량 export, collector 전송 |
50
- | `deploy` | NHN Cloud Deploy 실행과 배포/바이너리 조회·전송 |
51
- | `instance` | Compute 인스턴스, flavor, image, keypair, volume attach 관리 |
52
- | `network` | VPC와 subnet 조회 |
53
- | `volume` | Block Storage volume 조회·생성 |
54
- | `floatingip` | Floating IP 조회·발급·삭제 |
55
- | `ncr` | Container Registry registry/image/tag 조회 |
56
- | `nks` | Kubernetes cluster/nodegroup/addon/kubeconfig 관리 |
57
- | `ncs` | Container Service template/workload 조회·생성·변경·실행제어, malware 검사 설정·결과 조회 |
58
-
59
- ## 안전한 탐색 순서
60
-
61
- 1. [common.md](references/common.md)에서 profile과 출력 모드를 확인한다.
62
- 2. 대상 서비스 reference를 읽는다.
63
- 3. 조회/discovery 명령을 `--json`으로 먼저 실행한다.
64
- 4. 쓰기 명령은 대상 id, region, profile, `--yes`, payload file을 명시한다.
65
- 5. 실패하면 [troubleshooting.md](references/troubleshooting.md)의 exit code와 서비스별 인증 모델을 대조한다.
12
+ ## 실행 순서
13
+
14
+ 1. 아래 표에서 대상 서비스의 reference 하나만 먼저 읽는다.
15
+ 2. 정확한 경로·인수·옵션이 필요하면 `nhncloud commands --json`에서 해당 명령을 찾는다.
16
+ 3. 조회 명령을 `--json`으로 실행해 대상 식별자와 현재 상태를 확인한다.
17
+ 4. 쓰기 명령은 대상, `--profile`, 필요한 `--region`을 명시하고, 명령이 지원하면 `--yes`를 API 호출 전에 전달한다.
18
+ 5. 결과는 stdout의 구조화 데이터로 판정하고 stderr는 진행 상황과 진단에 사용한다.
19
+ 6. 실패하면 [troubleshooting.md](references/troubleshooting.md)에서 종료 코드와 인증 모델을 확인한다.
20
+
21
+ `--quiet`는 해당 명령이 식별자 출력을 문서화한 경우에만 사용한다.
22
+ 명령 문법이나 응답 형태를 추측하지 않는다.
23
+ 비밀값과 실제 사용자 리소스 ID는 문서·이슈·보고서에 남기지 않고 placeholder로 바꾼다.
24
+
25
+ ## 참조 라우터
26
+
27
+ | 작업 | 읽을 파일 |
28
+ |---|---|
29
+ | 설치, `configure`, profile, 출력 모드, 명령 카탈로그, 종료 코드 | [common.md](references/common.md) |
30
+ | Log & Crash Search v3 커서 검색·scroll 대량 추출·collector 전송 | [logncrash.md](references/logncrash.md) |
31
+ | Deploy 실행·조회·바이너리 전송 | [deploy.md](references/deploy.md) |
32
+ | Compute, VPC, Block Storage, Floating IP | [iaas.md](references/iaas.md) |
33
+ | Load Balancer와 IP ACL | [loadbalancer.md](references/loadbalancer.md) |
34
+ | Container Registry | [ncr.md](references/ncr.md) |
35
+ | Kubernetes Service | [nks.md](references/nks.md) |
36
+ | Container Service | [ncs.md](references/ncs.md) |
37
+ | 인증·profile·region·출력·검색 제한 문제 해결 | [troubleshooting.md](references/troubleshooting.md) |
@@ -24,18 +24,39 @@ CI나 자동화에서는 flag로 비대화형 저장을 한다.
24
24
  ```bash
25
25
  nhncloud configure \
26
26
  --uak-id <uak-id> --uak-secret <uak-secret> \
27
- --logncrash-appkey <appkey> --logncrash-secret <secret> \
27
+ --logncrash-appkey <appkey> \
28
28
  --ncr-appkey <appkey> \
29
29
  --no-verify
30
30
  ```
31
31
 
32
+ Log & Crash Search v3는 서비스 appkey와 profile 공통 UAK를 함께 사용한다.
33
+ CLI가 UAK를 OAuth 토큰으로 교환하므로 별도 logncrash secret은 저장하지 않는다.
34
+
35
+ ```json
36
+ {
37
+ "version": 1,
38
+ "profiles": {
39
+ "default": {
40
+ "userAccessKey": {
41
+ "id": "<uak-id>",
42
+ "secret": "<uak-secret>"
43
+ },
44
+ "logncrash": {
45
+ "appkey": "<appkey>"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
32
52
  주요 옵션:
33
53
 
34
54
  | 옵션 | 설명 |
35
55
  |------|------|
36
56
  | `--profile <name>` | 대상 profile. 기본값은 `default` |
37
57
  | `--uak-id <id>` / `--uak-secret <secret>` | 공통 User Access Key |
38
- | `--logncrash-appkey <key>` / `--logncrash-secret <secret>` | Log & Crash 검색 자격증명 |
58
+ | `--logncrash-appkey <key>` | Log & Crash 서비스 appkey |
59
+ | `--logncrash-secret <secret>` | 폐기 예정 호환 옵션. 경고 후 사용·저장하지 않음 |
39
60
  | `--ncr-appkey <key>` | NCR appkey |
40
61
  | `--iaas-tenant-id <id>` / `--iaas-username <name>` / `--iaas-password <password>` | IaaS/NKS 자격증명 |
41
62
  | `--iaas-region <region>` | IaaS 기본 region |
@@ -85,7 +106,7 @@ AI 에이전트는 먼저 `commands --json`으로 실제 command path와 option
85
106
  | 명령 | `--json` 출력 shape |
86
107
  |------|---------------------|
87
108
  | `commands` | `{ commands: [{ path, description, arguments, options, subcommands }] }` |
88
- | `logncrash search` | `{ totalItems, pageNumber, pageSize, data }` |
109
+ | `logncrash search` | `{ totalItems, pageNumber, pageSize, data, nextCursor? }` |
89
110
  | `deploy binary-groups` | `binaryGroups` wrapper를 언랩한 배열 |
90
111
  | `deploy binaries` | `{ totalCount, binaries }` |
91
112
  | `instance list` | `servers` wrapper를 언랩한 server 배열 |
@@ -0,0 +1,237 @@
1
+ # Load Balancer Reference
2
+
3
+ `loadbalancer` 명령군은 Load Balancer와 IP ACL 그룹·대상을 조회하고 관리한다.
4
+ `network`와 같은 IaaS 자격증명, Keystone 토큰, network endpoint를 공유한다.
5
+ region이 중요하면 `--region <region>`을 명시한다.
6
+
7
+ ## 탐색 순서
8
+
9
+ 자동화와 AI 에이전트는 실제 명령 표면을 확인한 뒤 목록에서 UUID를 찾는다.
10
+
11
+ ```bash
12
+ nhncloud commands --json \
13
+ | jq '.commands[] | select(.path|startswith("loadbalancer"))'
14
+
15
+ nhncloud loadbalancer list --profile <profile> --region <region> --json
16
+ nhncloud loadbalancer ipacl list --profile <profile> --region <region> --json
17
+ nhncloud loadbalancer ipacl target list <group> \
18
+ --profile <profile> \
19
+ --region <region> \
20
+ --json
21
+ ```
22
+
23
+ ## 명령
24
+
25
+ | 명령 | 용도 | 기본 테이블 컬럼 |
26
+ |------|------|------------------|
27
+ | `loadbalancer list` | Load Balancer 목록 조회 | `id`, `name`, `vip_address`, `provisioning_status`, `operating_status`, `ipacl_group_action` |
28
+ | `loadbalancer get <loadbalancer>` | 이름 또는 UUID로 단건 조회 | `field`, `value` |
29
+ | `loadbalancer ipacl list` | IP ACL 그룹 목록 조회 | `id`, `name`, `action`, `ipacl_target_count`, `loadbalancer_count` |
30
+ | `loadbalancer ipacl get <group>` | 이름 또는 UUID로 IP ACL 그룹 단건 조회 | `field`, `value` |
31
+ | `loadbalancer ipacl target list <group>` | 그룹의 IP ACL 대상 목록 조회 | `id`, `cidr_address`, `description`, `ipacl_group_id` |
32
+ | `loadbalancer ipacl create` | IP ACL 그룹 생성 | `field`, `value` |
33
+ | `loadbalancer ipacl delete <group>` | IP ACL 그룹과 하위 대상·연결 규칙 삭제 | `field`, `value` |
34
+ | `loadbalancer ipacl target add <group>` | 대상 추가 후 관련 Load Balancer 재바인딩 | `field`, `value` |
35
+ | `loadbalancer ipacl target remove <target-id>` | 대상 삭제 후 관련 Load Balancer 재바인딩 | `field`, `value` |
36
+ | `loadbalancer set-ipacl <loadbalancer>` | IP ACL 그룹 연결 전체 교체 | `field`, `value` |
37
+ | `loadbalancer clear-ipacl <loadbalancer>` | IP ACL 그룹 연결 전체 해제 | `field`, `value` |
38
+
39
+ 단건 Load Balancer 테이블에는 `id`, `name`, `vip_address`, `provisioning_status`, `operating_status`, `ipacl_group_action`, `ipacl_group_ids`가 행으로 출력된다.
40
+ 단건 IP ACL 그룹 테이블에는 `id`, `name`, `action`, `ipacl_target_count`, `loadbalancer_ids`가 행으로 출력된다.
41
+
42
+ ## 이름과 UUID 해석
43
+
44
+ `<loadbalancer>`와 `<group>`에는 이름 또는 UUID를 넣는다.
45
+
46
+ 1. UUID가 정확히 일치하면 해당 리소스를 선택한다.
47
+ 2. UUID가 아니면 정확히 일치하는 이름을 찾는다.
48
+ 3. 이름이 하나만 일치하면 해당 리소스를 선택한다.
49
+ 4. 같은 이름이 여러 개면 입력 오류와 후보 UUID를 출력한다.
50
+ 5. 일치하는 리소스가 없으면 입력 오류로 종료한다.
51
+
52
+ 중복 이름으로 자동화가 불안정해지는 것을 막으려면 목록에서 UUID를 확인한 뒤 다음 명령에 전달한다.
53
+
54
+ ```bash
55
+ profile_name="<profile>"
56
+ region_name="<region>"
57
+ loadbalancer_id="<loadbalancer-id>"
58
+
59
+ nhncloud loadbalancer list \
60
+ --profile "$profile_name" \
61
+ --region "$region_name" \
62
+ --json \
63
+ | jq -r '.[] | [.name, .id] | @tsv'
64
+
65
+ nhncloud loadbalancer get "$loadbalancer_id" \
66
+ --profile "$profile_name" \
67
+ --region "$region_name" \
68
+ --json
69
+ ```
70
+
71
+ `target remove`의 `<target-id>`는 이름 해석을 하지 않는다.
72
+ `target list` 또는 이전 쓰기 결과에서 확인한 UUID를 그대로 전달한다.
73
+
74
+ ## 쓰기 절차
75
+
76
+ 쓰기 전에 현재 리소스를 `--json`으로 조회한다.
77
+ 명령에는 `--profile`, `--region`, `--json`을 명시한다.
78
+ 삭제·연결 교체·대상 변경에는 `--yes`도 명시한다.
79
+
80
+ ```bash
81
+ # 그룹 생성
82
+ nhncloud loadbalancer ipacl create \
83
+ --name <group-name> \
84
+ --action ALLOW \
85
+ --description <description> \
86
+ --profile <profile> \
87
+ --region <region> \
88
+ --json
89
+
90
+ # 그룹 삭제: 대상과 Load Balancer 연결 규칙도 함께 제거
91
+ nhncloud loadbalancer ipacl delete <group> \
92
+ --profile <profile> \
93
+ --region <region> \
94
+ --yes \
95
+ --json
96
+
97
+ # 연결 전체 교체: --group은 반복 가능하며 action이 모두 같아야 함
98
+ nhncloud loadbalancer set-ipacl <loadbalancer> \
99
+ --group <group> \
100
+ --group <other-group> \
101
+ --profile <profile> \
102
+ --region <region> \
103
+ --yes \
104
+ --json
105
+
106
+ # 연결 전체 해제
107
+ nhncloud loadbalancer clear-ipacl <loadbalancer> \
108
+ --profile <profile> \
109
+ --region <region> \
110
+ --yes \
111
+ --json
112
+
113
+ # 대상 추가와 삭제
114
+ nhncloud loadbalancer ipacl target add <group> \
115
+ --cidr <ip-or-cidr> \
116
+ --description <description> \
117
+ --profile <profile> \
118
+ --region <region> \
119
+ --yes \
120
+ --json
121
+ nhncloud loadbalancer ipacl target remove <target-id> \
122
+ --profile <profile> \
123
+ --region <region> \
124
+ --yes \
125
+ --json
126
+ ```
127
+
128
+ `set-ipacl`은 기존 연결에 그룹을 추가하는 명령이 아니다.
129
+ 전달한 그룹 목록으로 기존 연결 전체를 교체한다.
130
+ 모든 연결을 없애려면 그룹을 생략하지 말고 `clear-ipacl`을 사용한다.
131
+
132
+ 대상 추가·삭제는 변경 전에 연결 상태를 모두 수집한다.
133
+ 수집이 하나라도 실패하면 대상을 변경하지 않는다.
134
+ 대상 변경 후에는 관련 Load Balancer를 ID 순서로 재바인딩하고, 한 건이 실패해도 나머지를 계속 처리한다.
135
+ 자동 되돌리기는 수행하지 않는다.
136
+
137
+ `--no-rebind`는 재바인딩만 생략한다.
138
+ 데이터 영역에 규칙이 즉시 반영되지 않을 수 있으므로 의도적으로 지연을 감수할 때만 사용한다.
139
+ 대상 변경의 반영에는 약 10–20초가 걸릴 수 있다.
140
+ `ALLOW` 그룹 대상에는 Load Balancer가 속한 VPC의 private CIDR을 사용한다.
141
+
142
+ ## 출력 모드
143
+
144
+ | 명령 | `--json` 출력 | `--quiet` 출력 |
145
+ |------|----------------|----------------|
146
+ | `loadbalancer list` | Load Balancer 배열 | Load Balancer UUID를 한 줄에 하나씩 출력 |
147
+ | `loadbalancer get` | 단일 Load Balancer 객체 | 선택한 Load Balancer UUID 한 줄 |
148
+ | `loadbalancer ipacl list` | IP ACL 그룹 배열 | IP ACL 그룹 UUID를 한 줄에 하나씩 출력 |
149
+ | `loadbalancer ipacl get` | 단일 IP ACL 그룹 객체 | 선택한 IP ACL 그룹 UUID 한 줄 |
150
+ | `loadbalancer ipacl target list` | IP ACL 대상 배열 | IP ACL 대상 UUID를 한 줄에 하나씩 출력 |
151
+ | `loadbalancer ipacl create/delete` | 작업 상태와 IP ACL 그룹 UUID 객체 | IP ACL 그룹 UUID 한 줄 |
152
+ | `loadbalancer ipacl target add/remove` | 대상과 재바인딩 결과 객체 | IP ACL 대상 UUID 한 줄 |
153
+ | `loadbalancer set-ipacl/clear-ipacl` | 작업 상태와 Load Balancer·그룹 UUID 객체 | Load Balancer UUID 한 줄 |
154
+
155
+ 옵션을 생략하면 사람이 읽기 좋은 테이블을 출력한다.
156
+ 목록이 비어 있으면 기본 모드는 `결과 없음`을 stdout에 출력하고, `--json`은 빈 배열을 출력하며, `--quiet`는 출력하지 않는다.
157
+ `--json`은 NHN Cloud 응답의 최상위 래퍼를 제거한 객체 또는 배열이다.
158
+
159
+ ## 공통 옵션
160
+
161
+ | 옵션 | 설명 |
162
+ |------|------|
163
+ | `--region <region>` | region override. 생략하면 IaaS 자격증명의 region을 사용 |
164
+ | `--profile <name>` | 사용할 profile |
165
+ | `--json` | 객체 또는 배열을 JSON으로 stdout에 출력 |
166
+ | `--quiet` | 리소스 UUID만 stdout에 출력 |
167
+
168
+ ## 쓰기 전용 옵션
169
+
170
+ | 옵션 | 적용 명령 | 설명 |
171
+ |------|-----------|------|
172
+ | `--yes` | `ipacl delete`, `ipacl target add/remove`, `set-ipacl`, `clear-ipacl` | 삭제·연결 교체·대상 변경을 비대화형으로 확인 |
173
+ | `--no-rebind` | `ipacl target add/remove` | 대상 변경 후 자동 재바인딩 생략 |
174
+
175
+ ## stdout과 stderr
176
+
177
+ - 테이블, JSON, UUID, 정상 빈 결과는 stdout에 출력한다.
178
+ - 진행 상황, 운영 경고, 오류는 stderr에 출력한다.
179
+ - 파이프라인에서는 stdout만 다음 명령에 전달하고 stderr는 진단 로그로 분리한다.
180
+ - 부분 실패에서도 JSON 또는 UUID를 stdout에 먼저 출력한 뒤 stderr에 복구 안내를 출력한다.
181
+
182
+ ## 부분 실패 복구
183
+
184
+ 대상 변경이 성공했지만 일부 Load Balancer 재바인딩이 실패하면 종료 코드 1을 반환한다.
185
+ stdout JSON의 `status`는 `partial`이며, 실패마다 기계 실행용 `retry_argv`와 사람 확인용 `retry_command`를 제공한다.
186
+ 사용자가 명시한 profile과 region은 `retry_argv`에 보존된다.
187
+
188
+ ```json
189
+ {
190
+ "operation": "ipacl-target-add",
191
+ "status": "partial",
192
+ "target": {
193
+ "id": "<target-id>",
194
+ "ipacl_group_id": "<group-id>"
195
+ },
196
+ "rebind": {
197
+ "skipped": false,
198
+ "succeeded": [],
199
+ "failed": [
200
+ {
201
+ "loadbalancer_id": "<loadbalancer-id>",
202
+ "ipacl_group_ids": ["<group-id>"],
203
+ "error": "<message>",
204
+ "retry_argv": [
205
+ "nhncloud",
206
+ "loadbalancer",
207
+ "set-ipacl",
208
+ "<loadbalancer-id>",
209
+ "--group",
210
+ "<group-id>",
211
+ "--profile",
212
+ "<profile>",
213
+ "--region",
214
+ "<region>",
215
+ "--yes",
216
+ "--json"
217
+ ],
218
+ "retry_command": "'nhncloud' 'loadbalancer' 'set-ipacl' '<loadbalancer-id>' '--group' '<group-id>' '--profile' '<profile>' '--region' '<region>' '--yes' '--json'"
219
+ }
220
+ ]
221
+ }
222
+ }
223
+ ```
224
+
225
+ AI 에이전트는 `retry_command`를 셸에서 다시 해석하지 말고 `retry_argv` 배열을 직접 실행한다.
226
+ 빈 그룹 snapshot의 복구 배열은 `clear-ipacl`을 사용한다.
227
+ 복구 명령이 성공한 뒤 원래 대상 추가·삭제를 반복하지 않는다.
228
+
229
+ ## 에러 코드
230
+
231
+ | 상황 | exit code |
232
+ |------|-----------|
233
+ | Load Balancer 또는 IP ACL API 오류 | 1 |
234
+ | 대상 변경 후 재바인딩 부분 실패 | 1 |
235
+ | Keystone 인증 실패 | 2 |
236
+ | 빈 이름·UUID, 리소스 없음, 중복 이름 | 3 |
237
+ | IaaS 자격증명 누락 또는 미등록 region | 4 |
@@ -1,6 +1,10 @@
1
1
  # Log & Crash Reference
2
2
 
3
- `logncrash` 명령군은 Log & Crash Search 검색, scroll export, collector 전송을 다룬다.
3
+ `logncrash` 명령군은 Log & Crash Search v3 커서 검색, scroll export, collector 전송을 다룬다.
4
+
5
+ 검색과 export에는 profile의 logncrash appkey와 공통 UAK가 필요하다.
6
+ CLI가 UAK를 OAuth 토큰으로 교환해 Bearer 인증을 적용한다.
7
+ `send`는 별도 collector 계약이므로 Search v3 전환의 영향을 받지 않는다.
4
8
 
5
9
  ## 검색
6
10
 
@@ -25,10 +29,14 @@ nhncloud logncrash search \
25
29
  | `--query <lucene>` | 예 | Lucene 질의 문자열. API에 그대로 전달 |
26
30
  | `--from <time>` | 예 | 검색 시작. ISO8601 또는 상대시간 |
27
31
  | `--to <time>` | 예 | 검색 끝. ISO8601, 상대시간, `now` |
28
- | `--page <n>` | 아니오 | pageNumber. 기본 0 |
29
- | `--size <n>` | 아니오 | pageSize. 기본 10, 최대 100 |
32
+ | `--page <n>` | 아니오 | 전환 호환용 pageNumber. 기본 0이며 0만 허용 |
33
+ | `--size <n>` | 아니오 | pageSize. 기본 10, 범위 1~100 |
34
+ | `--cursor <value>` | 아니오 | 직전 JSON 응답의 불투명한 `nextCursor` |
30
35
  | `--profile <name>` | 아니오 | 사용할 profile |
31
36
 
37
+ CLI는 REAL API 실측 계약에 따라 모든 커서 요청을 `logTime DESC`로 고정 정렬한다.
38
+ 사용자 정렬 옵션은 제공하지 않는다.
39
+
32
40
  Lucene 예시:
33
41
 
34
42
  | 의도 | 쿼리 |
@@ -50,15 +58,28 @@ API 제약:
50
58
 
51
59
  ## 검색 출력
52
60
 
53
- `--json` 출력은 `{ totalItems, pageNumber, pageSize, data }` 객체다.
61
+ `--json` 출력은 `{ totalItems, pageNumber, pageSize, data, nextCursor? }` 객체다.
62
+ 마지막 페이지에는 `nextCursor`가 없을 수 있다.
54
63
 
55
64
  ```bash
56
65
  nhncloud logncrash search \
57
66
  --query '*' \
58
67
  --from 1h --to now \
59
68
  --json | jq '.totalItems'
69
+
70
+ # 다음 cursor가 있을 때만 순차 조회
71
+ next_cursor="$(nhncloud logncrash search \
72
+ --query '*' --from 1h --to now --json | jq -r '.nextCursor // empty')"
73
+ if [ -n "$next_cursor" ]; then
74
+ nhncloud logncrash search \
75
+ --query '*' --from 1h --to now \
76
+ --cursor "$next_cursor" --json
77
+ fi
60
78
  ```
61
79
 
80
+ cursor는 파싱하거나 인코딩을 바꾸지 않고 받은 문자열 그대로 전달한다.
81
+ 임의 페이지 이동은 지원하지 않으므로 `--page 1` 이상은 입력 오류다.
82
+
62
83
  전송 직후에는 인덱싱 지연으로 잠시 0건이 나올 수 있다.
63
84
  반복 검색이나 넓은 wildcard 검색은 시간 범위를 좁혀 확인한다.
64
85
 
@@ -82,16 +103,17 @@ nhncloud logncrash export \
82
103
  | `--output <file>` | 필수. 출력 파일 |
83
104
  | `--format json` | JSON 배열로 저장. 기본은 JSON Lines |
84
105
  | `--force` | 기존 파일 덮어쓰기 |
85
- | `--size <n>` | scroll pageSize. 10~100 |
106
+ | `--size <n>` | 폐기 예정 호환 옵션. 10~100 검증 후 경고하고 v3 요청에는 미전달 |
86
107
 
87
- scrollKey는 1분 만료다.
88
- 데이터가 많아 다음 호출까지 1분을 넘기면 만료될 수 있다.
89
- 이 경우 검색 범위를 좁히거나 `--size`를 키워 페이지 수를 줄인다.
108
+ scroll 계속 요청이 실패하면 CLI가 원본 오류를 보존한다.
109
+ 오류를 확인한 뒤 검색 시간 범위를 좁혀 다시 실행한다.
110
+ `--size`는 v3 scroll의 페이지 크기를 제어하지 않는다.
90
111
 
91
112
  ## 로그 전송
92
113
 
93
114
  `logncrash send`는 collector host로 로그 한 건을 전송한다.
94
- 검색과 달리 secret 헤더를 쓰지 않고, body의 `projectName`에 appkey를 넣는다.
115
+ 검색의 UAK OAuth Bearer 인증을 재사용하지 않는다.
116
+ 인증 헤더 없이 body의 `projectName`에 appkey를 넣는다.
95
117
 
96
118
  ```bash
97
119
  nhncloud logncrash send --body "batch finished" --level INFO
@@ -120,7 +142,7 @@ nhncloud logncrash send --file ./error.log --level ERROR
120
142
 
121
143
  | 상황 | exit code |
122
144
  |------|-----------|
123
- | appkey 또는 secret 누락 | 4 |
145
+ | 검색 appkey 또는 공통 UAK 누락 | 4 |
124
146
  | 인증 실패 | 2 |
125
147
  | 시간 범위 초과, 본문 없음, 8MB 초과 | 3 |
126
148
  | API 오류 또는 봉투 실패 | 1 |
@@ -62,6 +62,43 @@ nhncloud ncs workload events <workload-id> --task <task-id> --app-key <appkey> -
62
62
  nhncloud ncs workload events <workload-id> --task <task-id> --type Warning --app-key <appkey> --json
63
63
  ```
64
64
 
65
+ ### logs·events 시간 필터
66
+
67
+ `--from`과 `--to`는 다음 두 형식을 받는다.
68
+
69
+ - 시간대와 초를 포함한 RFC3339 절대시간
70
+ - `now`
71
+ - 0 이상의 정수 뒤에 `m`, `h`, `d` 중 하나를 붙인 상대시간
72
+
73
+ 상대시간 예시는 `30m`, `1h`, `2d`다.
74
+
75
+ ```bash
76
+ # 같은 현재 시각을 기준으로 최근 1시간 조회
77
+ nhncloud ncs workload events <workload-id> \
78
+ --task <task-id> \
79
+ --from 1h \
80
+ --to now \
81
+ --profile <profile> \
82
+ --json
83
+
84
+ # 시간대 오프셋을 포함한 절대시간 조회
85
+ nhncloud ncs workload logs <workload-id> \
86
+ --task <task-id> \
87
+ --container <name> \
88
+ --from 2026-05-01T09:00:00+09:00 \
89
+ --to 2026-05-01T10:00:00+09:00 \
90
+ --profile <profile> \
91
+ --json
92
+ ```
93
+
94
+ CLI는 입력을 API 호출 전에 `YYYY-MM-DDTHH:mm:ssZ` 형식으로 정규화하고 소수 초를 제거한다.
95
+ 두 옵션을 모두 생략하면 API 기본 범위를 사용한다.
96
+ 한쪽만 지정하면 지정한 필드만 API에 전달한다.
97
+
98
+ 존재하지 않는 날짜, 시간대 없는 절대시간, 지원하지 않는 상대시간 단위, `from > to`는 종료 코드 3으로 거부한다.
99
+ 검증은 profile·자격증명 조회와 API 호출보다 먼저 실행된다.
100
+ AI 에이전트는 같은 입력으로 인증 재시도를 반복하지 말고 오류에 표시된 옵션 값을 수정한다.
101
+
65
102
  실행 히스토리와 예약 실행 히스토리는 workload 단위로 조회한다.
66
103
 
67
104
  ```bash
@@ -136,6 +173,7 @@ nhncloud ncs workload history <workload-id> --app-key <appkey> --json | jq -r '.
136
173
  | `--q <query>` | workload list·events 필터 |
137
174
  | `--task <taskId>` | `workload logs`·`workload events`·`workload restart` 필수 |
138
175
  | `--container <name>` | `workload logs` 필수 |
176
+ | `--from <time>` / `--to <time>` | `workload logs`·`workload events` 시간 필터. 시간대 포함 RFC3339, `now`, 0 이상의 정수와 `m`·`h`·`d` 단위 |
139
177
  | `--sort <sort>` | `workload history` 정렬 (역순은 필드명 앞에 `-`) |
140
178
  | `--file <path>` | `template create`·`template version create`·`workload create`·`workload update`·`workload patch` 필수 — JSON payload 파일 경로 (`patch`는 JSON Patch 배열) |
141
179
  | `--wait` / `--timeout <sec>` | `workload create` — Running 상태 폴링(`--timeout` 기본 300초) |
@@ -146,6 +184,8 @@ nhncloud ncs workload history <workload-id> --app-key <appkey> --json | jq -r '.
146
184
 
147
185
  - appkey는 NCS service appkey다. 인증 secret은 공통 UAK secret을 사용한다.
148
186
  - `workload logs`·`workload events`는 task 단위 조회라 `--task` 없이는 입력 오류다.
187
+ - `workload logs`·`workload events` 데이터는 stdout, 진행 상황과 오류는 stderr에 출력한다.
188
+ - 시간 필터를 생략하면 CLI가 임의 기본값을 만들지 않고 API 기본 범위를 유지한다.
149
189
  - `workload restart`도 task 단위라 `--task` 없이는 입력 오류다.
150
190
  - `workload schedule-history`는 page/size를 아직 노출하지 않는다(대량 이력 시 첫 페이지만 반환될 수 있음 — ADR-020).
151
191
  - template/workload id, history id 인수가 공백이면 입력 오류다.
@@ -162,5 +202,7 @@ nhncloud ncs workload history <workload-id> --app-key <appkey> --json | jq -r '.
162
202
  |------|-----------|
163
203
  | UAK 누락 또는 NCS appkey 미설정 | 4 |
164
204
  | UAK 인증 실패 | 2 |
165
- | 지원하지 않는 region, 빈 id 인수, `--task`/`--container` 누락, `--file` 파일 오류(누락·디렉터리·크기초과·JSON 파싱 실패), `--enabled` 값 오류(`true`/`false` 외), 비대화형 삭제 시 `--yes` 누락 | 3 |
205
+ | 지원하지 않는 region, 빈 id 인수, `--task`·`--container` 누락 | 3 |
206
+ | 잘못된 logs·events 시간 필터 | 3 |
207
+ | `--file` 파일 오류, 잘못된 `--enabled`, 비대화형 삭제 시 `--yes` 누락 | 3 |
166
208
  | NCS API 오류 (payload 필수값 누락, `workload create --wait` 타임아웃 등 서버측 검증·폴링 실패 포함) | 1 |
@@ -15,7 +15,7 @@
15
15
 
16
16
  | 서비스 | 비밀 | 인증 방식 |
17
17
  |--------|------|-----------|
18
- | Log & Crash 검색/export | appkey + secret | `X-LNCS-SECRET` |
18
+ | Log & Crash 검색/export | appkey + 공통 UAK id/secret | UAK OAuth `X-NHN-Authorization: Bearer <token>` |
19
19
  | Log & Crash send | appkey | body `projectName=appkey`, 인증 헤더 없음 |
20
20
  | Deploy | UAK id + secret | OAuth Bearer token |
21
21
  | Instance/network/volume/floatingip | tenantId + username + API password | Keystone `X-Auth-Token` |
@@ -70,8 +70,17 @@ nhncloud ncr list --json | jq '.[0] | keys'
70
70
 
71
71
  - `--from`은 최근 90일 이내여야 한다.
72
72
  - `--to - --from` 범위는 31일 이하여야 한다.
73
- - scrollKey는 1분 만료다.
74
- - export가 중간 실패하면 검색 범위를 좁히거나 `--size`를 키운다.
73
+ - `--page`는 0만 허용한다. 다음 페이지는 JSON의 `nextCursor`를 `--cursor`로 그대로 전달한다.
74
+ - 검색 `--size`는 1~100이다.
75
+ - export `--size`는 폐기 예정 호환 옵션이며 10~100 검증 후 경고하고 v3 요청에서는 무시한다.
76
+ - export가 중간 실패하면 보존된 원본 오류를 확인하고 검색 범위를 좁혀 다시 실행한다.
77
+
78
+ 검색 또는 export에서 설정 오류가 나면 profile에 다음 두 값이 모두 있는지 확인한다.
79
+
80
+ - `userAccessKey.id`와 `userAccessKey.secret`
81
+ - `logncrash.appkey`
82
+
83
+ 기존 `logncrash.secret`은 Search v3 인증에 사용하지 않는다.
75
84
 
76
85
  ## 쓰기 명령 confirm
77
86