{"id":"e495097a-cd34-4963-b04c-7025a01eda03","shortId":"CNgLzk","kind":"skill","title":"nodegroup","tagline":"NodeGroup operation Skill for the edgewize nodegroup project. Use this whenever the user wants to query, create, update, delete, bind, unbind, or troubleshoot NodeGroup resources, including node binding, namespace binding, workspace binding, and deployment/config inspection for n","description":"# NodeGroup Operations\n\n## Purpose\n\nUse this skill to perform real `nodegroup`-related operations in the `edgewize-io/nodegroup` environment.\n\nThis skill should help with:\n\n- listing and inspecting `NodeGroup`\n- creating, updating, patching, and deleting `NodeGroup`\n- binding and unbinding nodes\n- binding and unbinding namespaces\n- binding and unbinding workspaces\n- troubleshooting failed or incomplete nodegroup sync\n- checking deployment config under `config/nodegroup`\n\nPrefer using the bundled script `scripts/nodegroup_api.py` for authenticated KAPI operations. Use `kubectl` only as a verification or fallback tool when the API path is unavailable.\n\n## Prerequisites\n\nUse the bundled script:\n\n- `scripts/nodegroup_api.py`\n\nAuthentication model:\n\n- logs in against `/oauth/token`\n- stores token in `~/.kubesphere_token`\n- uses `KUBESPHERE_HOST`, `KUBESPHERE_USERNAME`, `KUBESPHERE_PASSWORD`, and `KUBESPHERE_TOKEN`\n\nSetup:\n\n```bash\ncd scripts\npip install requests\nexport KUBESPHERE_HOST=\"http://<kubesphere-host>\"\npython nodegroup_api.py login --username admin --password <password>\n```\n\nToken helpers:\n\n```bash\npython nodegroup_api.py clear-cache\npython nodegroup_api.py request GET /kapis/infra.kubesphere.io/v1alpha1/nodegroups\n```\n\n## Source of Truth\n\nWhen you need to confirm how an operation works, read these files first from the nodegroup source repository root:\n\n- `pkg/kapis/infra/v1alpha1/register.go`\n- `pkg/kapis/infra/v1alpha1/handler.go`\n- `pkg/kapis/infra/v1alpha1/workspace_handler.go`\n- `pkg/controller/nodegroup/nodegroup_controller.go`\n- `pkg/constants/constants.go`\n\nDo not invent unsupported operations. Base the workflow on the source repository.\n\n## Main Resources\n\n### NodeGroup\n\nCluster-scoped resource.\n\nImportant fields:\n\n- `spec.alias`\n- `spec.description`\n- `spec.manager`\n- `status.state`\n\n## Safe Operating Rules\n\n- Read-only requests: prefer `python nodegroup_api.py ...` query commands.\n- Write requests: perform only the exact requested change.\n- Do not delete resources unless the user explicitly asks for deletion.\n- For destructive or potentially disruptive actions such as node unbind or delete, confirm impact in your response if the request is ambiguous.\n- When changing bindings, verify the current state first, then apply the change, then verify the result.\n\n## Preferred Operation Flow\n\nFor any write operation, follow this order:\n\n1. Inspect the current resource.\n2. Apply the minimal required change.\n3. Verify the resulting resource and any affected node, namespace, or workspace.\n4. If sync looks wrong, inspect labels, annotations, and controller behavior.\n\n## Core Commands\n\n### 1. Query NodeGroups\n\n```bash\npython nodegroup_api.py nodegroup list\npython nodegroup_api.py nodegroup get <name>\n```\n\n### 2. Create a NodeGroup\n\n```bash\npython nodegroup_api.py nodegroup create \\\n  --name <nodegroup-name> \\\n  --alias \"<alias>\" \\\n  --description \"<description>\" \\\n  --manager \"<manager>\"\npython nodegroup_api.py nodegroup get <nodegroup-name>\n```\n\n### 3. Update or Patch a NodeGroup\n\nPrefer patching for small changes.\n\n```bash\npython nodegroup_api.py nodegroup patch <name> \\\n  --alias \"<new-alias>\" \\\n  --description \"<new-description>\" \\\n  --manager \"<manager>\"\npython nodegroup_api.py nodegroup get <name>\n```\n\nFor unsupported fields or ad hoc testing, use raw request mode.\n\nFor `PATCH`, send a JSON Patch array:\n\n```bash\npython nodegroup_api.py request PATCH /kapis/infra.kubesphere.io/v1alpha1/nodegroups/<name> '[{\"op\":\"add\",\"path\":\"/spec/alias\",\"value\":\"<new-alias>\"}]'\n```\n\n### 4. Delete a NodeGroup\n\nOnly do this when explicitly requested.\n\n```bash\npython nodegroup_api.py nodegroup delete <name>\n```\n\nIf delete hangs, inspect finalizers:\n\n```bash\npython nodegroup_api.py nodegroup get <name>\n```\n\nRelevant finalizer:\n\n- `finalizers.nodegroups.kubesphere.io`\n\n### 5. Bind or Unbind a Node\n\nNode binding is implemented through nodegroup APIs and reflected with label:\n\n- `apps.edgewize.io/nodegroup=<nodegroup-name>`\n\nRead current state:\n\n```bash\nkubectl get node <node-name> --show-labels\nkubectl get nodes -l apps.edgewize.io/nodegroup=<nodegroup-name>\n```\n\nOperate through the bundled script:\n\n```bash\npython nodegroup_api.py bind node --nodegroup <nodegroup-name> --node <node-name>\npython nodegroup_api.py unbind node --nodegroup <nodegroup-name> --node <node-name>\n\n# Verify\nkubectl get nodes -l apps.edgewize.io/nodegroup=<nodegroup-name>\nkubectl get node <node-name> -o yaml\n```\n\n### 6. Bind or Unbind a Namespace\n\nRead current state:\n\n```bash\nkubectl get ns <namespace> --show-labels\n```\n\nOperate through the bundled script:\n\n```bash\npython nodegroup_api.py bind namespace --nodegroup <nodegroup-name> --namespace <namespace>\npython nodegroup_api.py unbind namespace --nodegroup <nodegroup-name> --namespace <namespace>\n\n# Verify\npython nodegroup_api.py nodegroup get <nodegroup-name>\nkubectl get ns <namespace> -o yaml\n```\n\n### 7. Bind or Unbind a Workspace\n\n```bash\npython nodegroup_api.py bind workspace --nodegroup <nodegroup-name> --workspace <workspace>\npython nodegroup_api.py unbind workspace --nodegroup <nodegroup-name> --workspace <workspace>\n```\n\n## Troubleshooting Checklist\n\nWhen an operation appears to succeed but state is wrong, check these in order:\n\n1. Does the resource exist?\n2. Does it still have a finalizer?\n3. Are node labels correct?\n4. Are namespace or workspace labels/annotations correct?\n5. Did IPPool annotations or labels fail to sync?\n6. Is the feature enabled in nodegroup config?\n\nUseful checks:\n\n```bash\npython nodegroup_api.py nodegroup get <name>\nkubectl get node <node-name> -o yaml\nkubectl get ns <namespace> -o yaml\nkubectl get cm nodegroup-config -n kubesphere-system -o yaml\nkubectl get pods -n kubesphere-system | grep nodegroup\n```\n\nImportant constants:\n\n- `apps.edgewize.io/nodegroup`\n- `apps.edgewize.io/namespace-`\n- `nodegroup.infra.kubesphere.io/parent`\n- `infra.kubesphere.io/ippool-`\n\n## Deployment and Config\n\nIf the user asks how nodegroup is deployed or configured, inspect these files from the nodegroup source repository root:\n\n- `config/nodegroup/templates/nodegroup-apiserver.yml`\n- `config/nodegroup/templates/nodegroup-controller-manager.yaml`\n- `config/nodegroup/templates/nodegroup-config.yaml`\n- `config/nodegroup/values.yaml`\n\nConfigMap key:\n\n- `nodegroup.yaml`\n\nNotable config sections:\n\n- `scheduling`\n- `policy`\n- `rbac`\n- `ippool`\n\n## API-First Rule\n\nIf the user asks for an operation that already has a dedicated nodegroup API, prefer the bundled script and the dedicated nodegroup API semantics over manual label hacking.\n\nExamples:\n\n- node bind/unbind: use `python nodegroup_api.py bind node ...`\n- namespace bind/unbind: use `python nodegroup_api.py bind namespace ...`\n- workspace bind/unbind: use `python nodegroup_api.py bind workspace ...`\n- ad hoc API call: use `python nodegroup_api.py request ...`\n\nOnly fall back to direct manifest edits or label repair when the request is explicitly about low-level repair.\n\n## Response Style For This Skill\n\nWhen using this skill:\n\n- tell the user what operation you are performing\n- verify before and after state\n- mention any side effects or risks\n- if blocked by missing cluster credentials or missing API access, say exactly what is missing\n- if the operation is supported in code but cannot be executed in the current environment, provide the exact `nodegroup_api.py` command or API path to run next","tags":["nodegroup","kubesphere","agent-skills","cloud-native","cncf","devops","ebpf","hacktoberfest","kubernetes","llm","multi-cluster","multi-tenancy"],"capabilities":["skill","source-kubesphere","skill-nodegroup","topic-agent-skills","topic-cloud-native","topic-cncf","topic-devops","topic-ebpf","topic-hacktoberfest","topic-kubernetes","topic-kubesphere","topic-llm","topic-multi-cluster","topic-multi-tenancy","topic-observability"],"categories":["kubesphere"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/kubesphere/kubesphere/nodegroup","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add kubesphere/kubesphere","source_repo":"https://github.com/kubesphere/kubesphere","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 16934 github stars · SKILL.md body (7,393 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:52:40.050Z","embedding":null,"createdAt":"2026-04-27T06:52:19.661Z","updatedAt":"2026-05-18T18:52:40.050Z","lastSeenAt":"2026-05-18T18:52:40.050Z","tsv":"'/.kubesphere_token':136 '/ippool-':691 '/kapis/infra.kubesphere.io/v1alpha1/nodegroups':175,418 '/namespace-':685 '/nodegroup':56,682 '/nodegroup=':471,488,514 '/oauth/token':132 '/parent':688 '/spec/alias':422 '1':307,343,599 '2':312,355,604 '3':318,372,611 '4':330,424,616 '5':452,623 '6':520,632 '7':564 'access':847 'action':264 'ad':399,782 'add':420 'admin':161 'affect':325 'alia':365,388 'alreadi':740 'ambigu':280 'annot':337,626 'api':117,464,729,745,754,784,846,874 'api-first':728 'appear':588 'appli':290,313 'apps.edgewize.io':470,487,513,681,684 'apps.edgewize.io/namespace-':683 'apps.edgewize.io/nodegroup':680 'apps.edgewize.io/nodegroup=':469,486,512 'array':412 'ask':256,698,735 'authent':103,127 'back':792 'base':208 'bash':148,165,346,359,383,413,434,444,475,494,529,541,570,642 'behavior':340 'bind':21,29,31,33,73,77,81,283,453,459,497,521,544,565,573,766,773,780 'bind/unbind':762,769,776 'block':839 'bundl':99,124,492,539,748 'cach':170 'call':785 'cannot':861 'cd':149 'chang':247,282,292,317,382 'check':91,595,641 'checklist':584 'clear':169 'clear-cach':168 'cluster':219,842 'cluster-scop':218 'cm':659 'code':859 'command':239,342,872 'config':93,639,662,694,722 'config/nodegroup':95 'config/nodegroup/templates/nodegroup-apiserver.yml':714 'config/nodegroup/templates/nodegroup-config.yaml':716 'config/nodegroup/templates/nodegroup-controller-manager.yaml':715 'config/nodegroup/values.yaml':717 'configmap':718 'configur':704 'confirm':183,271 'constant':679 'control':339 'core':341 'correct':615,622 'creat':18,67,356,363 'credenti':843 'current':286,310,473,527,866 'dedic':743,752 'delet':20,71,250,258,270,425,438,440 'deploy':92,692,702 'deployment/config':35 'descript':366,389 'destruct':260 'direct':794 'disrupt':263 'edgew':7,54 'edgewize-io':53 'edit':796 'effect':835 'enabl':636 'environ':57,867 'exact':245,849,870 'exampl':760 'execut':863 'exist':603 'explicit':255,432,804 'export':154 'fail':86,629 'fall':791 'fallback':113 'featur':635 'field':223,397 'file':190,707 'final':443,450,610 'finalizers.nodegroups.kubesphere.io':451 'first':191,288,730 'flow':299 'follow':304 'get':174,354,371,394,448,477,483,509,516,531,558,560,646,648,653,658,670 'grep':676 'hack':759 'hang':441 'help':61 'helper':164 'hoc':400,783 'host':139,156 'impact':272 'implement':461 'import':222,678 'includ':27 'incomplet':88 'infra.kubesphere.io':690 'infra.kubesphere.io/ippool-':689 'inspect':36,65,308,335,442,705 'instal':152 'invent':205 'io':55 'ippool':625,727 'json':410 'kapi':104 'key':719 'kubectl':107,476,482,508,515,530,559,647,652,657,669 'kubespher':138,140,142,145,155,665,674 'kubesphere-system':664,673 'l':485,511 'label':336,468,481,535,614,628,758,798 'labels/annotations':621 'level':808 'list':63,350 'log':129 'login':159 'look':333 'low':807 'low-level':806 'main':215 'manag':367,390 'manifest':795 'manual':757 'mention':832 'minim':315 'miss':841,845,852 'mode':405 'model':128 'n':38,663,672 'name':364 'namespac':30,80,327,525,545,547,551,553,618,768,774 'need':181 'next':878 'node':28,76,267,326,457,458,478,484,498,500,504,506,510,517,613,649,761,767 'nodegroup':1,2,8,25,39,48,66,72,89,194,217,345,349,353,358,362,370,377,386,393,427,437,447,463,499,505,546,552,557,575,581,638,645,661,677,700,710,744,753 'nodegroup-config':660 'nodegroup.infra.kubesphere.io':687 'nodegroup.infra.kubesphere.io/parent':686 'nodegroup.yaml':720 'nodegroup_api.py':158,167,172,237,348,352,361,369,385,392,415,436,446,496,502,543,549,556,572,578,644,765,772,779,788,871 'notabl':721 'ns':532,561,654 'o':518,562,650,655,667 'op':419 'oper':3,40,50,105,186,207,229,298,303,489,536,587,738,823,855 'order':306,598 'password':143,162 'patch':69,375,379,387,407,411,417 'path':118,421,875 'perform':46,242,826 'pip':151 'pkg/constants/constants.go':202 'pkg/controller/nodegroup/nodegroup_controller.go':201 'pkg/kapis/infra/v1alpha1/handler.go':199 'pkg/kapis/infra/v1alpha1/register.go':198 'pkg/kapis/infra/v1alpha1/workspace_handler.go':200 'pod':671 'polici':725 'potenti':262 'prefer':96,235,297,378,746 'prerequisit':121 'project':9 'provid':868 'purpos':41 'python':157,166,171,236,347,351,360,368,384,391,414,435,445,495,501,542,548,555,571,577,643,764,771,778,787 'queri':17,238,344 'raw':403 'rbac':726 'read':188,232,472,526 'read-on':231 'real':47 'reflect':466 'relat':49 'relev':449 'repair':799,809 'repositori':196,214,712 'request':153,173,234,241,246,278,404,416,433,789,802 'requir':316 'resourc':26,216,221,251,311,322,602 'respons':275,810 'result':296,321 'risk':837 'root':197,713 'rule':230,731 'run':877 'safe':228 'say':848 'schedul':724 'scope':220 'script':100,125,150,493,540,749 'scripts/nodegroup_api.py':101,126 'section':723 'semant':755 'send':408 'setup':147 'show':480,534 'show-label':479,533 'side':834 'skill':4,44,59,814,818 'skill-nodegroup' 'small':381 'sourc':176,195,213,711 'source-kubesphere' 'spec.alias':224 'spec.description':225 'spec.manager':226 'state':287,474,528,592,831 'status.state':227 'still':607 'store':133 'style':811 'succeed':590 'support':857 'sync':90,332,631 'system':666,675 'tell':819 'test':401 'token':134,146,163 'tool':114 'topic-agent-skills' 'topic-cloud-native' 'topic-cncf' 'topic-devops' 'topic-ebpf' 'topic-hacktoberfest' 'topic-kubernetes' 'topic-kubesphere' 'topic-llm' 'topic-multi-cluster' 'topic-multi-tenancy' 'topic-observability' 'troubleshoot':24,85,583 'truth':178 'unavail':120 'unbind':22,75,79,83,268,455,503,523,550,567,579 'unless':252 'unsupport':206,396 'updat':19,68,373 'use':10,42,97,106,122,137,402,640,763,770,777,786,816 'user':14,254,697,734,821 'usernam':141,160 'valu':423 'verif':111 'verifi':284,294,319,507,554,827 'want':15 'whenev':12 'work':187 'workflow':210 'workspac':32,84,329,569,574,576,580,582,620,775,781 'write':240,302 'wrong':334,594 'yaml':519,563,651,656,668","prices":[{"id":"8847fee5-5fa1-4426-b70d-41f39c4d84d2","listingId":"e495097a-cd34-4963-b04c-7025a01eda03","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"kubesphere","category":"kubesphere","install_from":"skills.sh"},"createdAt":"2026-04-27T06:52:19.661Z"}],"sources":[{"listingId":"e495097a-cd34-4963-b04c-7025a01eda03","source":"github","sourceId":"kubesphere/kubesphere/nodegroup","sourceUrl":"https://github.com/kubesphere/kubesphere/tree/master/skills/nodegroup","isPrimary":false,"firstSeenAt":"2026-04-27T06:52:19.661Z","lastSeenAt":"2026-05-18T18:52:40.050Z"}],"details":{"listingId":"e495097a-cd34-4963-b04c-7025a01eda03","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"kubesphere","slug":"nodegroup","github":{"repo":"kubesphere/kubesphere","stars":16934,"topics":["agent-skills","ai","cloud-native","cncf","devops","ebpf","hacktoberfest","kubernetes","kubesphere","llm","multi-cluster","multi-tenancy","observability","servicemesh","skills","skills-sh","skillsmp"],"license":"other","html_url":"https://github.com/kubesphere/kubesphere","pushed_at":"2026-05-06T07:16:53Z","description":"The container platform tailored for Kubernetes multi-cloud, datacenter, and edge management ⎈ 🖥 ☁️","skill_md_sha":"9d0d74c098ae3825c84b003e7dbe14513a73b143","skill_md_path":"skills/nodegroup/SKILL.md","default_branch":"master","skill_tree_url":"https://github.com/kubesphere/kubesphere/tree/master/skills/nodegroup"},"layout":"multi","source":"github","category":"kubesphere","frontmatter":{"name":"nodegroup","description":"NodeGroup operation Skill for the edgewize nodegroup project. Use this whenever the user wants to query, create, update, delete, bind, unbind, or troubleshoot NodeGroup resources, including node binding, namespace binding, workspace binding, and deployment/config inspection for nodegroup."},"skills_sh_url":"https://skills.sh/kubesphere/kubesphere/nodegroup"},"updatedAt":"2026-05-18T18:52:40.050Z"}}