原始 JSON 报告 机器可读
{
"data": {
"repo": {
"topics": [
"asgardeo",
"choreo"
],
"is_fork": false,
"size_kb": 5404,
"has_wiki": false,
"homepage": "https://github.com/wso2/open-cloud-datacenter",
"languages": {
"HCL": 371036,
"Shell": 25622,
"Smarty": 7856,
"Go Template": 4789
},
"pushed_at": "2026-07-27T09:22:47Z",
"created_at": "2026-02-02T05:22:04Z",
"owner_type": "Organization",
"updated_at": "2026-07-27T04:59:22Z",
"description": "Open cloud datacenter initiative",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Apache-2.0",
"default_branch": "main",
"license_spdx_raw": "Apache-2.0",
"primary_language": "HCL",
"significant_languages": [
"HCL"
]
},
"owner": {
"blog": "https://wso2.com",
"name": "WSO2",
"type": "Organization",
"login": "wso2",
"company": null,
"location": "787 Castro Street, Mountain View, CA 94041",
"followers": 1731,
"avatar_url": "https://avatars.githubusercontent.com/u/533043?v=4",
"created_at": "2010-12-22T08:54:38Z",
"is_verified": null,
"public_repos": 383,
"account_age_days": 5697
},
"license": {
"state": "standard",
"spdx_id": "Apache-2.0",
"raw_spdx": "Apache-2.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "terraform/v0.1.9",
"kind": "other",
"published_at": "2026-07-24T04:47:13Z"
},
{
"tag": "terraform/v0.1.8",
"kind": "other",
"published_at": "2026-07-13T05:55:24Z"
},
{
"tag": "terraform/v0.1.7",
"kind": "other",
"published_at": "2026-06-30T10:31:05Z"
},
{
"tag": "terraform/v0.1.6",
"kind": "other",
"published_at": "2026-06-30T08:27:45Z"
},
{
"tag": "terraform/v0.1.5",
"kind": "other",
"published_at": "2026-06-26T04:17:50Z"
},
{
"tag": "terraform/v0.1.4",
"kind": "other",
"published_at": "2026-06-22T05:16:12Z"
},
{
"tag": "terraform/v0.1.3",
"kind": "other",
"published_at": "2026-06-18T12:18:14Z"
},
{
"tag": "terraform/v0.1.2",
"kind": "other",
"published_at": "2026-05-29T10:47:24Z"
},
{
"tag": "terraform/v0.1.1",
"kind": "other",
"published_at": "2026-05-29T05:53:07Z"
},
{
"tag": "terraform/v0.1.0",
"kind": "other",
"published_at": "2026-05-28T10:22:30Z"
},
{
"tag": "v0.8.3",
"kind": "patch",
"published_at": "2026-05-25T15:02:33Z"
},
{
"tag": "v0.8.2",
"kind": "patch",
"published_at": "2026-05-25T10:49:26Z"
},
{
"tag": "v0.8.1",
"kind": "patch",
"published_at": "2026-05-25T05:15:42Z"
},
{
"tag": "v0.8.0",
"kind": "minor",
"published_at": "2026-05-19T06:16:11Z"
},
{
"tag": "v0.7.9",
"kind": "patch",
"published_at": "2026-05-18T15:11:19Z"
},
{
"tag": "v0.7.8",
"kind": "patch",
"published_at": "2026-05-15T10:28:07Z"
},
{
"tag": "v0.7.7",
"kind": "patch",
"published_at": "2026-05-15T04:00:00Z"
},
{
"tag": "v0.7.6",
"kind": "patch",
"published_at": "2026-05-06T07:40:02Z"
},
{
"tag": "v0.7.5",
"kind": "patch",
"published_at": "2026-04-28T13:55:26Z"
},
{
"tag": "v0.7.4",
"kind": "patch",
"published_at": "2026-04-21T08:50:02Z"
},
{
"tag": "v0.7.3",
"kind": "patch",
"published_at": "2026-04-21T05:20:12Z"
},
{
"tag": "v0.7.2",
"kind": "patch",
"published_at": "2026-04-17T11:41:20Z"
},
{
"tag": "v0.7.1",
"kind": "patch",
"published_at": "2026-04-16T05:55:38Z"
},
{
"tag": "v0.7.0",
"kind": "minor",
"published_at": "2026-04-16T03:32:30Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2026-04-10T11:37:11Z"
},
{
"tag": "v0.5.8",
"kind": "patch",
"published_at": "2026-04-09T09:33:16Z"
},
{
"tag": "v0.5.7",
"kind": "patch",
"published_at": "2026-04-07T17:48:40Z"
},
{
"tag": "v0.5.6",
"kind": "patch",
"published_at": "2026-04-03T05:21:06Z"
},
{
"tag": "v0.5.5",
"kind": "patch",
"published_at": "2026-04-02T07:38:30Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2026-03-31T08:31:53Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2026-03-30T05:15:38Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2026-03-27T17:15:18Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2026-03-27T01:59:56Z"
},
{
"tag": "v0.1.0",
"kind": "minor",
"published_at": "2026-03-13T04:48:11Z"
}
],
"recent_commits": [
{
"oid": "25cb78eacee2ae426e3171b1113f24f1f46bb586",
"body": null,
"is_bot": false,
"headline": "fix: update the precondition check and namespace quota divided nonzeoro",
"author_name": "sathindudezoysa",
"author_login": "sathindudezoysa",
"committed_at": "2026-07-27T04:59:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d0f580e76be15c0348ed240a77775abae313b8e2",
"body": null,
"is_bot": false,
"headline": "fix: the auto split namespaces getting near zero resources",
"author_name": "sathindudezoysa",
"author_login": "sathindudezoysa",
"committed_at": "2026-07-27T04:59:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2e8d4b2c7eb567e57e4dc4852a19a373388dba49",
"body": "…project quota limits",
"is_bot": false,
"headline": "fix: set default namespace limits and set unit validation check with …",
"author_name": "sathindudezoysa",
"author_login": "sathindudezoysa",
"committed_at": "2026-07-27T04:59:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "73ded4dd7b2d608de63cf5ec7d2bca5db7eefefa",
"body": null,
"is_bot": false,
"headline": "fix: add preflight validation for namespace resource quotas",
"author_name": "sathindudezoysa",
"author_login": "sathindudezoysa",
"committed_at": "2026-07-27T04:59:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "67b3d7fe516f5af519fde5be4fd5903724e3b4d4",
"body": "CodeRabbit reads its configuration only from the repository's default\nbranch, so base_branches must be set here on main. Without it, CodeRabbit\nuses dashboard defaults and reviews only the default branch, skipping\npull requests targeting the long-lived controlplane, terraform,\noperators, and terrafo\n[…]\nis supersedes the per-branch .coderabbit.yaml files added earlier;\nthey live on non-default branches and are therefore never read.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Enable CodeRabbit on non-default branches",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-06-26T04:58:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "142a6ae7d5d547dad9c47f6340ff82c3fe67e13d",
"body": "The repository PR template was the generic WSO2-product template\n(Certification, Marketing, Training, FindSecurityBugs, a JDK/DB/browser\ntest matrix, ...). Almost none of it applies to this repo's products —\nthe Go control plane, the Terraform module catalog, or the operators —\nso contributors faced\n[…]\ner-repo names).\n\nGitHub serves the PR template only from the default branch, so this\nsingle file governs PRs against every branch.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Replace the legacy PR template with a lean one",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-06-11T08:12:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "73db130de358640948c900fcd78da90d03e2a4f9",
"body": "Add short dcctl and cloud-ui VNet-creation clips to the entry-point README, laid out side by side so the two demos stay compact.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add CLI and console demo clips to the README",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-30T12:13:45Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "686e76842e7aaf3dd6cacaa7ed7e4e4fdb72e271",
"body": "Repurpose the deprecated main branch as the repository's front door.\nGitHub renders this branch's README first, so it now opens with a\nbranch-navigation map and the OCD roadmap instead of Terraform module\nusage (which belongs on the terraform branch).\n\n - ASCII diagram + table mapping the terraform\n[…]\nES.md for detail.\n\nmain carries no code; the previous Terraform-flavored README content\nremains available on the terraform branch.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Make main the repo entry point and roadmap",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-30T09:22:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1cbfa40f8e0ddb1b9d3d00def3abeb4bc875043d",
"body": "Add structured issue forms under .github/ISSUE_TEMPLATE so issues\nare filed with consistent, triage-ready fields:\n\n - 01-bug: area, description, repro steps, severity, version\n - 02-improvement: area, current limitation, suggested improvement\n - 03-task: area, description, related issues\n - 04-e\n[…]\nform auto-applies its Type/* label. The broader label taxonomy\nis managed in repository settings, not in this change.\n\nCloses #127\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add GitHub issue form templates",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-30T04:56:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "81062c591e091a824e592e890fee17abf62f01a5",
"body": "Four fixes from automated review:\n\n* dc-controlplane-services: cloud-ui probe path is now configurable\n via cloudui_health_path. Default stays /healthz because the wso2\n cloud-ui image's nginx.conf serves it; consumers that ship a stock\n nginx-unprivileged image (no /healthz) override to /.\n\n* dc\n[…]\nts.\n\n* dc-controlplane: vm_storage_class_override is trimspace'd before\n the empty-string check so a whitespace-only override no longer\n wins precedence and propagates an invalid storage class name.",
"is_bot": false,
"headline": "Address CodeRabbit feedback on PR #107",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-27T03:23:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3f6672f2174fb2b3390c2a0f64880e98d75962b2",
"body": "Convert the dc-controlplane RKE2 cluster to a 3-node HA layout with\nkube-vip serving the apiserver VIP, and bring the cloud-ui Deployment\n+ Service + Ingress into the dc-controlplane-services module so a\ncluster rebuild restores routing without waiting for the cloud-ui CI\nworkflow.\n\nStorage:\n\n* Crea\n[…]\ns\n >= 1.7.\n\n* Apply trimspace() to user_data + storage_class_name override\n checks in workloads/k8s-cluster so whitespace-only inputs fall\n through to defaults instead of masking as real overrides.",
"is_bot": false,
"headline": "Add 3-node HA dc-controlplane + cloud-ui in TF",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-27T03:23:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5c3b20ae132f0230d94d15c0574fa6d30a1e68c1",
"body": "…ole binding for_each",
"is_bot": false,
"headline": "Fix same network multi attachemnts + static principal+index key for r…",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T15:02:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "82661f446182d20418ed0dc33b8f79414efa644d",
"body": null,
"is_bot": false,
"headline": "Fix description with uuid instead of email",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T10:48:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9a12ae12bea06d601d62cbb22681d57234ab5e90",
"body": null,
"is_bot": false,
"headline": "Add user_principal_id and user_id support for tenant role bindings",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T10:48:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "63caf20827baf5d28480fc7e3295b48480216694",
"body": null,
"is_bot": false,
"headline": "Address code rabbit issue regarding userdata template",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T05:14:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "67a7e1f8ea8de48947734b9b882e030b93b4c31b",
"body": null,
"is_bot": false,
"headline": "Addressing code rabbit concerns",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T05:14:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f66b284a28ab000608371b64fa5b9be30e4baa9a",
"body": "… tenants",
"is_bot": false,
"headline": "Feat: DHCP support for storage network + restricted images access for…",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T05:14:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "91ee1ffafd8c7ebe144867f42935f07d6d00970d",
"body": null,
"is_bot": false,
"headline": "Fix: bug when using harvester cluster name instead of id",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-25T05:14:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fdddf3581607be9d86f9b3f177bfc4467a3cede7",
"body": "Two fixes from the review on the OCD PR:\n\n * main.tf: base64-decode harvester_kubeconfig_b64 before storing\n it in the kubernetes_secret data field. The kubernetes provider\n auto-base64-encodes whatever string is passed into data, so the\n live Secret was holding base64-of-base64 — the webh\n[…]\nin description said\n \"ValidatingWebhookConfiguration\" but the module creates a\n MutatingWebhookConfiguration. Word-fix only.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address CodeRabbit review on dc-webhook module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-19T06:15:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f89a6ad73be61c8b9822bea0787862f968d7a2b9",
"body": "KubeVirt admission webhook that pins VM NIC MAC addresses for tenants\nwhose workloads sit behind a kube-ovn LB. Without MAC pinning,\nKubeVirt regenerates NIC MACs on VM restart, which breaks\nsticky-by-MAC connections that depend on a stable backend.\n\nThe module covers:\n * Deployment + Service for t\n[…]\n's\nenvironments/<env>/02-dc-webhooks layer instantiates this module\nper-environment with the appropriate kubeconfig and image SHA.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add dc-webhook module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-19T06:15:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "49e9eab3cf988b23468eb56d84680bb1622e5ad0",
"body": "A batch of dc-controlplane-services module changes that surfaced\nwhile verifying a real-world consumer's plan. Together they push\nevery per-environment knob out of consumer layers and into the\nmodule, so consumers only pass parameters going forward.\n\nChanges:\n\n * Eight BFF input variables (bff_clie\n[…]\n terraform validate clean; terraform plan\nagainst a representative dev environment shows only intentional\nchanges; apply succeeds.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Land BFF, VPC, hostname, env-order and lifecycle fixes",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-19T06:15:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e58680e1cc75d709e6781363f14d67b1a353eed6",
"body": "Introduce a self-signed RSA-4096 certificate (1-year validity) via the\nhashicorp/tls provider. The cert covers dcapi.lk.internal.wso2.com and\n*.lk.internal.wso2.com. A kubernetes.io/tls Secret (dc-api-tls) is\ncreated in dc-system and referenced by the Ingress tls block so\nnginx-ingress serves HTTPS on port 443.\n\nPort-80 rules are preserved unchanged. No new variables are required.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add TLS termination to dc-api ingress",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-19T06:15:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2f931c065aa19c25671ff70d21cb2c9cee377158",
"body": null,
"is_bot": false,
"headline": "Introduce support to provision RKE2 clusters with dynamic harvester",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-18T14:37:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "04c160cf16ace509ac793dc3d4fc216cf9bedbb0",
"body": "Bind tenant SAs to harvesterhci.io:csi-driver for RWX",
"is_bot": false,
"headline": "Merge pull request #98 from wso2/fix/97-csi-driver-clusterrolebinding",
"author_name": "Deependra Ariyadewa",
"author_login": "gnudeep",
"committed_at": "2026-05-15T10:17:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4d942a597f9fbd92d7b667a57b63120cf672dcd6",
"body": "PR #96 added a custom harvester-cloud-provider-rwx ClusterRole and\ntwo namespaced RoleBindings to cover networkfilesystems + longhorn\nvolumes. End-to-end testing on kasun-test-cluster after that landed\nshowed RWX PVCs went Bound but pods failed to mount with\n`Failed to get NetworkFS ...: not found`.\n[…]\n logs quiet\non already-provisioned tenants. Namespace deletion explicitly removes\nthe ClusterRoleBinding since cluster-scoped resources are not GC'd\nwhen their tenant namespace is removed.\n\nCloses #97",
"is_bot": false,
"headline": "Bind tenant SAs to harvesterhci.io:csi-driver for RWX",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-15T10:10:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "96db11551a95e31da82f9e4382c36e3810f89f0f",
"body": null,
"is_bot": false,
"headline": "fix: typo in comment - coderabbit",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-15T06:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7593a6683d904c7d745ca1c0c36c32ed8c3dbaba",
"body": null,
"is_bot": false,
"headline": "fix: remove label platform role from default namespace",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-15T06:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "416557c14cdca2d021c51ea5ee9edb48c8eb367e",
"body": null,
"is_bot": false,
"headline": "fix: addrss coderabbit issues",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-15T06:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ba18d94f0b5a4612a36e2f7dec4f0f53d25f0cf0",
"body": null,
"is_bot": false,
"headline": "fix: management/tenant-module quota management + vm module enhancements",
"author_name": "iamtrazy",
"author_login": "iamtrazy",
"committed_at": "2026-05-15T06:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3dddc058ca07466f771724fd2b3c21ecf02890da",
"body": "The harvester-csi-driver running on guest RKE2 clusters probes\nnetworkfilesystems.harvesterhci.io and volumes.longhorn.io on the\nhost Harvester cluster at startup. On a Forbidden response it\nsilently disables RWX support and only advertises SINGLE_NODE_WRITER,\nso every subsequent RWX CreateVolume fa\n[…]\nnamespace, backfills them in the init pass\nfor already-provisioned namespaces, and removes them in\non_deleted_namespace. All operations use the existing idempotent\n`kubectl apply` pattern.\n\nCloses #95",
"is_bot": false,
"headline": "Grant tenant cloud-provider SAs RWX RBAC on Harvester",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-15T03:59:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ed820b15c09815f0ee714dad93f970dfbb0bd2ac",
"body": "Two findings from CodeRabbit on PR #93:\n\n1. Avoid fixed runtime files under path.module\n The helm kubeconfig and dc-runner values files used hardcoded names\n in the module source dir, which would collide if the module is\n instantiated more than once or two applies share a checkout. Append\n a\n[…]\n--values) so values containing\n spaces don't break the command line. Destroy guards no-op via an\n if [[ -z … ]] short-circuit.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address CodeRabbit review on helm CLI bypass",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-10T13:04:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e5a9c5f92f047742c63b29d4f42f541ab4a5b038",
"body": "The TF helm provider repeatedly fails when posting the ARC controller's\nrelease Secret through Rancher 2.14's cluster-router proxy with\n\"http: request body too large\" — even with public-api-body-limit and\nthe rancher Ingress proxy-body-size both raised to 50Mi/50m. The\ncluster-router has its own har\n[…]\n hashicorp/local and hashicorp/null providers in versions.tf\n - destroy-time helm uninstall provisioners with on_failure=continue\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bypass helm provider with helm CLI for ARC chart install",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-10T13:04:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "32a4e6c2fa7fe583335a35f60b0313d5bccb1444",
"body": "Add PostgreSQL liveness probe so Kubernetes can restart a hung or\ndeadlocked Postgres process; readiness alone only gates traffic.\n\nAdd pod-security.kubernetes.io/enforce=privileged label to the\narc-runners namespace so dind runner pods are not silently blocked\nby PSA admission on clusters with non-default security policies.\nThe dind container mode is preserved as the runner may need Docker\nbuild capabilities in future workflows.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(dc-controlplane-services): address CodeRabbit review",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-06T05:01:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "33c7b3f1dca73920813fc1eade56c7c78ff684ad",
"body": "tenant-space requires kubernetes.harvester via configuration_aliases.\ndc-controlplane must declare it in required_providers and forward it\nto module \"project\" via the providers meta-argument.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Wire kubernetes.harvester provider through dc-controlplane",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-06T05:01:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e25677b1e4001342ecc93abc29997f0888396532",
"body": "Rancher injects cattle.io/status, lifecycle.cattle.io/create.namespace-auth,\nand field.cattle.io/publicEndpoints automatically. kube-vip injects\nkube-vip.io/loadbalancerIPs and kube-vip.io/vipHost on the ingress LB\nservice. Without lifecycle ignore_changes, terraform plan always shows\nthese as diffs to remove even though the apply is a no-op.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Ignore Rancher/kube-vip managed annotations on k8s resources",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-06T05:01:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2a1bb84cae6c42b1ca4059f07cb17073f01f1fb2",
"body": "- Fix invalid trim() call: use trimspace() in credential_namespace\n validation (trim() requires two args; trimspace() strips whitespace)\n- Drop namespaces from dc-api-deployer Role: namespaces is cluster-\n scoped and silently ineffective inside a namespace-scoped Role\n- Add validation block to log_level variable: enforce the four allowed\n values so typos fail at plan time instead of propagating to the\n ConfigMap\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address CodeRabbit review on dc-controlplane-services",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-06T05:01:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3355d9fc6a64da7642f5d4e6e2ff6787415f947b",
"body": "dc-controlplane: wraps the RKE2 cluster, Harvester NAD, and LB\nIPPool for the DC-API control plane. Includes the kubectl patch\nthat sets selector.scope on the IPPool (workaround until the\nHarvester provider exposes the field declaratively).\n\ndc-controlplane-services: wraps all workloads that run on \n[…]\nster — PostgreSQL StatefulSet, DC-API Deployment and\nIngress, ARC controller + runner scale set, and all Kubernetes\nsecrets. Environment layers become thin callers with no inline\nresource definitions.",
"is_bot": false,
"headline": "Add dc-controlplane and dc-controlplane-services modules",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-06T05:01:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "61b04a55858dcba6abf9e1bd29b389f9d4c6ec6b",
"body": "Add VM image and storage management to the bootstrap module:\nnew variables for image source URL, disk size, and storage class;\ncloud-init template extended with additional packages and disk\nsetup; outputs expose the provisioned image ID for downstream\nlayers.\n\nImprove the namespace-credential-provisioner reconcile script to\nhandle edge cases and surface clearer error messages on failure.",
"is_bot": false,
"headline": "Extend bootstrap and reconcile modules",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-06T05:01:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fa14460d931f4d5fd87646c09d3fc05f91739cd9",
"body": "Cloud-init user_data carries SSH authorized keys, bootstrap tokens,\nand other credentials. Without sensitive = true, the value is emitted\nin plain text during terraform plan and stored without redaction in\nstate.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Mark user_data variable as sensitive",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-05T16:40:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "87996c727af13b9205b5229a2dd9a4e5d0ccb7c7",
"body": "Wraps tenant-space + workloads/k8s-cluster into a single opinionated\nmodule for provisioning a Rancher project, its DC-API VM namespace,\nthe Harvester NAD and IPPool for that namespace, and a managed RKE2\ncluster with the Harvester cloud provider attached. Consumers pass\nmachine pool definitions and\n[…]\nter\nLonghorn-backed VM disks; without them, both controllers lose their\nleases and crashloop every ~80 seconds during initial cluster\nbring-up.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add dc-controlplane management module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-05T16:40:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "673126d1e4266ad205622b5015efcf55b5486909",
"body": "Two reconciler hardening fixes for the namespace-credential-provisioner:\n\n1. Cluster watch race with namespace watch\n When a cluster is created in close succession with its tenant\n namespace, the cluster event can arrive before the namespace watch\n has minted the cloud-provider ServiceAccount \n[…]\nredentials provisioned. Skip them in both the watch\n loop and the reconciler-restart sweep, alongside the existing\n network-namespace skip.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Wait for SA token and skip infrastructure namespaces",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-05T16:27:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "acde3cbe79c2eb4ee3e21564e8f2668873241236",
"body": "Move cloud image download into the module via image_url,\nimage_name, and image_display_name variables. ubuntu_image_id\nis kept as an optional brownfield escape hatch when the image\nalready exists in the cluster.\n\nAdd storage class management: creates harvester-longhorn-2r as\nthe cluster default (con\n[…]\nfy the server certificate,\nand add a wait loop for the supervisor port before joining.\nAdd LB port 9345 listener for RKE2 HA supervisor join.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(bootstrap): add image and storage management",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-04T06:57:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bdf2c0fe0646b1a4ab1474a853400678ad9181a2",
"body": "Add validation block to credential_namespace to reject empty or\nwhitespace-only values before plan/apply.\n\nAdd check block for coredns_patch_vars_set so that setting\npatch_coredns = true without both rancher_lb_ip and rancher_hostname\nfails early with a clear error instead of silently rendering an empty\nhosts entry in the CoreDNS Corefile.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address CodeRabbit review on harvester-integration module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-04T06:57:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "588e6a2b5b1da653e5cf8b2c6334659dcbab8f17",
"body": "The SA and token Secret for the cloud credential were hardcoded to\nkube-system. Brownfield deployments that created these resources in\na different namespace (e.g. default) would see a forced replacement\non every apply due to the namespace drift.\n\nExpose credential_namespace (default: kube-system) so consumers can\npin the value to match their existing state.\n\nCloses #82",
"is_bot": false,
"headline": "Add credential_namespace variable to harvester-integration",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-05-04T06:57:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "291c8a35140588d2f23ada81f5b18074fe4dfaa9",
"body": "Kubernetes auto-adds kubernetes.io/metadata.name to every namespace\non creation. The rancher2 provider does not manage this label but\ndetects it as drift, producing a spurious remove-label diff on every\nplan run.\n\nAdding it to lifecycle ignore_changes on both rancher2_namespace.this\nand rancher2_namespace.network suppresses the noise permanently without\naffecting any managed label.\n\nCloses #79\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Ignore kubernetes.io/metadata.name label drift in namespaces",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-28T13:55:01Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "567f84d1e94bf0c4e1ac399bca940aa685e31606",
"body": "Replace the fine-grained per-API-group rules with a wildcard grant\ncovering all Kubernetes resources, subresources (*/scale, pods/exec,\npods/log), and non-resource URLs. This is the same permission set as\nthe built-in cluster-admin ClusterRole.\n\nRancher cluster lifecycle operations (delete, reconfigure) are\nenforced at the Rancher management-plane level independently of\nthis Kubernetes RBAC role.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Broaden cluster-contributor to full cluster-admin-equivalent access",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-28T13:37:26Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9590fea384401f2ae1749c5198ccf5e5061c2a87",
"body": "Introduces a cluster-scoped role template that grants SRE teams full\nkubectl operational access to downstream RKE2 clusters without\nRancher management-plane permissions. Members can deploy, scale,\nexec, stream logs, and manage workload config but cannot delete or\nreconfigure the cluster from the Ran\n[…]\nility. Explicitly excludes node mutation, RBAC\nmutation, and namespace lifecycle operations, which remain with the\nplatform team.\n\nCloses #78\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add cluster-contributor role for SRE operational access",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-28T13:37:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "184e145c75448745cc534ff60ffbc39ba5f137d4",
"body": "Introduces the project-contributor RoleTemplate for Rancher projects.\nThe role allows namespace and project member management (full CRUD on\nnamespaces and projectroletemplatebindings), read-only access to the\nproject resource itself to prevent quota modification or deletion, and\nread-only visibility\n[…]\nand Claude Code artefacts to .gitignore\nto keep module-level lock files and personal editor configs out of the\nmodule repository.\n\nCloses #75\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add project-contributor role with batch workload access",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-28T11:26:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a94b203affc3058fb9bed814e6d2dd50efe1520c",
"body": null,
"is_bot": false,
"headline": "feat(vm): add brownfield override variables",
"author_name": "Akini Karunarathne",
"author_login": "Akini98",
"committed_at": "2026-04-28T05:17:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "974efa83d62f6d94cc7bae1ef57768f09c011ac0",
"body": "Adds README for namespace-credential-provisioner documenting the\nmodule's purpose, deployment sequence relative to harvester-integration\nand tenant-space, and usage example.\n\nUpdates docs/architecture.md:\n- Adds namespace-credential-provisioner (Phase 2e) to the dependency\n graph between rbac (Phas\n[…]\nxes harvester-cloud-credential README: replaces non-existent\nkubeconfig output entry with the actual service_account_name output.\n\nCloses #73\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bundle namespace-credential-provisioner into management setup phase",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-28T05:07:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b61386fee27c4a4831a86d529de1151e56d2e3a5",
"body": "Extends the namespace-credential-provisioner reconciler to create\nper-namespace VM-access credentials alongside cloud-provider creds:\n - SA harvester-vm-access-<ns> with harvesterhci.io:edit RoleBinding\n in the tenant namespace, edit in harvester-public for shared images\n - harvester-vm-kubecon\n[…]\n.\n\nUpdates READMEs for vm, k8s-cluster, and harvester-cloud-credential\nmodules with inline kubeconfig pattern and usage examples.\n\nCloses #71\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add VM access kubeconfig provisioning and consumer onboarding docs",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-27T10:00:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4ad8797a693a1f98a057ddb00d69208696b6c422",
"body": "On init, check whether the SA token secret already exists before\ncalling on_added_namespace. Distinguishes NotFound (provision) from\ntransient kubectl errors (skip with warning, retry on watch event).\nOnly marks the namespace processed when provisioning succeeds.\n\nAlso adds:\n- vlan_id uniqueness val\n[…]\n4)\n- harvester_api_server variable to tenant-space for VM access kubeconfig\n- Removes \"or empty\" wording from vlan_id description\n\nCloses #69\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Skip already-provisioned namespaces on reconciler restart",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-27T04:57:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9d502de9f7e3617fc7db4a81bf51289295cc83a6",
"body": "Guard against an empty string being passed as the network namespace\noverride — coalesce accepts \"\" as truthy so validation is the right\nfix, consistent with other string variables in this module.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add non-empty validation for network_namespace_name",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T08:49:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "42349d5e50d56fa96ebc0b9307617120ffad9584",
"body": "- vlan_id is now list(number); each entry creates a harvester_network\n via for_each so networks can be added/removed independently\n- Auto-route path (no vyos_endpoint) supports multiple VLANs; VyOS\n path still requires exactly one VLAN (precondition enforced)\n- network_namespace_name override lets\n[…]\nwnfield\n harvester_network resources with non-default names\n- network_name output replaced by network_names map keyed by VLAN ID\n\nCloses #67\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Support multiple VLAN networks per tenant space",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T08:49:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "71d351dd66dd4f73e9803f1c0e2ac8cf361fe41c",
"body": null,
"is_bot": false,
"headline": "Address CodeRabbit review",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T06:39:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "75b04a8c678e085f9071b58e2b50f78c76313f18",
"body": null,
"is_bot": false,
"headline": "Add flag to control default namespace creation",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T06:39:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "72cb731b6d05a75a957ba74445f2ef02de825d3c",
"body": "Checkov CKV_K8S_21 flags resources placed in the default namespace.\nMove the rancher-cloud-credential ServiceAccount and its token Secret\nto kube-system, which is the conventional namespace for infrastructure-\nlevel service accounts.\n\nThe ClusterRoleBinding subject namespace reference is derived from\nthe ServiceAccount metadata, so no separate change is needed there.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Move cloud credential SA and token to kube-system namespace",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:19:18Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "83033f835e512b6124ca68826eaa579fbde202c9",
"body": "Exposes the Harvester Kubernetes API server URL extracted from\nthe kubeconfig so downstream layers can pass it to the\nharvester-cloud-credential module without hardcoding the VIP.\n\nMarked sensitive because it derives from the kubeconfig input.\nReturns null when create_cloud_credential = false.\n\nCloses #57\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add harvester_api_server output to harvester-integration module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:19:18Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c64fe870fddfc18f5d0154d31d14b0c479577c67",
"body": "When vlan_id is set without vyos_endpoint, use route_mode=auto so the\nupstream router (DigiOps / physical switch) handles DHCP and routing.\nThe manual route_mode with deterministic 10.0.0.0/8 subnetting is now\ngated on vyos_endpoint being set.\n\n- Add use_vyos local; gate tenant_subnet/tenant_gateway\n[…]\ntional\n- Relax vlan_id validation from >= 1000 to valid 802.1Q range (1–4094)\n- Update subnet_cidr/gateway_ip output descriptions (VyOS-only)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Support auto route mode for non-VyOS VLAN networks in tenant-space",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:05:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f1b43b93d109df80912a8a6cf2f78981b017d2f5",
"body": "- tenant-space/variables.tf: vyos_endpoint and vyos_api_key were\n declared twice after the create_network_namespace commit merged\n them in alongside pre-existing copies from the decouple branch.\n- vyos-tenant/outputs.tf: subnet_cidr output was declared twice,\n once as the canonical output and once as an alias added earlier.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Remove duplicate variable and output declarations",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:05:31Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "730ce9b918eea20a154d8da24fd47fd264a89b05",
"body": "The vyos provider was listed unconditionally, forcing every caller to\nconfigure it even when vyos_endpoint is null and no VyOS resources are\ncreated. The provider is only needed by the child vyos-tenant module,\nwhich declares its own required_providers — Terraform picks it up\ntransitively without it being declared in the parent.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Remove vyos from tenant-space required_providers",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:05:31Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "59dbfb577ec59bcfaaac587d98a82d0a12439386",
"body": "tenant-space:\n- Add create_network_namespace (bool, default false) to pre-provision\n the <project_name>-net namespace before a VLAN is assigned. The\n network namespace is created when create_network_namespace = true OR\n when vlan_id is set (backward compat: existing callers with vlan_id\n are una\n[…]\narvester_network moving from the vyos-tenant child module address to\nthe tenant-space address — a targeted import is required on first apply.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add create_network_namespace flag; fix harvester_network ownership",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:05:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ff093ce961533f2e57752dec7d51725779e7c4f6",
"body": "Previously, setting vlan_id always invoked the vyos-tenant module,\nmaking it impossible to create a network namespace + harvester_network\nwithout VyOS config calls.\n\nNow vlan_id and vyos_endpoint are independent gates:\n- vlan_id only: creates network namespace + harvester_network (for\n environments\n[…]\no the network\nnamespace (used by the namespace credential provisioner), and fixes\na pre-existing missing newline in variables.tf.\n\nCloses #63\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Decouple VyOS integration from network namespace in tenant-space",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T05:05:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5c35e894cfdcdecb8049b6db46c00c23ef380fd5",
"body": "- Change harvesterconfig Secret type from non-standard \"secret\" to\n \"Opaque\" to match Kubernetes convention and avoid potential\n filtering by Rancher controllers\n- Skip Terminating namespaces in the initial pass by reading\n deletionTimestamp from the jq pipeline; prevents failed kubectl\n apply calls against namespaces in the process of being deleted\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix secret type and skip Terminating namespaces at startup",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T04:39:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "47e427aed0b19e0e34ec65f1d8b09a87747c4845",
"body": "- Remove token-presence early return in on_added_namespace so all\n SA/RBAC resources are re-applied idempotently on every ADDED event,\n repairing drift caused by deleted ServiceAccounts or RoleBindings\n- Mark namespaces/clusters as processed only after the handler\n succeeds; transient failures (n\n[…]\nt\n- Replace `func || true` with `func || log \"...exited with error\"` so\n watch-loop failures are visible in logs instead of silently ignored\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix reconciler idempotency and error handling",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T04:39:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c19f412ec899b43421e2b319858d67515406baeb",
"body": "The net-read RoleBinding creation was failing with:\n user ... is attempting to grant RBAC permissions not currently held\n\nKubernetes RBAC escalation prevention blocks a subject from granting\npermissions it doesn't hold. Fix by adding the escalate verb to the\nrolebindings rule — the approved mechani\n[…]\nrovider (cloudprovider\nSA binding) and view (net-read binding). Restricting to a single name\nprevented the second binding from being created.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add escalate verb and broaden clusterroles bind in provisioner RBAC",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T04:39:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "00b8461e10f9a18ee9cd63e7778bec083acc54be",
"body": "Replace the substring kubeconfig body search with an exact annotation\nmatch when finding harvesterconfig-* secrets to delete on namespace\nremoval. The previous contains(\"namespace: \" + $ns) check would match\nprefix namespaces (e.g. \"team-a\" incorrectly matching \"team-a2\").\n\nAdd platform.wso2.com/cre\n[…]\nsource-namespace annotation to the\nsecret at creation time so the deletion path can do a precise lookup\nwithout decoding the kubeconfig body.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix stale-secret cleanup to use exact annotation match",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T04:39:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ca59d867ad991607ba3a40a48778b16931f9ad5e",
"body": "Adds modules/management/namespace-credential-provisioner — a Kubernetes\nDeployment that runs a reconciler script to automate harvesterconfig\nsecret management across tenant lifecycle events.\n\nWhat it does:\n- Watches Harvester namespaces; on new tenant namespace provisions a\n ServiceAccount (harvest\n[…]\ne includes configmaps get (kube-root-ca.crt for CA\ncert), patch/update on serviceaccounts/secrets/rolebindings for\nkubectl apply idempotency.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add namespace credential provisioner module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-21T04:39:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "034f12ec0b6bacf59fb7c17f33ae6ffbd1d72022",
"body": "Downstream layers that provision RKE2 clusters need the\ncattle-global-data:cc-xxxx ID for the k8s-cluster module.\nReturns null when create_cloud_credential = false so brownfield\nenvironments that manage the credential outside Terraform are\nnot affected.\n\nCloses #55\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Expose cloud_credential_id from harvester-integration module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-17T11:37:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "db8282a7afd73e12f907ee570c219660fbfe78a3",
"body": "Callers can now pass node_password, ssh_authorized_keys, and\nntp_server instead of composing raw cloud-init YAML. The module\ngenerates a full RKE2-ready cloud-init (packages, IPVS kernel\nmodules, sysctl, NTP) via templatefile.\n\nuser_data remains a full override. ssh_user (existing variable)\nis reused as the username in the generated chpasswd.list entry.\n\nCloses #53\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add node_password and ssh_authorized_keys to k8s-cluster module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-17T11:37:20Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9ca3818c6f0b8a7821153ac37e346c811531ebd1",
"body": "Callers can now pass `password`, `ssh_authorized_keys`, and\n`default_user` instead of composing raw cloud-init YAML. The\nmodule generates a correct chpasswd.list-based cloud-init using\na templatefile, avoiding heredoc indentation pitfalls.\n\n`user_data` remains a full override — when set, the new\nvariables are ignored entirely. `default_user` defaults to\n\"ubuntu\" but can be changed for non-Ubuntu images.\n\nCloses #53\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add password and ssh_authorized_keys to vm module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-17T11:37:20Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e8f209f14e8d1e5552a6e628168666ff7aec9471",
"body": "The dynamic resource_quota on rancher2_namespace.this was wrong:\nit assigned the full project quota to every namespace, which would\nprevent users from adding more namespaces and causes double\nenforcement. The project-level quota is already the ceiling —\nRancher enforces it across all namespaces without a per-namespace\nResourceQuota object. Remove the block and document why.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Revert per-namespace quota block from tenant-space module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:55:07Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "dcf23cf9bcad9614b28bb7a36e779d5247bb5254",
"body": "The vyos-tenant submodule requires both variables but tenant-space\nwas not declaring or passing them. Add vyos_endpoint and\nvyos_api_key as optional (default null) variables to tenant-space\nand pass them through to the module \"vyos_tenant\" call.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Thread vyos_endpoint and vyos_api_key through tenant-space module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:55:07Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "91a445e1ecb8a08736a61d399f702dd9723af67e",
"body": "Rancher does not reliably propagate namespace_default_limit to\nnamespaces created via the API. Without an explicit resource_quota\nblock on the rancher2_namespace resource, the namespace ResourceQuota\ncan end up with limits.cpu=0 / limits.memory=0, which blocks all\nVM creation with \"exceeded quota\".\n\n[…]\nat\nmirrors the project's per-namespace limits whenever cpu_limit is set.\n\nAlso fix a cosmetic syntax error (missing newline) in variables.tf.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Explicitly set namespace resource quota in tenant-space module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:55:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "066762c17b683aac7f5d2d10cf563d549ffbb93a",
"body": "Move network-attachment-definitions read from vm-creator (cluster)\nto vm-manager (project). Keeping it cluster-scoped let tenants list\nNADs in all namespaces, exposing other tenants' networks and platform\ninfrastructure in the VM creation network dropdown.\n\nWith it project-scoped, the Harvester UI o\n[…]\nrom\nthe tenant's own project namespaces (e.g. choreo-sre-net) — no\nvisibility into default/, harvester-public/, or other tenants.\n\nCloses #51\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Scope network visibility to tenant project in RBAC roles",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:55:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b05d5efb986238245e88cf19478ed6ea784ec9a9",
"body": "tenant-space/outputs.tf references module.vyos_tenant[0].subnet_cidr\nbut the vyos-tenant module only exposed subnet. Add subnet_cidr as\nan alias so both names resolve correctly.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add subnet_cidr output alias to vyos-tenant module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:54:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c28714385193a817c99ae3d4a87996ba9e03d465",
"body": "Rewrite all vyos_config_block_tree resources to use the\nhiranadikari/vyos provider schema:\n- path: list of strings (was a space-separated string)\n- section: jsonencode({...}) (was configs = {key = value} map)\n\nMerge the separate dhcp_dns resource into the main dhcp section —\ndns_servers is now a JSO\n[…]\nider source from thomasfinstad/vyos-rolling (~> 19.0)\nto hiranadikari/vyos (~> 0.1). Remove unused locals: vif_path,\nsubnet_base.\n\nCloses #49\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix vyos-tenant module for hiranadikari/vyos provider schema",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:54:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b4d101aad7a8d62d870caabe5704150b93e55717",
"body": "Change thomasfinstad/vyos-rolling (~> 19.0) to hiranadikari/vyos\n(~> 0.1) — the published provider that exposes the\nvyos_config_block_tree resource used in this module. Without this,\nterraform init pulls the wrong provider and plan fails with\n\"does not support resource type vyos_config_block_tree\".\n\nCloses #49\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix vyos provider source in vyos-tenant module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-16T05:54:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "fd74aae8bfec8b770f59c4c9c73ae5e9cf4a2983",
"body": "- vlan_id (optional): when set, creates a <project_name>-net network\n namespace and calls the vyos-tenant submodule to provision the\n Harvester NAD, VyOS vif sub-interface, DHCP server, and NAT rule.\n Adds harvester and vyos to required_providers.\n\n- namespaces defaults to null, resolved to [proj\n[…]\ncenter uses a different name.\n\n- network_name, subnet_cidr, gateway_ip, network_namespace outputs\n added (all null when vlan_id is not set).\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Extend tenant-space with optional VyOS VLAN network integration",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-12T04:09:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "91f449c433465cd2cd9bf9b52e4e0824d6abfc9b",
"body": "Narrow lifecycle ignore_changes from [disk] to [disk[0].auto_delete]\nso only the specific Harvester-caused drift (auto_delete flag flip on\nrootdisk post-CDROM removal) is suppressed; other disk attributes\nremain Terraform-managed.\n\nAdd validation block to management_network_name enforcing null or\nthe required namespace/name format, catching malformed values at\nplan time rather than failing at provider apply.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address CodeRabbit review on vyos bootstrap module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-12T04:09:07Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2c21e3203c2a26259a6015b56ff2745779430500",
"body": "- Optional eth2 NIC via management_network_name variable. When set,\n attaches VyOS to the Harvester management cluster network (mgmt-br)\n so in-cluster processes (DHCP reconciler pods with hostNetwork) can\n reach the VyOS HTTPS API at a stable IP without routing through the\n external uplink inte\n[…]\nM resource prevents a\n perpetual diff caused by Harvester flipping auto_delete on the\n rootdisk after the CDROM is removed on second apply.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add optional management NIC and fix disk lifecycle in vyos module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-12T04:09:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "24192322e7c5330fb91fb206fadf1737ef6ef9ea",
"body": "The provider is published at registry.terraform.io/hiranadikari/asgardeo.\nThe previous source 'asgardeo/asgardeo' does not exist on the registry\nand would fail on terraform init without a dev_override.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix asgardeo provider source to hiranadikari/asgardeo",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-11T17:18:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7613d4dc88affee6595e21ee7802e30be63510ba",
"body": "cloud-init runs only on first boot. Any subsequent changes to\nuser_data (template reformats, key rotation, etc.) have no\nruntime effect but previously triggered an in-place VM restart.\n\nCloses #41\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Ignore cloudinit changes after VM is provisioned",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-11T16:51:45Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "39a5f2fd4f571dc504d5b861297d5f816b67e038",
"body": "Use a template for-loop instead of indent()/join()/formatlist()\nto emit ssh_authorized_keys list items — the previous expression\nproduced 8 spaces of leading whitespace (4 from the heredoc + 6\nfrom indent), which broke cloud-init YAML parsing.\n\nAdd prose note and example variable declarations to make clear\nthat vm_password and ssh_authorized_keys are root-module variables,\nnot inputs to this module.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix cloud-init SSH key indentation and clarify variable scope",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1cc0c2a204ab1bb8c573634ecfe0659621cedc76",
"body": "Replace the generic nginx example with a validated pattern that avoids\ntwo known issues on Ubuntu 22.04 with cloud-init 25.x:\n\n- Do not use package_update: true — it races with apt-daily timers on\n first boot, causing silent package install failures\n- Do not use a users: block with password: — clou\n[…]\n Notes entry explaining that qemu-guest-agent is required for\nHarvester to display the guest IP for VMs on private VLAN networks.\n\nCloses #39\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Update workloads/vm README with correct cloud-init pattern",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e35b6ab0a867170a0cbb5fbbc5f7e1d7deac4ea3",
"body": "Individual range bounds (2–510) were already validated per-variable.\nAdd a check block to enforce start_offset <= end_offset, which cannot\nbe expressed in variable validation blocks without Terraform >= 1.9.\n\nUsing check block (Terraform >= 1.5, already required) keeps the\nrequired_version constraint unchanged.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add cross-variable DHCP offset order validation",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e536225e0d8786938b370d50dd3e3007b2880c22",
"body": "- bootstrap/vyos/main.tf: explicitly state the route_cidr as\n 10.0.0.0/8 in the eth1 trunk comment so it matches the resource\n- tenant-space/variables.tf: soften \"At minimum, provide one\n namespace named after the project\" to \"It is recommended\" to\n match the actual (non-enforced) behaviour\n- vyo\n[…]\nues for consumers\n- vyos-tenant/versions.tf: correct vyos-rolling version constraint\n from ~> 19.1 (non-existent) to ~> 19.0 (latest series)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address remaining CodeRabbit comments on PR #38",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d3de050aaaf68cbbc9f02da7f50eceafc4a9ef28",
"body": "- Remove unused rancher2 provider from versions.tf; the module\n only uses harvester and vyos providers\n- Add validation blocks to dhcp_range_start_offset and\n dhcp_range_end_offset: valid range 2–510, offset 1 is reserved\n for the gateway IP\n- Consolidate dhcp_dns into a single vyos_config_block_\n[…]\n is now a unique config key\n- Replace 0.0.0.0/0 in the API setup comment with\n <management_cidr> placeholder to avoid suggesting open access\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Address CodeRabbit review on vyos-tenant module",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7e98e3dc3759e6a10a01d4c01ace649b9b09f30a",
"body": "Replace DigiOps references and WSO2-specific defaults with generic\nterminology so the modules are usable by any Harvester operator.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Remove internal naming from VyOS module comments and variables",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0eebf94162268bece096b1ac127f5f199bafcac1",
"body": "Introduces two modules for deploying and configuring a VyOS VM as a\nprivate cloud gateway on Harvester, enabling per-tenant VLAN isolation,\nDHCP, NAT, and internet egress without DigiOps involvement per tenant.\n\nmodules/bootstrap/vyos/\n- Deploys VyOS VM with two NICs: eth0 (DigiOps uplink) and eth1 \n[…]\n NAT rules, and harvester_network resources\n- Creates harvester_network with vlan_id matching the VyOS vif tag exactly\n\nCloses #77\nCloses #78\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add VyOS multi-tenant gateway modules",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:36:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f6324ee06991f1f97db53d3a70277ea3527ebce4",
"body": "- Rename duplicate Phase 4 (Asgardeo Auth) to Phase 5 to resolve\n numbering conflict with the Workloads phase added in this PR\n- Update Provider Dependency Summary table: replace stale ~> 0.6.0 /\n ~> 3.0 / ~> 8.0.0 constraints with versions from actual module\n versions.tf files (harvester ~> 1.7,\n[…]\nasgardeo ~> 0.1)\n- Fix storage example source: update from wso2-enterprise org and\n stale v0.1.0 tag to wso2/open-cloud-datacenter at v0.5.8\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix CodeRabbit review comments on architecture docs",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:35:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "afd0a0fef5e62d2ce503cdceda18e52f9e108010",
"body": "…odules and fix broken references",
"is_bot": false,
"headline": "Update README and architecture documentation to include all missing m…",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T11:35:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "54757306ee37eb48c45418fbeca409654cb9d307",
"body": "Add three new role templates to the cluster-roles module to extend the\nDC platform RBAC framework:\n\nvm-creator (cluster): minimum cluster-level read access for tenants who\ncreate VMs — VM images, network attachment definitions, and SSH keypairs\nlive outside project namespaces so project-owner alone \n[…]\nnamed after the project, ensuring\nthe namespace dropdown is populated in the Rancher/Harvester VM and RKE2\ncluster creation flow.\n\nCloses #36\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add vm-creator, vm-operator, and cluster-operator role templates",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-10T08:02:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "06c962f3941acfd573e7ac0b4a18c1def5712a29",
"body": null,
"is_bot": false,
"headline": "Add optional scheduled backup support to vm module",
"author_name": "Akini Karunarathne",
"author_login": "Akini98",
"committed_at": "2026-04-09T09:32:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9440407a4bbbaf140629d3a17559a62318e8e94d",
"body": "…rs[0]\n\nFollow Kubernetes kubeconfig resolution semantics: parse current-context,\nfind the matching context, extract its cluster reference, then look up the\ncluster entry by name. This correctly handles multi-cluster kubeconfigs\nwhere the target cluster may not be the first entry.\n\nAlso add a check block validating that certificate-authority-data (embedded\nCA) is present, since file-path certificate-authority references are not\nsupported when building the portable SA kubeconfig for Rancher.",
"is_bot": false,
"headline": "fix: resolve kubeconfig cluster via current-context instead of cluste…",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-07T17:47:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cd4844bfd5d5ac9b62b828ac5536677346039fae",
"body": "The Harvester UI kubeconfig embeds a Rancher-internal token that\nstandalone Rancher cannot validate against the Harvester API,\ncausing 500 errors on cloud credential creation. Generate a\ndedicated Kubernetes ServiceAccount token instead so Harvester\ncan authenticate the credential directly.\n\nAlso ad\n[…]\ne management interface.\n\nAll new SA resources are gated on create_cloud_credential to\npreserve brownfield environments (lk prod).\n\nCloses #32\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix Harvester cloud credential and IP pool VLAN selector",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-07T17:47:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b60b4566c3fe08db6f39ef51d0cddc6848173f34",
"body": "- Use double quotes for chpasswd entry in cloud-init template so\n passwords containing single quotes do not break YAML parsing\n- Gate rancher2_secret_v2.registry_auth on manage_rke_config so\n secrets are not created for brownfield clusters that never reference\n them\n- Tighten registries validation: require non-empty hostname (unique,\n case-insensitive), enforce non-empty username/password when set, and\n enforce non-empty auth_config_secret_name when set",
"is_bot": false,
"headline": "Address CodeRabbit review comments on PR #31",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-07T17:22:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6bc5ec54e28f6f66d481f49ad1b593d32265c500",
"body": "regexreplace() is not available in all Terraform-compatible\nruntimes. replace() with /pattern/ regex delimiter achieves\nthe same result and has broader compatibility.",
"is_bot": false,
"headline": "Use replace() instead of regexreplace() for secret name",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-07T17:22:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c1d668dcd357568bdbbf520ba4d1de5d765cf581",
"body": "- Reflect current API (provider ~> 13.1, terraform >= 1.7)\n- Document all current inputs including machine_pools fields,\n registries (inline credentials vs brownfield secret), and etcd_s3\n- Add registry credential modes reference table and usage examples\n- Add outputs table and brownfield import instructions\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Update k8s-cluster module README",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-07T17:22:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5364817cbfe0650d0d13a4415625e1c1e41995f4",
"body": "- Quote password in chpasswd list to handle special characters\n- Replace ping connectivity check with curl — more reliable through\n firewalls that block ICMP\n- Redirect deployment echo messages to /dev/console so progress is\n visible in Harvester VM serial console during boot, not only in\n /var/log/rancher-install.log\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Improve cloud-init bootstrap script reliability",
"author_name": "HiranAdikari",
"author_login": "HiranAdikari",
"committed_at": "2026-04-07T17:22:34Z",
"body_truncated": false,
"is_coding_agent": true
}
],
"releases_count": 34,
"commits_last_year": 173,
"latest_release_at": "2026-07-24T04:47:13Z",
"latest_release_tag": "terraform/v0.1.9",
"releases_from_tags": false,
"days_since_last_push": 1,
"active_weeks_last_year": 16,
"days_since_latest_release": 4,
"mean_days_between_releases": 6.3
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 87,
"has_issue_template": true,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"ecosystem": {
"packages": []
},
"popularity": {
"forks": 12,
"stars": 7,
"watchers": 1,
"fork_history": {
"days": [
{
"date": "2026-02-25",
"count": 2
},
{
"date": "2026-03-03",
"count": 1
},
{
"date": "2026-03-31",
"count": 2
},
{
"date": "2026-04-22",
"count": 1
},
{
"date": "2026-05-13",
"count": 1
},
{
"date": "2026-05-28",
"count": 1
},
{
"date": "2026-06-02",
"count": 1
},
{
"date": "2026-06-10",
"count": 1
},
{
"date": "2026-06-11",
"count": 1
},
{
"date": "2026-06-12",
"count": 1
}
],
"complete": true,
"collected": 12,
"total_forks": 12
},
"star_history": null,
"open_issues_and_prs": 26
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [],
"largest_source_bytes": null,
"source_files_sampled": 0,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [],
"dependencies": [],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 5,
"merged_prs": 167,
"open_issues": 21,
"closed_ratio": 0.58,
"closed_issues": 29,
"closed_unmerged_prs": 10
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "HiranAdikari",
"commits": 109,
"avatar_url": "https://avatars.githubusercontent.com/u/13211597?v=4"
},
{
"type": "User",
"login": "VimukthiPerera",
"commits": 30,
"avatar_url": "https://avatars.githubusercontent.com/u/15902071?v=4"
},
{
"type": "User",
"login": "iamtrazy",
"commits": 12,
"avatar_url": "https://avatars.githubusercontent.com/u/73080739?v=4"
},
{
"type": "User",
"login": "sathindudezoysa",
"commits": 4,
"avatar_url": "https://avatars.githubusercontent.com/u/59018854?v=4"
},
{
"type": "User",
"login": "git-repo-creation-app",
"commits": 3,
"avatar_url": "https://avatars.githubusercontent.com/u/216828136?v=4"
},
{
"type": "User",
"login": "Akini98",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/116425440?v=4"
},
{
"type": "User",
"login": "gnudeep",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/155502?v=4"
}
],
"contributors_sampled": 7,
"top_contributor_share": 0.677
},
"quality_signals": {
"has_ci": true,
"has_tests": false,
"ci_workflows": [
"linter.yml",
"terraform-scan.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": null,
"reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 6,
"reason": "10 out of 15 merged PRs checked by a CI test -- score normalized to 6",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 10,
"reason": "all changesets reviewed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 10,
"reason": "all dependencies are pinned",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 10,
"reason": "GitHub workflow tokens follow principle of least privilege",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "25cb78eacee2ae426e3171b1113f24f1f46bb586",
"ran_at": "2026-07-28T10:08:20Z",
"aggregate_score": 6.7,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-27T04:59:02Z",
"oldest_open_prs": [
{
"number": 21,
"created_at": "2026-03-05T11:59:06Z",
"last_comment_at": "2026-03-05T11:59:21Z",
"last_comment_author": "coderabbitai"
},
{
"number": 150,
"created_at": "2026-06-11T04:57:42Z",
"last_comment_at": "2026-06-11T04:57:50Z",
"last_comment_author": "coderabbitai"
},
{
"number": 205,
"created_at": "2026-06-30T10:04:10Z",
"last_comment_at": "2026-06-30T10:04:35Z",
"last_comment_author": "coderabbitai"
},
{
"number": 215,
"created_at": "2026-07-03T06:26:47Z",
"last_comment_at": "2026-07-03T06:26:53Z",
"last_comment_author": "coderabbitai"
},
{
"number": 230,
"created_at": "2026-07-16T09:09:32Z",
"last_comment_at": "2026-07-16T09:09:41Z",
"last_comment_author": "coderabbitai"
}
],
"last_merged_pr_at": "2026-07-27T09:22:47Z",
"ci_last_conclusion": null,
"oldest_open_issues": [
{
"number": 34,
"created_at": "2026-04-07T17:29:12Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 58,
"created_at": "2026-04-17T11:38:31Z",
"last_comment_at": "2026-06-16T07:32:27Z",
"last_comment_author": "kavix"
},
{
"number": 59,
"created_at": "2026-04-17T12:14:17Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 85,
"created_at": "2026-05-04T06:58:09Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 86,
"created_at": "2026-05-04T06:58:10Z",
"last_comment_at": "2026-06-16T07:32:47Z",
"last_comment_author": "kavix"
},
{
"number": 87,
"created_at": "2026-05-04T06:58:14Z",
"last_comment_at": "2026-06-16T07:33:19Z",
"last_comment_author": "kavix"
},
{
"number": 92,
"created_at": "2026-05-05T17:17:27Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 109,
"created_at": "2026-05-28T06:53:48Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 120,
"created_at": "2026-05-29T09:43:06Z",
"last_comment_at": "2026-05-31T03:06:34Z",
"last_comment_author": "Akini98"
},
{
"number": 131,
"created_at": "2026-05-30T12:52:09Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 139,
"created_at": "2026-06-02T13:02:48Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 218,
"created_at": "2026-07-07T00:00:31Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 220,
"created_at": "2026-07-07T00:26:16Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 223,
"created_at": "2026-07-09T05:31:00Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 226,
"created_at": "2026-07-10T09:55:05Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 228,
"created_at": "2026-07-14T06:43:24Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 229,
"created_at": "2026-07-16T06:05:24Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 231,
"created_at": "2026-07-20T00:45:26Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 233,
"created_at": "2026-07-22T09:52:57Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 239,
"created_at": "2026-07-25T18:39:54Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/wso2/open-cloud-datacenter",
"host": "github.com",
"name": "open-cloud-datacenter",
"owner": "wso2"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 66,
"inputs": {
"security": 67,
"vitality": 85,
"community": 58,
"governance": 60,
"engineering": 58
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 85,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"commits_last_year": 173,
"human_commit_share": 1,
"days_since_last_push": 1,
"active_weeks_last_year": 16
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "16/52 weeks with commits",
"points": 11.1,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 16
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "173 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 173
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 34,
"latest_release_tag": "terraform/v0.1.9",
"releases_from_tags": false,
"days_since_latest_release": 4,
"mean_days_between_releases": 6.3
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "34 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 34
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 4 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 4
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~6.3 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 6.3
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 58,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 21,
"inputs": {
"forks": 12,
"stars": 7,
"watchers": 1,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "7 stars",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 7
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "12 forks",
"points": 8.7,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 12
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "1 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 1
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "excellent",
"name": "Community health",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"has_issue_template": true,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (Apache-2.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "Apache-2.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 13.5,
"status": "met",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 7.2,
"status": "met",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 60,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 29,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 7,
"top_contributor_share": 0.677
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 68% of commits",
"points": 7.3,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 68
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "7 contributors",
"points": 9.5,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 7
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 78,
"inputs": {
"merged_prs": 167,
"open_issues": 21,
"closed_issues": 29,
"issue_closed_ratio": 0.58,
"closed_unmerged_prs": 10
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "58% of issues closed",
"points": 27.1,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 58
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "167/177 decided PRs merged",
"points": 36.1,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 167,
"decided": 177
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "all changesets reviewed",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "good",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 78,
"inputs": {
"followers": 1731,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "wso2",
"public_repos": 383,
"account_age_days": 5697
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "1,731 followers of wso2",
"points": 23.3,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 1731,
"login": "wso2"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "383 public repos, account ~15 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 383
}
},
{
"code": "account_age_years",
"params": {
"years": 15
}
}
],
"max_points": 25
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 58,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "at_risk",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 36,
"inputs": {
"has_ci": true,
"has_tests": false,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "2 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 2
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "10 out of 15 merged PRs checked by a CI test -- score normalized to 6",
"points": 12,
"status": "partial",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"topics": [
"asgardeo",
"choreo"
],
"has_wiki": false,
"homepage": "https://github.com/wso2/open-cloud-datacenter",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://github.com/wso2/open-cloud-datacenter",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "2 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 2
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 67,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Branch-Protection, Packaging, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"branch_protection",
"packaging",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 67,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 15,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 3,
"scorecard_aggregate": 6.7
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "10 out of 15 merged PRs checked by a CI test -- score normalized to 6",
"points": 1.5,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "all changesets reviewed",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "all dependencies are pinned",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "GitHub workflow tokens follow principle of least privilege",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 4
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "critical",
"name": "AI Readiness",
"value": 26,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.88,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "88 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 88,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "critical",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 20,
"inputs": {
"has_nix": false,
"has_tests": false,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": false,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.68,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "68 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 68,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "all dependencies are pinned",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "critical",
"name": "Code legibility for models",
"note": "Excluded from scoring (no data or not applicable): Manageable file sizes. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"manageable_file_sizes"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 1,
"inputs": {
"primary_language": "HCL",
"largest_source_bytes": null,
"source_files_sampled": 0,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "HCL without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "HCL"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "no source files detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_source_files",
"params": {}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": false,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "examples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-28T10:08:39.159260Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/w/wso2/open-cloud-datacenter.svg",
"full_name": "wso2/open-cloud-datacenter",
"license_state": "standard",
"license_spdx": "Apache-2.0"
}