@bifos/nhncloud-cli 0.13.0 → 0.15.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.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "CLI tool for NHN Cloud services — AI agent & terminal friendly",
5
5
  "keywords": [
6
6
  "nhncloud",
@@ -30,7 +30,7 @@ description: >-
30
30
  |---|---|
31
31
  | CLI 설치, `configure`, profile, 출력 모드, 명령 카탈로그, 종료 코드 | [common.md](references/common.md) |
32
32
  | 공개 스킬 상태 확인·설치·갱신·제거와 상태별 복구 | [common.md](references/common.md) |
33
- | Log & Crash Search v3 커서 검색·scroll 대량 추출·collector 전송 | [logncrash.md](references/logncrash.md) |
33
+ | Log & Crash Search v3 커서 검색·scroll 대량 추출·collector 전송<br>반복 조회 자동화의 호출 비용 설계 | [logncrash.md](references/logncrash.md) |
34
34
  | Deploy 실행·조회·바이너리 전송 | [deploy.md](references/deploy.md) |
35
35
  | Compute, VPC, Block Storage, Floating IP | [iaas.md](references/iaas.md) |
36
36
  | Load Balancer와 IP ACL | [loadbalancer.md](references/loadbalancer.md) |
@@ -38,4 +38,5 @@ description: >-
38
38
  | Kubernetes Service | [nks.md](references/nks.md) |
39
39
  | Container Service | [ncs.md](references/ncs.md) |
40
40
  | API Gateway 서비스·리소스·스테이지·배포 조회와 Swagger export | [apigateway.md](references/apigateway.md) |
41
+ | API Gateway `stage update`·`stage import-resources`·`stage deploy create`·`stage deploy rollback`, `resource set-path-plugin`·`set-method-plugin` | [apigateway.md](references/apigateway.md) |
41
42
  | 인증·profile·region·출력·검색 제한 문제 해결 | [troubleshooting.md](references/troubleshooting.md) |
@@ -1,13 +1,12 @@
1
- # API Gateway 조회 안내
1
+ # API Gateway 조회·변경 안내
2
2
 
3
3
  `apigateway` 명령군은 API Gateway 서비스, 리소스, 스테이지, 배포 이력을 조회하고 스테이지의 Swagger를 내보낸다.
4
- 현재는 조회만 지원하며 플러그인 적용, 스테이지 수정, 배포, 롤백 같은 쓰기 작업은 지원하지 않는다.
4
+ 스테이지의 백엔드 URL·설명 수정과 리소스 경로·메서드 플러그인 설정도 지원한다.
5
5
 
6
6
  ## 인증과 설정
7
7
 
8
8
  공통 UAK와 API Gateway `appKey`가 필요하다.
9
- `nhncloud configure --apigateway-appkey <appkey>`로 `profile`의 `apigateway.appkey`를 설정하거나, 명령마다 `--app-key <appkey>`를 넘긴다.
10
- `--app-key`가 `profile` 설정보다 우선한다.
9
+ `nhncloud configure --apigateway-appkey <appkey>`로 `profile`의 `apigateway.appkey`를 설정한다.
11
10
 
12
11
  API 요청은 공통 UAK로 발급한 Bearer 토큰을 `X-NHN-Authorization` 헤더에 담는다.
13
12
  표준 `Authorization` 헤더가 아니므로 직접 API를 호출할 때 혼동하지 않는다.
@@ -15,12 +14,12 @@ API 요청은 공통 UAK로 발급한 Bearer 토큰을 `X-NHN-Authorization` 헤
15
14
  지원 `region`은 `kr1`, `kr2`, `kr3`이며 기본값은 `kr1`이다.
16
15
 
17
16
  ```bash
18
- nhncloud apigateway service list --region kr1 --app-key <appkey> --json
17
+ nhncloud apigateway service list --region kr1 --json
19
18
  ```
20
19
 
21
20
  ## 명령
22
21
 
23
- 아래 표의 공통 옵션은 `--region <region>`, `--app-key <key>`, `--profile <name>`이다.
22
+ 아래 표의 공통 옵션은 `--region <region>`, `--profile <name>`이다.
24
23
  루트 전역 옵션인 `--json`과 `--quiet`도 사용할 수 있다.
25
24
 
26
25
  | 명령 경로 | 인수 | 명령 옵션 |
@@ -30,11 +29,17 @@ nhncloud apigateway service list --region kr1 --app-key <appkey> --json
30
29
  | `nhncloud apigateway resource list` | `<service-id>` | 공통 옵션 |
31
30
  | `nhncloud apigateway resource parameters` | `<service-id> <resource-id>` | 공통 옵션 |
32
31
  | `nhncloud apigateway resource responses` | `<service-id> <resource-id>` | 공통 옵션 |
32
+ | `nhncloud apigateway resource set-path-plugin` | `<service-id> <resource-id>` | 공통 옵션, `--config-file <path>`, `--dry-run`, `--yes` |
33
+ | `nhncloud apigateway resource set-method-plugin` | `<service-id> <resource-id>` | 공통 옵션, `--config-file <path>`, `--dry-run`, `--yes` |
33
34
  | `nhncloud apigateway stage list` | `<service-id>` | 공통 옵션 |
34
35
  | `nhncloud apigateway stage swagger` | `<service-id> <stage-id>` | 공통 옵션, `--output <file>`, `--force` |
35
36
  | `nhncloud apigateway stage resources` | `<service-id> <stage-id>` | 공통 옵션 |
37
+ | `nhncloud apigateway stage update` | `<service-id> <stage-id>` | 공통 옵션, `--backend-endpoint-url <url>`, `--description <text>`, `--yes` |
38
+ | `nhncloud apigateway stage import-resources` | `<service-id> <stage-id>` | 공통 옵션, `--yes` |
39
+ | `nhncloud apigateway stage deploy create` | `<service-id> <stage-id>` | 공통 옵션, `--description <text>`, `--no-wait`, `--timeout <sec>`, `--yes` |
36
40
  | `nhncloud apigateway stage deploy list` | `<service-id> <stage-id>` | 공통 옵션 |
37
41
  | `nhncloud apigateway stage deploy latest` | `<service-id> <stage-id>` | 공통 옵션 |
42
+ | `nhncloud apigateway stage deploy rollback` | `<service-id> <stage-id> <deploy-id>` | 공통 옵션, `--yes` |
38
43
 
39
44
  `--quiet`가 식별자를 출력하는 명령은 다음과 같다.
40
45
 
@@ -42,12 +47,101 @@ nhncloud apigateway service list --region kr1 --app-key <appkey> --json
42
47
  - `resource list`: `resourceId`
43
48
  - `stage list`: `stageId`
44
49
  - `stage resources`: `stageResourceId`
50
+ - `stage import-resources`·`stage deploy rollback`: `stageResourceId`
45
51
  - `stage deploy list`·`stage deploy latest`: `deployId`
52
+ - `stage deploy create`: 대기 경로는 `deployId`, `--no-wait`는 출력 없음
46
53
 
47
54
  `resource parameters`와 `resource responses`는 식별자 출력이 없어 `--quiet`에서 아무것도 출력하지 않는다.
48
55
  `stage swagger`는 `--output`을 생략하면 Swagger JSON을 stdout에 출력하고, 지정하면 파일을 새로 만든 뒤 경로를 출력한다.
49
56
  기존 파일을 덮어쓰려면 `--force`를 함께 지정한다.
50
57
 
58
+ ## 플러그인 설정 파일
59
+
60
+ `set-path-plugin`과 `set-method-plugin`은 API 요청 본문 형태의 JSON 파일을 `--config-file`로 받는다.
61
+ 경로 플러그인의 `applyChildPath`와 공통 필드인 `delete`는 모두 각 플러그인 항목에 넣는다.
62
+
63
+ `path-plugins.json` 예시:
64
+
65
+ ```json
66
+ {
67
+ "pathPluginList": [
68
+ {
69
+ "pluginType": "ADD_REQUEST_QUERY_PARAMETER",
70
+ "pluginConfigJson": {},
71
+ "applyChildPath": true,
72
+ "delete": false
73
+ }
74
+ ]
75
+ }
76
+ ```
77
+
78
+ `method-plugins.json` 예시:
79
+
80
+ ```json
81
+ {
82
+ "methodPluginList": [
83
+ {
84
+ "pluginType": "HTTP",
85
+ "pluginConfigJson": {
86
+ "url": "https://backend.example.com"
87
+ },
88
+ "delete": false
89
+ }
90
+ ]
91
+ }
92
+ ```
93
+
94
+ `delete` 가 `true`면 해당 플러그인을 삭제하므로 `pluginConfigJson`을 생략할 수 있다.
95
+ `applyChildPath`는 경로 플러그인에만 사용하며 메서드 설정에 넣으면 입력 오류로 거부된다.
96
+
97
+ `set-path-plugin`과 `set-method-plugin`만 `--dry-run`을 제공한다.
98
+ 하위 적용 범위를 서버가 판정하고 CORS 플러그인이 기존 OPTIONS 메서드를 삭제·대체하므로,
99
+ 다른 위험 명령의 `--yes` 확인만으로는 되돌릴 수 없는 범위를 적용 전에 확인할 수 없기 때문이다.
100
+
101
+ 리소스 플러그인 변경을 스테이지에 반영하려면 별도의 리소스 반영과 배포가 필요하다.
102
+
103
+ ## 반영·배포·롤백
104
+
105
+ 리소스 변경이 트래픽에 적용되려면 서비스 리소스를 스테이지로 반영한 뒤 스테이지를 배포하는 두 단계를 거친다.
106
+ 반영·배포·롤백 명령은 모두 API 호출 전에 `--yes`가 필요하다.
107
+
108
+ ```text
109
+ nhncloud apigateway stage import-resources <service-id> <stage-id> --yes
110
+ nhncloud apigateway stage deploy create <service-id> <stage-id> [--description <text>] [--no-wait] [--timeout <sec>] --yes
111
+ nhncloud apigateway stage deploy rollback <service-id> <stage-id> <deploy-id> --yes
112
+ ```
113
+
114
+ 배포 요청과 배포 결과 조회는 별도 API이므로 `deploy create`는 기본적으로 최신 배포 결과를 조회하며 완료까지 기다린다.
115
+ 요청 직후 반환하려면 `--no-wait`를 사용하고, 기다리는 시간의 상한은 `--timeout <sec>`로 지정한다.
116
+
117
+ **대기가 끊겨 명령이 실패해도 배포 요청은 취소되지 않는다.**
118
+ `--timeout` 초과나 결과 조회 실패로 끝나면 명령은 아래 경고를 함께 낸다.
119
+
120
+ ```text
121
+ 주의: 배포 요청은 이미 접수됐습니다. 재실행하지 말고 apigateway stage deploy latest 로 결과를 확인하세요.
122
+ ```
123
+
124
+ 이 경고가 나오면 재실행하지 않는다. 같은 스테이지에 두 번째 배포가 나간다.
125
+ `deploy latest`로 결과를 확인한 뒤 다음 동작을 정한다.
126
+
127
+ 배포가 `FAILURE`로 끝난 경우에는 이 경고가 나오지 않는다.
128
+ 결과가 이미 확정됐으므로 원인을 고쳐 다시 배포하면 된다.
129
+
130
+ 바꿀 것이 없으면 반영과 배포 모두 오류로 끝난다(종료 코드 1). 빈 결과를 돌려주지 않는다.
131
+
132
+ ```text
133
+ 반영: API 오류: The latest resource has already been applied.
134
+ 배포: API 오류: Failed to deploy because stage is not changed.
135
+ ```
136
+
137
+ 반복 실행하는 자동화는 이 오류를 실패로 볼지 "이미 최신"으로 볼지 미리 정해 둔다.
138
+ 현재 상태만 알고 싶다면 `deploy latest`로 조회한다.
139
+
140
+ `deploy rollback`은 선택한 배포 이력으로 스테이지 설정만 되돌린다.
141
+ 되돌린 설정을 트래픽에 적용하려면 `deploy create`를 다시 실행해야 한다.
142
+ 되돌리면 직전까지의 스테이지 설정은 남지 않는다.
143
+ 명령은 실행 후 `완료: 직전까지의 스테이지 설정은 이 배포 이력의 내용으로 대체됐습니다.`라고 알린다.
144
+
51
145
  ## JSON 구조
52
146
 
53
147
  API 응답 봉투의 `header`를 검사한 뒤 CLI는 아래 데이터를 꺼내 `--json`으로 출력한다.
@@ -96,3 +190,20 @@ diff -u specs/apigateway-swagger.json /tmp/apigateway-swagger.json
96
190
 
97
191
  `service list --quiet`과 `stage list --quiet`은 결과가 없으면 아무것도 출력하지 않는다.
98
192
  자동화에서는 빈 식별자를 다음 명령에 넘기기 전에 검사한다.
193
+
194
+ 플러그인 일괄 적용은 같은 설정 파일로 영향 범위를 먼저 확인한 뒤 실행한다.
195
+
196
+ ```bash
197
+ nhncloud apigateway resource set-path-plugin <service-id> <resource-id> \
198
+ --config-file path-plugins.json --dry-run --json
199
+
200
+ nhncloud apigateway resource set-path-plugin <service-id> <resource-id> \
201
+ --config-file path-plugins.json --yes
202
+ ```
203
+
204
+ 변경된 서비스 리소스를 스테이지에 반영하고 배포 완료까지 기다릴 수 있다.
205
+
206
+ ```bash
207
+ nhncloud apigateway stage import-resources <service-id> <stage-id> --yes
208
+ nhncloud apigateway stage deploy create <service-id> <stage-id> --yes
209
+ ```
@@ -6,49 +6,42 @@ UAK를 OAuth `client_credentials`로 교환한 Bearer token으로 인증하고,
6
6
  ## 설정
7
7
 
8
8
  `~/.nhncloud/credentials.json`에 profile 공통 `userAccessKey`가 필요하다.
9
+ appkey는 `nhncloud configure --deploy-appkey <key>`로 profile에 설정한다.
9
10
  `nhncloud configure` 사용을 권장한다.
10
11
 
11
- `~/.nhncloud/config.json`에는 named deploy target을 둔다.
12
+ 배포 좌표(아티팩트·서버그룹·시나리오 등)는 config에 두지 않는다.
13
+ 매 호출마다 명령 옵션으로 넘긴다.
14
+ 반복되는 값은 호출하는 쪽의 스크립트나 CI 변수가 관리한다.
12
15
 
13
- Discovery:
16
+ **여러 배포 대상을 쓰려면 profile 을 나눈다.**
17
+ profile 하나에 appkey 하나다.
14
18
 
15
19
  ```bash
16
- nhncloud commands --json | jq '.commands[] | select(.path|startswith("deploy"))'
20
+ nhncloud configure --profile projA --deploy-appkey <keyA>
21
+ nhncloud deploy run --profile projA --artifact-id <id> --server-group-id <id> --scenario-ids <ids>
17
22
  ```
18
23
 
19
- ```json
20
- {
21
- "version": 1,
22
- "defaultProfile": "default",
23
- "deploy": {
24
- "targets": {
25
- "my-service": {
26
- "appKey": "<appKey>",
27
- "artifactId": "<artifactId>",
28
- "serverGroupId": "<serverGroupId>",
29
- "scenarioIds": "<id1,id2>"
30
- }
31
- }
32
- }
33
- }
24
+ 구버전에서 쓰던 config.json 의 이름 붙은 배포 대상 설정이 남아 있으면 경고가 나오며 읽지 않는다.
25
+
26
+ Discovery:
27
+
28
+ ```bash
29
+ nhncloud commands --json | jq '.commands[] | select(.path|startswith("deploy"))'
34
30
  ```
35
31
 
36
32
  ## 배포 실행
37
33
 
38
34
  ```bash
39
- nhncloud deploy run my-service
40
- nhncloud deploy run my-service --async
41
- nhncloud deploy run my-service --target-hosts <host1,host2>
35
+ nhncloud deploy run --artifact-id <id> --server-group-id <id> --scenario-ids <id1,id2>
36
+ nhncloud deploy run --artifact-id <id> --server-group-id <id> --scenario-ids <id1,id2> --async
37
+ nhncloud deploy run --artifact-id <id> --server-group-id <id> --scenario-ids <id1,id2> --target-hosts <host1,host2>
42
38
  ```
43
39
 
44
- `<target>`은 config의 deploy target 이름이다.
45
-
46
40
  | 옵션 | 설명 |
47
41
  |------|------|
48
- | `--app-key <k>` | target의 appKey override |
49
- | `--artifact-id <id>` | target의 artifactId override |
50
- | `--server-group-id <id>` | target의 serverGroupId override |
51
- | `--scenario-ids <csv>` | target의 scenarioIds override |
42
+ | `--artifact-id <id>` | 배포할 아티팩트 ID (`artifacts`로 확인) |
43
+ | `--server-group-id <id>` | 배포 대상 서버그룹 ID (`server-groups`로 확인) |
44
+ | `--scenario-ids <csv>` | 실행할 시나리오 ID 목록 (쉼표 구분) |
52
45
  | `--target-hosts <csv>` | 대상 호스트. 생략 시 서버그룹 전체 |
53
46
  | `--concurrent <n>` | 병렬 배포 수. 기본 1 |
54
47
  | `--next-when-fail` | 시나리오 실패 시에도 진행 |
@@ -62,22 +55,22 @@ nhncloud deploy run my-service --target-hosts <host1,host2>
62
55
  ## 조회 명령
63
56
 
64
57
  ```bash
65
- nhncloud deploy artifacts my-service --json
66
- nhncloud deploy server-groups my-service --json
67
- nhncloud deploy histories my-service --json
68
- nhncloud deploy binary-groups my-service --json
69
- nhncloud deploy binaries my-service --binary-group <key> --json
58
+ nhncloud deploy artifacts --json
59
+ nhncloud deploy server-groups --artifact-id <id> --json
60
+ nhncloud deploy histories --artifact-id <id> --json
61
+ nhncloud deploy binary-groups --artifact-id <id> --json
62
+ nhncloud deploy binaries --binary-group <key> --artifact-id <id> --json
70
63
  ```
71
64
 
72
65
  의도별 명령:
73
66
 
74
67
  | 의도 | 명령 |
75
68
  |------|------|
76
- | 아티팩트 목록 | `deploy artifacts <target>` |
77
- | 서버그룹 목록 | `deploy server-groups <target>` |
78
- | 배포 이력 | `deploy histories <target>` |
79
- | 바이너리 그룹 목록 | `deploy binary-groups <target>` |
80
- | 바이너리 목록 | `deploy binaries <target> --binary-group <key>` |
69
+ | 아티팩트 목록 | `deploy artifacts` |
70
+ | 서버그룹 목록 | `deploy server-groups --artifact-id <id>` |
71
+ | 배포 이력 | `deploy histories --artifact-id <id>` |
72
+ | 바이너리 그룹 목록 | `deploy binary-groups --artifact-id <id>` |
73
+ | 바이너리 목록 | `deploy binaries --binary-group <key> --artifact-id <id>` |
81
74
 
82
75
  `deploy binary-groups --json`은 `binaryGroups` wrapper를 언랩한 배열이다.
83
76
  `deploy binaries --json`은 `{ totalCount, binaries }` 객체다.
@@ -85,8 +78,8 @@ nhncloud deploy binaries my-service --binary-group <key> --json
85
78
  ## 바이너리 전송
86
79
 
87
80
  ```bash
88
- nhncloud deploy upload <target> --file ./app.tgz --binary-group <key>
89
- nhncloud deploy download <target> --binary-group <key> --binary-key <key> -o ./app.tgz
81
+ nhncloud deploy upload --artifact-id <id> --file ./app.tgz --binary-group <key>
82
+ nhncloud deploy download --artifact-id <id> --binary-group <key> --binary-key <key> -o ./app.tgz
90
83
  ```
91
84
 
92
85
  `upload`는 multipart로 로컬 파일을 업로드한다.
@@ -98,15 +91,21 @@ nhncloud deploy download <target> --binary-group <key> --binary-key <key> -o ./a
98
91
  ## 체이닝 예시
99
92
 
100
93
  ```bash
101
- nhncloud deploy artifacts my-service --json | jq -r '.[0].artifactId'
102
- nhncloud deploy run my-service --artifact-id <artifactId>
103
- nhncloud deploy histories my-service --json | jq '.[0] | {deployKey, deployStatus}'
94
+ nhncloud deploy artifacts --json | jq -r '.[0].artifactId'
95
+ nhncloud deploy run --artifact-id <artifactId> --server-group-id <id> --scenario-ids <ids>
96
+ nhncloud deploy histories --artifact-id <id> --json | jq '.[0] | {deployKey, deployStatus}'
104
97
  ```
105
98
 
106
99
  ## 에러 코드
107
100
 
108
101
  | 상황 | exit code |
109
102
  |------|-----------|
110
- | UAK 누락 또는 config target 없음 | 4 또는 3 |
103
+ | UAK 누락 또는 profile에 deploy appkey 없음 | 4 |
104
+ | 좌표 옵션(`--artifact-id`·`--server-group-id`·`--scenario-ids`) 누락 | 3 |
111
105
  | OAuth 인증 실패 | 2 |
112
106
  | Deploy API 오류 또는 봉투 실패 | 1 |
107
+ | `--binary-group`·`--binary-key`·`--file`·`-o` 누락 | 1 |
108
+
109
+ 마지막 두 행이 같은 값인 것은 우연이 아니라 필수 옵션을 강제하는 방식이 둘이기 때문이다.
110
+ 좌표 옵션은 CLI 가 직접 검증해 3 을 내고, 나머지 필수 옵션은 Commander 가 거부해 1 을 낸다.
111
+ 종료 코드로 분기하는 자동화는 이 차이를 알아야 한다.
@@ -27,8 +27,8 @@ nhncloud logncrash search \
27
27
  | 옵션 | 필수 | 설명 |
28
28
  |------|:---:|------|
29
29
  | `--query <lucene>` | 예 | Lucene 질의 문자열. API에 그대로 전달 |
30
- | `--from <time>` | 예 | 검색 시작. ISO8601 또는 상대시간 |
31
- | `--to <time>` | 예 | 검색 끝. ISO8601, 상대시간, `now` |
30
+ | `--from <time>` | 예 | 검색 시작. 초와 시간대를 갖춘 ISO8601 또는 상대시간 |
31
+ | `--to <time>` | 예 | 검색 끝. 초와 시간대를 갖춘 ISO8601, 상대시간, `now` |
32
32
  | `--page <n>` | 아니오 | 전환 호환용 pageNumber. 기본 0이며 0만 허용 |
33
33
  | `--size <n>` | 아니오 | pageSize. 기본 10, 범위 1~100 |
34
34
  | `--cursor <value>` | 아니오 | 직전 JSON 응답의 불투명한 `nextCursor` |
@@ -49,12 +49,20 @@ Lucene 예시:
49
49
  시간 입력:
50
50
 
51
51
  - `1h`, `30m`, `2d`, `now`
52
- - `2024-01-01T00:00:00+09:00` 같은 ISO8601 직접 입력
52
+ - `2024-01-01T00:00:00+09:00` 이나 `2024-01-01T00:00:00Z` 같은 ISO8601 직접 입력
53
+ - 초와 시간대를 모두 지정해야 한다. 날짜만 주거나(`2024-01-01`) 초·시간대가 빠지면
54
+ 서버가 받지 않으므로 CLI 가 먼저 거부한다
53
55
 
54
56
  API 제약:
55
57
 
56
58
  - 검색 시작은 최근 90일 이내여야 한다.
57
59
  - 검색 범위는 31일 이하여야 한다.
60
+ - 문서상 제약보다 짧은 기간에서도 서버가 500 응답을 낼 수 있다. 처리 가능한 기간의
61
+ 경계는 프로젝트의 로그 양에 따라 달라진다.
62
+
63
+ `search`는 기간을 자동으로 나누지 않는다. 서버가 500 응답을 반환하면 기간을 줄여
64
+ 다시 시도하라는 안내와 서버 응답의 `requestId`를 보여 준다. 넓은 기간을 훑어야 하면
65
+ 자동으로 기간을 나누는 `logncrash export`를 사용한다.
58
66
 
59
67
  ## 검색 출력
60
68
 
@@ -81,7 +89,61 @@ cursor는 파싱하거나 인코딩을 바꾸지 않고 받은 문자열 그대
81
89
  임의 페이지 이동은 지원하지 않으므로 `--page 1` 이상은 입력 오류다.
82
90
 
83
91
  전송 직후에는 인덱싱 지연으로 잠시 0건이 나올 수 있다.
84
- 반복 검색이나 넓은 wildcard 검색은 시간 범위를 좁혀 확인한다.
92
+
93
+ ## 조회 횟수 제한
94
+
95
+ 짧은 시간에 여러 번 조회하면 조회 횟수 제한에 걸린다.
96
+ 이 응답은 HTTP 200에 봉투 오류로 오며 500과는 다른 원인이다.
97
+ CLI는 둘을 구분해 안내한다.
98
+
99
+ ```text
100
+ 조회 횟수 제한에 걸렸습니다. 시간을 두고 다시 실행하세요. 검색 기간을 좁혀도 풀리지 않습니다.
101
+ ```
102
+
103
+ **검색 기간을 좁히는 것은 해법이 아니다.**
104
+ 호출 한 번의 비용이 조회 기간에 거의 비례하지 않기 때문이다.
105
+ 같은 구간을 여러 창으로 나누면 오히려 제한을 더 빨리 소모한다.
106
+ 시간을 두고 다시 실행해야 한다.
107
+
108
+ CLI는 자동으로 다시 시도하지 않는다.
109
+ 서버가 남은 시간을 알려주지 않아 얼마나 기다릴지 알 수 없고, 회복이 느려 대기가 실효를 갖기 어렵다.
110
+
111
+ ### 반복 조회를 설계할 때
112
+
113
+ 주기적으로 로그를 수집하는 자동화라면 아래를 전제로 짠다.
114
+ 실패한 워크플로에서 되짚어 얻은 것이다.
115
+
116
+ **비용을 정하는 것은 호출 횟수와 쿼리의 선택성이다.** 조회 기간이 아니다.
117
+ 기간을 6배로 늘려도 한 호출의 비용은 거의 그대로였다.
118
+ 반면 `*` 대신 필드로 좁힌 쿼리는 같은 조회를 10분의 1 이하로 끝냈다.
119
+
120
+ **그래서 쿼리를 먼저 좁힌다.** 기간을 좁히는 것보다 효과가 크다.
121
+ `logSource`·`logLevel`·`host` 처럼 인덱스가 있는 필드로 걸러내면 호출당 비용이 급감한다.
122
+ `*` 로 넓게 받아 로컬에서 거르는 방식은 제한을 가장 빨리 소모한다.
123
+
124
+ **전수 수집은 `search` 반복이 아니라 `export` 한 번이다.**
125
+ `search`를 페이지마다 부르면 호출 수가 페이지 수만큼 늘어난다.
126
+ `export`는 같은 양을 훨씬 적은 호출로 받고, 기간 재분할과 페이지 순회를 CLI가 처리한다.
127
+
128
+ **`--page`로 페이지네이션을 직접 만들지 않는다.**
129
+ Search v3에서 `--page`는 `0`만 받는다.
130
+ `1` 이상을 넘기면 입력 오류(종료 코드 3)로 거부되며, 이것은 시간이 지나도 풀리지 않는다.
131
+ 100건을 넘겨 받아야 하면 `export`를 쓴다.
132
+
133
+ **재시도할 때 오류를 구분한다.**
134
+ 조회 횟수 제한과 서버 500은 기다리면 풀리지만, 입력 오류와 설정 오류는 풀리지 않는다.
135
+ 구분하지 않고 백오프를 걸면 풀리지 않는 오류에 대기 시간만 쓴다.
136
+
137
+ | 종료 코드 | 의미 | 기다리면 풀리나 |
138
+ |---|---|---|
139
+ | 1 | API 오류, 봉투 실패 (조회 횟수 제한 포함) | 그렇다 |
140
+ | 2 | 인증 실패 | 아니다 |
141
+ | 3 | 입력 오류 | 아니다 |
142
+ | 4 | 설정 오류 | 아니다 |
143
+
144
+ **백오프는 분 단위로 짧게 잡지 않는다.**
145
+ 회복이 느려서, 넓은 쿼리로 소모한 뒤에는 몇십 초나 몇 분을 기다려도 한 번 호출할 몫이 돌아오지 않는다.
146
+ 좁은 쿼리라면 훨씬 빨리 회복되지만, 정확한 값은 프로젝트와 쿼리마다 달라 넉넉히 잡는 편이 안전하다.
85
147
 
86
148
  ## 대량 export
87
149
 
@@ -105,10 +167,35 @@ nhncloud logncrash export \
105
167
  | `--force` | 기존 파일 덮어쓰기 |
106
168
  | `--size <n>` | 폐기 예정 호환 옵션. 10~100 검증 후 경고하고 v3 요청에는 미전달 |
107
169
 
108
- scroll 계속 요청이 실패하면 CLI가 원본 오류를 보존한다.
109
- 오류를 확인한 뒤 검색 시간 범위를 좁혀 다시 실행한다.
170
+ scroll 시작이나 계속 요청에서 서버가 500 응답을 반환하면 CLI가 해당 기간을 절반으로
171
+ 줄여 자동으로 다시 시도한다. 성공한 기간 크기는 남은 구간에도 재사용하므로 사용자가
172
+ 직접 기간을 나눠 호출할 필요가 없다.
173
+
174
+ 더 나눌 수 없는 기간에서도 500 응답이 계속되거나 다른 오류가 발생하면 CLI가 원본
175
+ 오류를 보존한다.
110
176
  `--size`는 v3 scroll의 페이지 크기를 제어하지 않는다.
111
177
 
178
+ 조회 횟수 제한을 만나면 기간을 나누지 않고 즉시 멈춘다.
179
+ 나눌수록 호출이 늘어 제한을 더 소모하기 때문이다.
180
+
181
+ ### 중단된 추출 이어받기
182
+
183
+ 추출이 실패하면 `--output`은 만들어지지 않는다.
184
+ 대신 그때까지 받은 결과가 `<output>.partial`에 남고, 위치와 이어받는 방법을 stderr로 알린다.
185
+
186
+ ```text
187
+ 안내: 여기까지 받은 3000건을 logs.jsonl.partial 에 남겼습니다.
188
+ 안내: 이어받으려면 --from "<시각>" --to "<시각>" 로 다시 실행하세요. 경계 구간의 로그가 중복될 수 있습니다.
189
+ ```
190
+
191
+ 안내에 나온 `--from` 값과 원래 `--to`를 그대로 넘겨 다시 실행한다.
192
+ 그 값은 아직 받지 못한 구간의 시작이며, 이미 받은 부분과 경계에서 겹칠 수 있다.
193
+
194
+ `--format json`이면 부분 파일도 배열을 닫아 그대로 파싱된다.
195
+ 한 건도 받지 못하고 실패하면 부분 파일을 만들지 않는다.
196
+
197
+ 부분 결과를 남기지 못하면 CLI가 그 사실을 경고로 알리고 원래 오류를 그대로 낸다.
198
+
112
199
  ## 로그 전송
113
200
 
114
201
  `logncrash send`는 collector host로 로그 한 건을 전송한다.
@@ -12,16 +12,15 @@ Management API는 공통 UAK 정적 헤더를 사용한다.
12
12
  nhncloud configure --uak-id <uak-id> --uak-secret <uak-secret> --ncr-appkey <appkey>
13
13
  ```
14
14
 
15
- `--app-key <key>`는 profile의 `ncr.appkey`보다 우선한다.
16
15
  기본 region은 `kr1`이고, `kr1`, `kr2`, `kr3`를 지원한다.
17
16
 
18
17
  ## Registry 조회
19
18
 
20
19
  ```bash
21
20
  nhncloud commands --json | jq '.commands[] | select(.path|startswith("ncr"))'
22
- nhncloud ncr list --app-key <appkey> --json
23
- nhncloud ncr list --region kr2 --app-key <appkey> --json
24
- nhncloud ncr get <registry> --app-key <appkey> --json
21
+ nhncloud ncr list --json
22
+ nhncloud ncr list --region kr2 --json
23
+ nhncloud ncr get <registry> --json
25
24
  ```
26
25
 
27
26
  `ncr list --json`은 `registries` wrapper를 언랩한 registry 배열이다.
@@ -40,8 +39,8 @@ nhncloud ncr tags <registry> <repository> --json
40
39
  ## 체이닝 예시
41
40
 
42
41
  ```bash
43
- nhncloud ncr list --app-key <appkey> --json | jq -r '.[].name'
44
- nhncloud ncr get <registry> --app-key <appkey> --json
42
+ nhncloud ncr list --json | jq -r '.[].name'
43
+ nhncloud ncr get <registry> --json
45
44
  nhncloud ncr images <registry> --json | jq -r '.[].repository'
46
45
  nhncloud ncr images <registry> --json | jq '.[] | {repository, artifact_count}'
47
46
  nhncloud ncr tags <registry> <repository> --json | jq -r '.[].tag'
@@ -53,7 +52,6 @@ nhncloud ncr tags <registry> <repository> --json | jq 'sort_by(.push_time) | las
53
52
  | 옵션 | 설명 |
54
53
  |------|------|
55
54
  | `--region <region>` | NCR region. 기본 `kr1` |
56
- | `--app-key <key>` | NCR appkey |
57
55
  | `--profile <name>` | 사용할 profile |
58
56
 
59
57
  ## 주의사항