feat(root): wire ROOT 05-10/12/Capstone curriculum expansion
023_phase6b_curriculum.sql — additive on top of 022_course_content.sql: 13 new teaching modules (ROOT 08/09 move from PLANNED to PARTIAL; ROOT 05-07/10 gain a new front-door module sequenced ahead of the existing bare-lab bank; ROOT 12 gains an incident-response framing lesson + reflection; Capstone gains a readiness module). No existing row is deleted; a small number of existing rows have their sequence/ prerequisites updated so a new teaching module supersedes the bare-lab bank as the front door — never their scenario_id/activity_type/ completion_behavior, so no student's derived completion changes meaning. is_required (new module_activities column, defaults true — every Phase 6A activity unaffected) lets a module distinguish CORE teaching from GUIDED/INDEPENDENT-practice duplicates and ADVANCED/optional extras. course-progress.js's totals() now considers a module complete once every REQUIRED activity is done, not literally every activity — an incomplete optional one no longer blocks completion, though it still counts toward the displayed percentage. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
-- Phase 6B — curriculum authoring & coverage expansion. Additive on top of Phase 6A's
|
||||
-- 022_course_content.sql: new teaching modules for ROOT 05/06/07/08/09/10/12/Capstone, built
|
||||
-- from real, previously-unwired scenario content (see docs/ROOT_CURRICULUM_COVERAGE_MATRIX.md
|
||||
-- for the evidence and reasoning behind every placement). No existing row is deleted; a small
|
||||
-- number of existing rows have their `sequence`/`prerequisites` updated so a new teaching
|
||||
-- module sits in front of the bare-lab bank it supersedes as the "front door" — never their
|
||||
-- scenario_id/activity_type/completion_behavior, so no student's derived completion state
|
||||
-- changes meaning. See docs/COURSE_CONTENT_MODEL.md §"content revision" for what does and
|
||||
-- doesn't require this kind of change.
|
||||
|
||||
-- ── is_required: Phase 6B §18/§27's optional-vs-required distinction. Defaults true, so every
|
||||
-- Phase 6A activity is unaffected (required, as it always implicitly was) — this is additive,
|
||||
-- not a redefinition. An optional activity (independent-practice duplicates, advanced/CKS-exam-
|
||||
-- style extras — see docs/ROOT_CURRICULUM_COVERAGE_MATRIX.md's ADVANCED/INDEPENDENT
|
||||
-- classifications) still counts toward a module's percent_complete display but NOT toward
|
||||
-- whether the module is considered complete — see course-progress.js's totals().
|
||||
ALTER TABLE module_activities ADD COLUMN IF NOT EXISTS is_required BOOLEAN NOT NULL DEFAULT true;
|
||||
|
||||
-- ── Course status: ROOT 08/09 move from PLANNED to PARTIAL — real modules exist now ─────────
|
||||
UPDATE courses SET status = 'partial', updated_at = now() WHERE course_id IN ('root-08-kubernetes-storage-scheduling', 'root-09-kubernetes-security');
|
||||
|
||||
-- ── Resequencing: new teaching modules become the front door; existing bare-lab banks move
|
||||
-- behind them. Sequence/prerequisites only — activities inside the existing modules are
|
||||
-- untouched. ──────────────────────────────────────────────────────────────────────────────
|
||||
UPDATE course_modules SET sequence = 2, prerequisites = '{root-05-m00-kubernetes-mental-model}', version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-05-m01-pods-and-kubectl-basics';
|
||||
UPDATE course_modules SET sequence = 3, prerequisites = '{root-06-m02-deployments-scaling-updates}', version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-06-m01-deployments-and-workloads';
|
||||
UPDATE course_modules SET sequence = 3, prerequisites = '{root-07-m03-services-and-service-discovery}', version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-07-m01-services-and-networking';
|
||||
-- root-07-m02 (configuration bank) is intentionally left UNGATED (no new configuration-teaching
|
||||
-- module was authored this phase — an honest PARTIAL gap, see
|
||||
-- docs/ROOT_CURRICULUM_COVERAGE_MATRIX.md) but still needs to move behind the new
|
||||
-- teaching modules in display order, to avoid colliding with m04's sequence=2.
|
||||
UPDATE course_modules SET sequence = 4, version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-07-m02-configuration-and-secrets';
|
||||
UPDATE course_modules SET sequence = 3, prerequisites = '{root-10-m03-troubleshooting-framework}', version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-10-m02-general-troubleshooting';
|
||||
|
||||
INSERT INTO course_modules (module_id, course_id, title, description, sequence, objectives, prerequisites, estimated_duration_minutes, status) VALUES
|
||||
('root-05-m00-kubernetes-mental-model', 'root-05-kubernetes-foundations', 'The Kubernetes Mental Model & Core Objects',
|
||||
'What Kubernetes actually solves, the control-plane/worker/desired-state model, and Pods/Namespaces/labels through kubectl — the real front door to ROOT 05, taught before the bare kubectl-fluency lab bank.',
|
||||
1, '{"Explain what problem Kubernetes solves and why running containers by hand does not scale","Describe the control-plane/worker split and what \"desired state\" means in practice","Navigate Pods, Namespaces, and labels with kubectl confidently"}',
|
||||
'{}', 45, 'ready'),
|
||||
|
||||
('root-06-m02-deployments-scaling-updates', 'root-06-kubernetes-application-workloads', 'Deployments, Scaling & Updates',
|
||||
'Why Deployments/ReplicaSets exist, how a rolling update actually progresses, and how to reason about rollback — taught before the bare Deployments lab bank.',
|
||||
1, '{"Explain why a Deployment manages Pods instead of creating them directly","Perform and reason about a rolling update in progress","Explain what a rollback actually restores and when to use one"}',
|
||||
'{root-05-m00-kubernetes-mental-model}', 55, 'ready'),
|
||||
('root-06-m03-jobs-cronjobs-daemonsets', 'root-06-kubernetes-application-workloads', 'Jobs, CronJobs & DaemonSets',
|
||||
'Distinguishing one-shot Jobs, scheduled CronJobs, and per-node DaemonSets from long-running Deployments.',
|
||||
2, '{"Choose the right workload primitive for a one-shot task, a scheduled task, and a per-node agent","Explain why a Job differs from a Deployment in restart/completion semantics"}',
|
||||
'{root-06-m02-deployments-scaling-updates}', 30, 'partial'),
|
||||
|
||||
('root-07-m03-services-and-service-discovery', 'root-07-kubernetes-networking-config', 'Services & Service Discovery',
|
||||
'The Service/Endpoints/DNS request path and choosing the right Service type — taught before the bare Services lab bank.',
|
||||
1, '{"Trace how a request actually reaches a Pod through a Service","Choose ClusterIP vs NodePort correctly for a given requirement","Explain why a Service with zero endpoints looks like network failure from outside"}',
|
||||
'{root-06-m02-deployments-scaling-updates}', 45, 'ready'),
|
||||
('root-07-m04-ingress-networkpolicy-foundations', 'root-07-kubernetes-networking-config', 'Ingress & NetworkPolicy Foundations',
|
||||
'How Ingress routes external traffic, and what a NetworkPolicy architecturally does (the security posture comes later, in ROOT 09).',
|
||||
2, '{"Explain how Ingress differs from a Service and why it exists","Describe what a NetworkPolicy actually controls at the architectural level"}',
|
||||
'{root-07-m03-services-and-service-discovery}', 30, 'partial'),
|
||||
|
||||
('root-08-m01-storage-fundamentals', 'root-08-kubernetes-storage-scheduling', 'Storage Fundamentals',
|
||||
'Ephemeral vs. persistent storage, and how PersistentVolumes/PersistentVolumeClaims/StorageClasses fit together.',
|
||||
1, '{"Explain the difference between ephemeral and persistent storage in Kubernetes","Describe how a PVC binds to a PV, directly or via dynamic provisioning"}',
|
||||
'{root-07-m03-services-and-service-discovery}', 35, 'partial'),
|
||||
('root-08-m02-scheduling-resource-governance', 'root-08-kubernetes-storage-scheduling', 'Scheduling & Resource Governance',
|
||||
'How the scheduler places Pods, and how quotas/limits/priority/disruption budgets shape that placement.',
|
||||
2, '{"Explain how taints/tolerations and affinity influence scheduling decisions","Explain why a PodDisruptionBudget matters during a voluntary disruption","Describe what a ResourceQuota/LimitRange enforces at the namespace level"}',
|
||||
'{root-08-m01-storage-fundamentals}', 40, 'partial'),
|
||||
|
||||
('root-09-m01-security-model-and-securitycontext', 'root-09-kubernetes-security', 'Security Model & SecurityContext',
|
||||
'Defense in depth, least privilege, and hardening a Pod with SecurityContext (non-root, capabilities, read-only filesystem).',
|
||||
1, '{"Explain defense in depth and least privilege as applied to a running Pod","Configure a Pod/container SecurityContext to run non-root with a read-only filesystem and no unnecessary Linux capabilities"}',
|
||||
'{root-06-m02-deployments-scaling-updates}', 50, 'ready'),
|
||||
('root-09-m02-serviceaccounts-and-rbac', 'root-09-kubernetes-security', 'ServiceAccounts & RBAC',
|
||||
'Identity for workloads and least-privilege permissions via Roles/ClusterRoles.',
|
||||
2, '{"Explain why a Pod needs its own identity separate from the human operating it","Write a least-privilege Role/RoleBinding for a specific, narrow permission"}',
|
||||
'{root-09-m01-security-model-and-securitycontext}', 40, 'partial'),
|
||||
('root-09-m03-network-and-supplychain-security', 'root-09-kubernetes-security', 'Network & Supply Chain Security',
|
||||
'NetworkPolicy as a security control (not just an architecture concept), image/registry trust, and TLS ingress.',
|
||||
3, '{"Apply a default-deny NetworkPolicy and open only the access a workload actually needs","Explain why an image-pull secret and a trusted registry matter for supply-chain security"}',
|
||||
'{root-09-m02-serviceaccounts-and-rbac,root-07-m04-ingress-networkpolicy-foundations}', 40, 'partial'),
|
||||
('root-09-m04-cluster-hardening-and-runtime', 'root-09-kubernetes-security', 'Cluster Hardening & Runtime Security',
|
||||
'Pod Security Admission and a survey of cluster-hardening/runtime-sandboxing topics — deliberately advanced/optional, not daily-driver core.',
|
||||
4, '{"Explain what Pod Security Admission enforces at the namespace level and how it differs from the old PodSecurityPolicy"}',
|
||||
'{root-09-m03-network-and-supplychain-security}', 25, 'partial'),
|
||||
|
||||
('root-10-m03-troubleshooting-framework', 'root-10-kubernetes-troubleshooting-observability', 'The RootNode Troubleshooting Framework',
|
||||
'A repeatable framework — Observe, Gather Evidence, Form Hypothesis, Test, Repair, Validate, Prevent Recurrence — applied to a CrashLoopBackOff and a broken Service.',
|
||||
2, '{"Apply a repeatable troubleshooting framework instead of guessing under pressure","Diagnose a CrashLoopBackOff from evidence, not assumption","Diagnose a broken Service-to-Pod selector mismatch"}',
|
||||
'{root-10-m01-health-probes-and-troubleshooting}', 40, 'partial'),
|
||||
|
||||
('root-capstone-m02-capstone-readiness', 'root-capstone', 'Capstone Readiness',
|
||||
'What the RootNode Capstone measures, what it requires, how the timed/randomized draw works, and how to manage your time — without publishing the draw or the answers.',
|
||||
1, '{"Explain what skills the RootNode Capstone measures and why","Describe how the timed, partially-randomized scenario draw works","Apply the RootNode troubleshooting framework under time pressure"}',
|
||||
'{}', 20, 'ready')
|
||||
ON CONFLICT (module_id) DO NOTHING;
|
||||
|
||||
-- The existing capstone assessment module keeps its original sequence position (2) relative to
|
||||
-- the new readiness module (1) — readiness comes first, matching that it now needs no
|
||||
-- prerequisite of its own (the course-level root-12-real-ops -> root-capstone chain still
|
||||
-- gates entry into this course at all; the actual capstone START is gated server-side by
|
||||
-- curriculum-rules.js's unlock_rule regardless of whether this readiness module was viewed —
|
||||
-- see docs/ROOT_CAPSTONE_READINESS.md for why those two gates are deliberately independent).
|
||||
UPDATE course_modules SET sequence = 2 WHERE module_id = 'root-capstone-m01-operate-and-recover';
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
-- New module_activities — gold-standard modules (lesson+demo+knowledge_check+guided_exercise+
|
||||
-- lab+reflection) for root-05-m00, root-06-m02, root-07-m03, root-09-m01. PARTIAL modules get
|
||||
-- lesson+knowledge_check(+lab) only, honestly, per docs/ROOT_CURRICULUM_COVERAGE_MATRIX.md.
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
-- ROOT 05 m00 — 6 activities
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-05-m00-a01-lesson-mental-model', 'root-05-m00-kubernetes-mental-model', 1, 'lesson', 'What Kubernetes Solves & the Desired-State Model',
|
||||
'content/root/root-05-kubernetes-foundations/m00-mental-model/01-lesson-mental-model.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-05-m00-a02-demonstration-desired-state', 'root-05-m00-kubernetes-mental-model', 2, 'demonstration', 'Demonstration: Desired State Reconciliation',
|
||||
'content/root/root-05-kubernetes-foundations/m00-mental-model/02-demonstration-desired-state.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-05-m00-a03-knowledge-check', 'root-05-m00-kubernetes-mental-model', 3, 'knowledge_check', 'Knowledge Check: The Kubernetes Mental Model',
|
||||
'content/root/root-05-kubernetes-foundations/m00-mental-model/03-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-05-m00-a04-guided-exercise-namespaces', 'root-05-m00-kubernetes-mental-model', 4, 'guided_exercise', 'Guided Exercise: Planning a Namespace Layout',
|
||||
'content/root/root-05-kubernetes-foundations/m00-mental-model/04-guided-exercise-namespaces.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-05-m00-a05-lab-namespaces-basics', 'root-05-m00-kubernetes-mental-model', 5, 'lab', 'Launch Lab: Working with Namespaces',
|
||||
'content/root/root-05-kubernetes-foundations/m00-mental-model/05-lab-intro.md', 'namespaces-basics', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-05-m00-a06-reflection', 'root-05-m00-kubernetes-mental-model', 6, 'reflection', 'Reflection: Why Desired State Matters in Production',
|
||||
'content/root/root-05-kubernetes-foundations/m00-mental-model/06-reflection.md', NULL, NULL, 'manual_marker', 10, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 06 m02 — 6 activities
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-06-m02-a01-lesson-deployments', 'root-06-m02-deployments-scaling-updates', 1, 'lesson', 'Why Deployments Exist & How a Rolling Update Progresses',
|
||||
'content/root/root-06-kubernetes-application-workloads/m02-deployments-scaling-updates/01-lesson-deployments.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-06-m02-a02-demonstration-rollout', 'root-06-m02-deployments-scaling-updates', 2, 'demonstration', 'Demonstration: Watching a Rollout, Good and Bad',
|
||||
'content/root/root-06-kubernetes-application-workloads/m02-deployments-scaling-updates/02-demonstration-rollout.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-06-m02-a03-knowledge-check', 'root-06-m02-deployments-scaling-updates', 3, 'knowledge_check', 'Knowledge Check: Deployments & Rollouts',
|
||||
'content/root/root-06-kubernetes-application-workloads/m02-deployments-scaling-updates/03-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-06-m02-a04-guided-exercise-rollout-strategy', 'root-06-m02-deployments-scaling-updates', 4, 'guided_exercise', 'Guided Exercise: Planning a Safe Rollout Strategy',
|
||||
'content/root/root-06-kubernetes-application-workloads/m02-deployments-scaling-updates/04-guided-exercise-rollout-strategy.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-06-m02-a05-lab-rolling-update', 'root-06-m02-deployments-scaling-updates', 5, 'lab', 'Launch Lab: Perform a Rolling Update',
|
||||
'content/root/root-06-kubernetes-application-workloads/m02-deployments-scaling-updates/05-lab-intro.md', 'rolling-update-task', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-06-m02-a05b-lab-deployment-rollback', 'root-06-m02-deployments-scaling-updates', 6, 'lab', 'Lab: Rolling Back a Deployment', NULL, 'deployment-rollback', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-06-m02-a06-reflection', 'root-06-m02-deployments-scaling-updates', 7, 'reflection', 'Reflection: Rollback Is a Plan, Not a Panic Button',
|
||||
'content/root/root-06-kubernetes-application-workloads/m02-deployments-scaling-updates/06-reflection.md', NULL, NULL, 'manual_marker', 10, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 06 m03 — 4 activities (PARTIAL: lesson + knowledge_check + two labs)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-06-m03-a01-lesson-jobs-cronjobs-daemonsets', 'root-06-m03-jobs-cronjobs-daemonsets', 1, 'lesson', 'Jobs, CronJobs, and DaemonSets: The Other Workload Shapes',
|
||||
'content/root/root-06-kubernetes-application-workloads/m03-jobs-cronjobs-daemonsets/01-lesson-jobs-cronjobs-daemonsets.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-06-m03-a02-knowledge-check', 'root-06-m03-jobs-cronjobs-daemonsets', 2, 'knowledge_check', 'Knowledge Check: Choosing the Right Workload Primitive',
|
||||
'content/root/root-06-kubernetes-application-workloads/m03-jobs-cronjobs-daemonsets/02-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-06-m03-a03-lab-job-task', 'root-06-m03-jobs-cronjobs-daemonsets', 3, 'lab', 'Lab: Create a One-Shot Job', NULL, 'job-task', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-06-m03-a04-lab-cronjob-task', 'root-06-m03-jobs-cronjobs-daemonsets', 4, 'lab', 'Lab: Create a CronJob', NULL, 'cronjob-task', NULL, 'auto_scenario', 15, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 07 m03 — 6 activities
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-07-m03-a01-lesson-services', 'root-07-m03-services-and-service-discovery', 1, 'lesson', 'The Service/Endpoints/DNS Request Path',
|
||||
'content/root/root-07-kubernetes-networking-config/m03-services-and-service-discovery/01-lesson-services.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-07-m03-a02-demonstration-zero-endpoints', 'root-07-m03-services-and-service-discovery', 2, 'demonstration', 'Demonstration: A Service With Zero Endpoints',
|
||||
'content/root/root-07-kubernetes-networking-config/m03-services-and-service-discovery/02-demonstration-zero-endpoints.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-07-m03-a03-knowledge-check', 'root-07-m03-services-and-service-discovery', 3, 'knowledge_check', 'Knowledge Check: Services & Service Discovery',
|
||||
'content/root/root-07-kubernetes-networking-config/m03-services-and-service-discovery/03-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-07-m03-a04-guided-exercise-service-type', 'root-07-m03-services-and-service-discovery', 4, 'guided_exercise', 'Guided Exercise: Choosing the Right Service Type',
|
||||
'content/root/root-07-kubernetes-networking-config/m03-services-and-service-discovery/04-guided-exercise-service-type.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-07-m03-a05-lab-expose-service', 'root-07-m03-services-and-service-discovery', 5, 'lab', 'Launch Lab: Exposing an Application',
|
||||
'content/root/root-07-kubernetes-networking-config/m03-services-and-service-discovery/05-lab-intro.md', 'expose-service-basics', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-07-m03-a06-reflection', 'root-07-m03-services-and-service-discovery', 6, 'reflection', 'Reflection: Service Discovery Is Infrastructure, Not Magic',
|
||||
'content/root/root-07-kubernetes-networking-config/m03-services-and-service-discovery/06-reflection.md', NULL, NULL, 'manual_marker', 10, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 07 m01 (existing bare bank) — extend with the two newly-wired networking scenarios
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-07-m01-a03-nodeport-task', 'root-07-m01-services-and-networking', 3, 'lab', 'Lab: Expose a Deployment via NodePort', NULL, 'nodeport-task', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-07-m01-a04-dns-resolution-mcq', 'root-07-m01-services-and-networking', 4, 'lab', 'Lab: Kubernetes DNS Resolution', NULL, 'dns-resolution-mcq', NULL, 'auto_scenario', 15, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 07 m04 — 4 activities (PARTIAL)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-07-m04-a01-lesson-ingress-networkpolicy', 'root-07-m04-ingress-networkpolicy-foundations', 1, 'lesson', 'Ingress and NetworkPolicy: What They Architecturally Do',
|
||||
'content/root/root-07-kubernetes-networking-config/m04-ingress-networkpolicy-foundations/01-lesson-ingress-networkpolicy.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-07-m04-a02-knowledge-check', 'root-07-m04-ingress-networkpolicy-foundations', 2, 'knowledge_check', 'Knowledge Check: Ingress & NetworkPolicy Foundations',
|
||||
'content/root/root-07-kubernetes-networking-config/m04-ingress-networkpolicy-foundations/02-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-07-m04-a03-lab-ingress-task', 'root-07-m04-ingress-networkpolicy-foundations', 3, 'lab', 'Lab: Create an Ingress Resource', NULL, 'ingress-task', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-07-m04-a04-lab-network-policy', 'root-07-m04-ingress-networkpolicy-foundations', 4, 'lab', 'Lab: Isolate Traffic with NetworkPolicy', NULL, 'network-policy', NULL, 'auto_scenario', 30, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 08 m01 — 4 activities (PARTIAL)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-08-m01-a01-lesson-storage-fundamentals', 'root-08-m01-storage-fundamentals', 1, 'lesson', 'Ephemeral vs. Persistent Storage',
|
||||
'content/root/root-08-kubernetes-storage-scheduling/m01-storage-fundamentals/01-lesson-storage-fundamentals.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-08-m01-a02-knowledge-check', 'root-08-m01-storage-fundamentals', 2, 'knowledge_check', 'Knowledge Check: Storage Fundamentals',
|
||||
'content/root/root-08-kubernetes-storage-scheduling/m01-storage-fundamentals/02-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-08-m01-a03-lab-emptydir', 'root-08-m01-storage-fundamentals', 3, 'lab', 'Lab: Shared emptyDir Volume Between Containers', NULL, 'emptydir-pod', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-08-m01-a04-lab-pv-pvc', 'root-08-m01-storage-fundamentals', 4, 'lab', 'Lab: Persistent Storage with PV and PVC', NULL, 'pv-pvc-mount', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m01-a05-lab-pvc-dynamic', 'root-08-m01-storage-fundamentals', 5, 'lab', 'Lab: Dynamic PVC Provisioning', NULL, 'pvc-dynamic-task', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m01-a06-lab-storageclass', 'root-08-m01-storage-fundamentals', 6, 'lab', 'Lab: StorageClass Reclaim Policies', NULL, 'storageclass-mcq', NULL, 'auto_scenario', 15, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 08 m02 — 8 activities (PARTIAL)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-08-m02-a01-lesson-scheduling', 'root-08-m02-scheduling-resource-governance', 1, 'lesson', 'How the Scheduler Places Pods, and How Governance Shapes It',
|
||||
'content/root/root-08-kubernetes-storage-scheduling/m02-scheduling-resource-governance/01-lesson-scheduling.md', NULL, NULL, 'manual_marker', 20, 'ready'),
|
||||
('root-08-m02-a02-knowledge-check', 'root-08-m02-scheduling-resource-governance', 2, 'knowledge_check', 'Knowledge Check: Scheduling & Resource Governance',
|
||||
'content/root/root-08-kubernetes-storage-scheduling/m02-scheduling-resource-governance/02-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-08-m02-a03-lab-node-label-selector', 'root-08-m02-scheduling-resource-governance', 3, 'lab', 'Lab: Node Labels and nodeSelector', NULL, 'node-label-selector', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-08-m02-a04-lab-node-taint-toleration', 'root-08-m02-scheduling-resource-governance', 4, 'lab', 'Lab: Taints and Tolerations', NULL, 'node-taint-toleration', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m02-a05-lab-pod-affinity', 'root-08-m02-scheduling-resource-governance', 5, 'lab', 'Lab: Pod Affinity vs Anti-Affinity', NULL, 'pod-affinity-mcq', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m02-a06-lab-priority-class', 'root-08-m02-scheduling-resource-governance', 6, 'lab', 'Lab: Pod Priority and PriorityClass', NULL, 'priority-class-task', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m02-a07-lab-pdb', 'root-08-m02-scheduling-resource-governance', 7, 'lab', 'Lab: Configure a PodDisruptionBudget', NULL, 'pod-disruption-budget-task', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m02-a08-lab-resource-quota', 'root-08-m02-scheduling-resource-governance', 8, 'lab', 'Lab: ResourceQuota for a Namespace', NULL, 'resource-quota-ns', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-08-m02-a09-lab-limitrange', 'root-08-m02-scheduling-resource-governance', 9, 'lab', 'Lab: LimitRange for Default Container Limits', NULL, 'limitrange-task', NULL, 'auto_scenario', 20, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 09 m01 — 8 activities (READY: full gold-standard sequence + independent/guided/advanced practice)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-09-m01-a01-lesson-security-model', 'root-09-m01-security-model-and-securitycontext', 1, 'lesson', 'Defense in Depth & the Kubernetes Security Model',
|
||||
'content/root/root-09-kubernetes-security/m01-security-model-and-securitycontext/01-lesson-security-model.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-09-m01-a02-demonstration-securitycontext', 'root-09-m01-security-model-and-securitycontext', 2, 'demonstration', 'Demonstration: A Pod Before and After Hardening',
|
||||
'content/root/root-09-kubernetes-security/m01-security-model-and-securitycontext/02-demonstration-securitycontext.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-09-m01-a03-knowledge-check', 'root-09-m01-security-model-and-securitycontext', 3, 'knowledge_check', 'Knowledge Check: Security Model & SecurityContext',
|
||||
'content/root/root-09-kubernetes-security/m01-security-model-and-securitycontext/03-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-09-m01-a04-guided-exercise-hardening-plan', 'root-09-m01-security-model-and-securitycontext', 4, 'guided_exercise', 'Guided Exercise: Planning a Pod Hardening Checklist',
|
||||
'content/root/root-09-kubernetes-security/m01-security-model-and-securitycontext/04-guided-exercise-hardening-plan.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-09-m01-a05-lab-non-root', 'root-09-m01-security-model-and-securitycontext', 5, 'lab', 'Lab: Enforce Non-Root Container', NULL, 'cks-non-root-enforce', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m01-a06-lab-drop-capabilities', 'root-09-m01-security-model-and-securitycontext', 6, 'lab', 'Lab: Drop Linux Capabilities', NULL, 'cks-drop-capabilities', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m01-a07-lab-readonly-filesystem', 'root-09-m01-security-model-and-securitycontext', 7, 'lab', 'Lab: Read-Only Root Filesystem', NULL, 'cks-readonly-filesystem', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-09-m01-a08-lab-pod-security-context', 'root-09-m01-security-model-and-securitycontext', 8, 'lab', 'Lab: Pod Security Context (CKS)', NULL, 'cks-pod-security-context', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m01-a09-reflection', 'root-09-m01-security-model-and-securitycontext', 9, 'reflection', 'Reflection: Least Privilege Is a Default, Not an Afterthought',
|
||||
'content/root/root-09-kubernetes-security/m01-security-model-and-securitycontext/09-reflection.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-09-m01-a10-lab-seccomp-guided', 'root-09-m01-security-model-and-securitycontext', 10, 'lab', 'Lab: Seccomp Profiles (guided practice)', NULL, 'cks-seccomp-profile', NULL, 'auto_scenario', 30, 'ready'),
|
||||
('root-09-m01-a11-lab-apparmor-advanced', 'root-09-m01-security-model-and-securitycontext', 11, 'lab', 'Lab: AppArmor Profiles (advanced/optional)', NULL, 'cks-apparmor-profile', NULL, 'auto_scenario', 30, 'ready'),
|
||||
('root-09-m01-a12-lab-pod-security-context-independent', 'root-09-m01-security-model-and-securitycontext', 12, 'lab', 'Lab: Pod Security Context (independent practice)', NULL, 'pod-security-context', NULL, 'auto_scenario', 20, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 09 m02 — 6 activities (PARTIAL: lesson + KC + core labs + one independent-practice dup)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-09-m02-a01-lesson-serviceaccounts-rbac', 'root-09-m02-serviceaccounts-and-rbac', 1, 'lesson', 'Identity for Workloads: ServiceAccounts & RBAC',
|
||||
'content/root/root-09-kubernetes-security/m02-serviceaccounts-and-rbac/01-lesson-serviceaccounts-rbac.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-09-m02-a02-knowledge-check', 'root-09-m02-serviceaccounts-and-rbac', 2, 'knowledge_check', 'Knowledge Check: ServiceAccounts & RBAC',
|
||||
'content/root/root-09-kubernetes-security/m02-serviceaccounts-and-rbac/02-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-09-m02-a03-lab-serviceaccount-pod', 'root-09-m02-serviceaccounts-and-rbac', 3, 'lab', 'Lab: ServiceAccount for Pod API Access', NULL, 'serviceaccount-pod', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m02-a04-lab-automount-token', 'root-09-m02-serviceaccounts-and-rbac', 4, 'lab', 'Lab: Disable ServiceAccount Token', NULL, 'cks-automount-token', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-09-m02-a05-lab-rbac-role', 'root-09-m02-serviceaccounts-and-rbac', 5, 'lab', 'Lab: RBAC — Create Role and RoleBinding', NULL, 'rbac-role', NULL, 'auto_scenario', 30, 'ready'),
|
||||
('root-09-m02-a06-lab-rbac-clusterrole', 'root-09-m02-serviceaccounts-and-rbac', 6, 'lab', 'Lab: Cluster-Level RBAC (CKS)', NULL, 'cks-rbac-clusterrole', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m02-a07-lab-rbac-least-privilege', 'root-09-m02-serviceaccounts-and-rbac', 7, 'lab', 'Lab: RBAC Least Privilege', NULL, 'cks-rbac-least-privilege', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m02-a08-lab-rbac-clusterrole-independent', 'root-09-m02-serviceaccounts-and-rbac', 8, 'lab', 'Lab: ClusterRole and ClusterRoleBinding (independent practice)', NULL, 'rbac-clusterrole', NULL, 'auto_scenario', 20, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 09 m03 — 6 activities (PARTIAL)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-09-m03-a01-lesson-network-supplychain', 'root-09-m03-network-and-supplychain-security', 1, 'lesson', 'NetworkPolicy as a Security Control & Supply Chain Trust',
|
||||
'content/root/root-09-kubernetes-security/m03-network-and-supplychain-security/01-lesson-network-supplychain.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-09-m03-a02-knowledge-check', 'root-09-m03-network-and-supplychain-security', 2, 'knowledge_check', 'Knowledge Check: Network & Supply Chain Security',
|
||||
'content/root/root-09-kubernetes-security/m03-network-and-supplychain-security/02-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-09-m03-a03-lab-default-deny', 'root-09-m03-network-and-supplychain-security', 3, 'lab', 'Lab: Default Deny Network Policy', NULL, 'cks-network-policy', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m03-a04-lab-egress-namespace', 'root-09-m03-network-and-supplychain-security', 4, 'lab', 'Lab: Restrict Egress to Namespace', NULL, 'cks-egress-namespace', NULL, 'auto_scenario', 30, 'ready'),
|
||||
('root-09-m03-a05-lab-egress-networkpolicy-guided', 'root-09-m03-network-and-supplychain-security', 5, 'lab', 'Lab: Egress NetworkPolicy (guided practice)', NULL, 'networkpolicy-egress', NULL, 'auto_scenario', 30, 'ready'),
|
||||
('root-09-m03-a06-lab-tls-ingress', 'root-09-m03-network-and-supplychain-security', 6, 'lab', 'Lab: Secure Ingress with TLS', NULL, 'cks-tls-ingress', NULL, 'auto_scenario', 30, 'ready'),
|
||||
('root-09-m03-a07-lab-image-pull-secret', 'root-09-m03-network-and-supplychain-security', 7, 'lab', 'Lab: Private Registry Image Pull Secret', NULL, 'cks-image-pull-secret', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-09-m03-a08-lab-network-policy-metadata-advanced', 'root-09-m03-network-and-supplychain-security', 8, 'lab', 'Lab: Block Cloud Metadata (advanced/optional)', NULL, 'cks-network-policy-metadata', NULL, 'auto_scenario', 30, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 09 m04 — 4 activities (PARTIAL: survey-level, deliberately lighter)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-09-m04-a01-lesson-cluster-hardening', 'root-09-m04-cluster-hardening-and-runtime', 1, 'lesson', 'Pod Security Admission & a Survey of Runtime Hardening',
|
||||
'content/root/root-09-kubernetes-security/m04-cluster-hardening-and-runtime/01-lesson-cluster-hardening.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-09-m04-a02-lab-psa-namespace', 'root-09-m04-cluster-hardening-and-runtime', 2, 'lab', 'Lab: Pod Security Admission', NULL, 'cks-psa-namespace', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-09-m04-a03-lab-immutable-secret', 'root-09-m04-cluster-hardening-and-runtime', 3, 'lab', 'Lab: Immutable Secrets', NULL, 'cks-immutable-secret', NULL, 'auto_scenario', 15, 'ready'),
|
||||
('root-09-m04-a04-lab-runtime-class-advanced', 'root-09-m04-cluster-hardening-and-runtime', 4, 'lab', 'Lab: RuntimeClass for Sandboxed Workloads (advanced/optional)', NULL, 'cks-runtime-class', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-09-m04-a05-lab-audit-policy-advanced', 'root-09-m04-cluster-hardening-and-runtime', 5, 'lab', 'Lab: Write a Kubernetes Audit Policy (advanced/optional)', NULL, 'cks-audit-policy', NULL, 'auto_scenario', 30, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 10 m03 — 5 activities (PARTIAL: lesson + demo + KC + two labs)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-10-m03-a01-lesson-framework', 'root-10-m03-troubleshooting-framework', 1, 'lesson', 'The RootNode Troubleshooting Framework',
|
||||
'content/root/root-10-kubernetes-troubleshooting-observability/m03-troubleshooting-framework/01-lesson-framework.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-10-m03-a02-demonstration-crashloop', 'root-10-m03-troubleshooting-framework', 2, 'demonstration', 'Demonstration: Applying the Framework to a CrashLoopBackOff',
|
||||
'content/root/root-10-kubernetes-troubleshooting-observability/m03-troubleshooting-framework/02-demonstration-crashloop.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-10-m03-a03-knowledge-check', 'root-10-m03-troubleshooting-framework', 3, 'knowledge_check', 'Knowledge Check: The Troubleshooting Framework',
|
||||
'content/root/root-10-kubernetes-troubleshooting-observability/m03-troubleshooting-framework/03-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-10-m03-a04-lab-crashloop-fix', 'root-10-m03-troubleshooting-framework', 4, 'lab', 'Lab: Fix a CrashLoopBackOff Pod', NULL, 'crashloop-fix', NULL, 'auto_scenario', 20, 'ready'),
|
||||
('root-10-m03-a05-lab-endpoint-fix', 'root-10-m03-troubleshooting-framework', 5, 'lab', 'Lab: Fix a Broken Service Selector', NULL, 'endpoint-fix-task', NULL, 'auto_scenario', 20, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 10 m02 (existing bare bank) — extend with the newly-wired logging/monitoring MCQ
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-10-m02-a06-container-logging-mcq', 'root-10-m02-general-troubleshooting', 6, 'lab', 'Lab: Container Logging and Monitoring', NULL, 'container-logging-mcq', NULL, 'auto_scenario', 15, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ROOT 12 m01 — a new framework lesson at the FRONT (existing 4 lab activities renumbered
|
||||
-- +1 to make room; their scenario_id/activity_type/completion_behavior are untouched, so no
|
||||
-- student's derived completion changes meaning) plus a closing reflection.
|
||||
UPDATE module_activities SET sequence = sequence + 1, version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-12-m01-real-ops-incidents';
|
||||
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-12-m01-a00-lesson-incident-response', 'root-12-m01-real-ops-incidents', 1, 'lesson', 'The RootNode Incident-Response Framework',
|
||||
'content/root/root-12-real-ops/m01-real-ops-incidents/00-lesson-incident-response.md', NULL, NULL, 'manual_marker', 15, 'ready'),
|
||||
('root-12-m01-a99-reflection-post-incident', 'root-12-m01-real-ops-incidents', 6, 'reflection', 'Post-Incident Reflection: What Real Ops Actually Feels Like',
|
||||
'content/root/root-12-real-ops/m01-real-ops-incidents/99-reflection-post-incident.md', NULL, NULL, 'manual_marker', 10, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- Capstone Readiness — 4 activities (READY: informational/orientation, not a lesson-heavy module)
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-capstone-m02-a01-lesson-what-it-measures', 'root-capstone-m02-capstone-readiness', 1, 'lesson', 'What the Capstone Measures & How the Draw Works',
|
||||
'content/root/root-capstone/m02-capstone-readiness/01-lesson-what-it-measures.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-capstone-m02-a02-lesson-time-management', 'root-capstone-m02-capstone-readiness', 2, 'lesson', 'Time Management & Troubleshooting Strategy Under a Clock',
|
||||
'content/root/root-capstone/m02-capstone-readiness/02-lesson-time-management.md', NULL, NULL, 'manual_marker', 10, 'ready'),
|
||||
('root-capstone-m02-a03-knowledge-check', 'root-capstone-m02-capstone-readiness', 3, 'knowledge_check', 'Readiness Check: Are You Actually Ready?',
|
||||
'content/root/root-capstone/m02-capstone-readiness/03-knowledge-check.md', NULL, NULL, 'manual_marker', 5, 'ready'),
|
||||
('root-capstone-m02-a04-reflection-readiness', 'root-capstone-m02-capstone-readiness', 4, 'reflection', 'Readiness Reflection: What Completion Means',
|
||||
'content/root/root-capstone/m02-capstone-readiness/04-reflection-readiness.md', NULL, NULL, 'manual_marker', 5, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
-- ── Optional activities: guided/independent-practice duplicates and advanced/CKS-exam-style
|
||||
-- extras (docs/ROOT_CURRICULUM_COVERAGE_MATRIX.md's GUIDED/INDEPENDENT/ADVANCED
|
||||
-- classifications) count toward a module's displayed progress but not toward whether the
|
||||
-- module itself is considered complete — see course-progress.js's totals(). Everything not
|
||||
-- listed here stays required (the column's default), including every Phase 6A activity.
|
||||
UPDATE module_activities SET is_required = false, version = version + 1, updated_at = now() WHERE activity_id IN (
|
||||
'root-09-m01-a10-lab-seccomp-guided',
|
||||
'root-09-m01-a11-lab-apparmor-advanced',
|
||||
'root-09-m01-a12-lab-pod-security-context-independent',
|
||||
'root-09-m02-a08-lab-rbac-clusterrole-independent',
|
||||
'root-09-m03-a05-lab-egress-networkpolicy-guided',
|
||||
'root-09-m03-a08-lab-network-policy-metadata-advanced',
|
||||
'root-09-m04-a04-lab-runtime-class-advanced',
|
||||
'root-09-m04-a05-lab-audit-policy-advanced'
|
||||
);
|
||||
Reference in New Issue
Block a user