1use crate::cli_types::{OrchestratorResource, ResourceKind};
2use crate::config::OrchestratorConfig;
3use anyhow::{Result, anyhow};
4
5use super::{
6 AgentResource, EnvStoreResource, ExecutionProfileResource, ProjectResource,
7 RuntimePolicyResource, SecretStoreResource, StepTemplateResource, TriggerResource,
8 WorkflowResource, WorkspaceResource,
9};
10use super::{
11 ApplyResult, Resource, agent, env_store, execution_profile, project, runtime_policy,
12 secret_store, step_template, trigger, workflow, workspace,
13};
14
15#[derive(Debug, Clone)]
16pub enum RegisteredResource {
18 Workspace(WorkspaceResource),
20 Agent(Box<AgentResource>),
22 Workflow(WorkflowResource),
24 Project(ProjectResource),
26 RuntimePolicy(RuntimePolicyResource),
28 StepTemplate(StepTemplateResource),
30 ExecutionProfile(ExecutionProfileResource),
32 EnvStore(EnvStoreResource),
34 SecretStore(SecretStoreResource),
36 Trigger(TriggerResource),
38}
39
40#[derive(Debug, Clone, Copy)]
41pub struct ResourceRegistration {
43 pub kind: ResourceKind,
45 pub build: fn(OrchestratorResource) -> Result<RegisteredResource>,
47}
48
49pub fn resource_registry() -> [ResourceRegistration; 10] {
51 [
52 ResourceRegistration {
53 kind: ResourceKind::Workspace,
54 build: workspace::build_workspace,
55 },
56 ResourceRegistration {
57 kind: ResourceKind::Agent,
58 build: agent::build_agent,
59 },
60 ResourceRegistration {
61 kind: ResourceKind::Workflow,
62 build: workflow::build_workflow,
63 },
64 ResourceRegistration {
65 kind: ResourceKind::Project,
66 build: project::build_project,
67 },
68 ResourceRegistration {
69 kind: ResourceKind::RuntimePolicy,
70 build: runtime_policy::build_runtime_policy,
71 },
72 ResourceRegistration {
73 kind: ResourceKind::StepTemplate,
74 build: step_template::build_step_template,
75 },
76 ResourceRegistration {
77 kind: ResourceKind::ExecutionProfile,
78 build: execution_profile::build_execution_profile,
79 },
80 ResourceRegistration {
81 kind: ResourceKind::EnvStore,
82 build: env_store::build_env_store,
83 },
84 ResourceRegistration {
85 kind: ResourceKind::SecretStore,
86 build: secret_store::build_secret_store,
87 },
88 ResourceRegistration {
89 kind: ResourceKind::Trigger,
90 build: trigger::build_trigger,
91 },
92 ]
93}
94
95impl RegisteredResource {
96 pub fn metadata_project(&self) -> Option<&str> {
98 let meta = match self {
99 Self::Workspace(r) => &r.metadata,
100 Self::Agent(r) => &r.metadata,
101 Self::Workflow(r) => &r.metadata,
102 Self::Project(r) => &r.metadata,
103 Self::RuntimePolicy(r) => &r.metadata,
104 Self::StepTemplate(r) => &r.metadata,
105 Self::ExecutionProfile(r) => &r.metadata,
106 Self::EnvStore(r) => &r.metadata,
107 Self::SecretStore(r) => &r.metadata,
108 Self::Trigger(r) => &r.metadata,
109 };
110 meta.project.as_deref()
111 }
112}
113
114pub fn dispatch_resource(resource: OrchestratorResource) -> Result<RegisteredResource> {
116 let kind = resource.kind;
117 if let Some(registration) = resource_registry().iter().find(|entry| entry.kind == kind) {
118 return (registration.build)(resource);
119 }
120 Err(anyhow!("unsupported resource kind"))
121}
122
123impl Resource for RegisteredResource {
126 fn kind(&self) -> ResourceKind {
127 match self {
128 Self::Workspace(_) => ResourceKind::Workspace,
129 Self::Agent(_) => ResourceKind::Agent,
130 Self::Workflow(_) => ResourceKind::Workflow,
131 Self::Project(_) => ResourceKind::Project,
132 Self::RuntimePolicy(_) => ResourceKind::RuntimePolicy,
133 Self::StepTemplate(_) => ResourceKind::StepTemplate,
134 Self::ExecutionProfile(_) => ResourceKind::ExecutionProfile,
135 Self::EnvStore(_) => ResourceKind::EnvStore,
136 Self::SecretStore(_) => ResourceKind::SecretStore,
137 Self::Trigger(_) => ResourceKind::Trigger,
138 }
139 }
140
141 fn name(&self) -> &str {
142 match self {
143 Self::Workspace(resource) => &resource.metadata.name,
144 Self::Agent(resource) => &resource.metadata.name,
145 Self::Workflow(resource) => &resource.metadata.name,
146 Self::Project(resource) => &resource.metadata.name,
147 Self::RuntimePolicy(resource) => &resource.metadata.name,
148 Self::StepTemplate(resource) => &resource.metadata.name,
149 Self::ExecutionProfile(resource) => &resource.metadata.name,
150 Self::EnvStore(resource) => &resource.metadata.name,
151 Self::SecretStore(resource) => &resource.metadata.name,
152 Self::Trigger(resource) => &resource.metadata.name,
153 }
154 }
155
156 fn validate(&self) -> Result<()> {
157 match self {
158 Self::Workspace(resource) => resource.validate(),
159 Self::Agent(resource) => resource.validate(),
160 Self::Workflow(resource) => resource.validate(),
161 Self::Project(resource) => resource.validate(),
162 Self::RuntimePolicy(resource) => resource.validate(),
163 Self::StepTemplate(resource) => resource.validate(),
164 Self::ExecutionProfile(resource) => resource.validate(),
165 Self::EnvStore(resource) => resource.validate(),
166 Self::SecretStore(resource) => resource.validate(),
167 Self::Trigger(resource) => resource.validate(),
168 }
169 }
170
171 fn apply(&self, config: &mut OrchestratorConfig) -> Result<ApplyResult> {
172 match self {
173 Self::Workspace(resource) => resource.apply(config),
174 Self::Agent(resource) => resource.apply(config),
175 Self::Workflow(resource) => resource.apply(config),
176 Self::Project(resource) => resource.apply(config),
177 Self::RuntimePolicy(resource) => resource.apply(config),
178 Self::StepTemplate(resource) => resource.apply(config),
179 Self::ExecutionProfile(resource) => resource.apply(config),
180 Self::EnvStore(resource) => resource.apply(config),
181 Self::SecretStore(resource) => resource.apply(config),
182 Self::Trigger(resource) => resource.apply(config),
183 }
184 }
185
186 fn to_yaml(&self) -> Result<String> {
187 match self {
188 Self::Workspace(resource) => resource.to_yaml(),
189 Self::Agent(resource) => resource.to_yaml(),
190 Self::Workflow(resource) => resource.to_yaml(),
191 Self::Project(resource) => resource.to_yaml(),
192 Self::RuntimePolicy(resource) => resource.to_yaml(),
193 Self::StepTemplate(resource) => resource.to_yaml(),
194 Self::ExecutionProfile(resource) => resource.to_yaml(),
195 Self::EnvStore(resource) => resource.to_yaml(),
196 Self::SecretStore(resource) => resource.to_yaml(),
197 Self::Trigger(resource) => resource.to_yaml(),
198 }
199 }
200
201 fn get_from_project(
202 config: &OrchestratorConfig,
203 name: &str,
204 project_id: Option<&str>,
205 ) -> Option<Self> {
206 if let Some(workspace) = WorkspaceResource::get_from_project(config, name, project_id) {
207 return Some(Self::Workspace(workspace));
208 }
209 if let Some(agent) = AgentResource::get_from_project(config, name, project_id) {
210 return Some(Self::Agent(Box::new(agent)));
211 }
212 if let Some(workflow) = WorkflowResource::get_from_project(config, name, project_id) {
213 return Some(Self::Workflow(workflow));
214 }
215 if let Some(project) = ProjectResource::get_from_project(config, name, project_id) {
216 return Some(Self::Project(project));
217 }
218 if let Some(step_template) =
219 StepTemplateResource::get_from_project(config, name, project_id)
220 {
221 return Some(Self::StepTemplate(step_template));
222 }
223 if let Some(execution_profile) =
224 ExecutionProfileResource::get_from_project(config, name, project_id)
225 {
226 return Some(Self::ExecutionProfile(execution_profile));
227 }
228 if name == "runtime" {
229 if let Some(runtime_policy) =
230 RuntimePolicyResource::get_from_project(config, name, project_id)
231 {
232 return Some(Self::RuntimePolicy(runtime_policy));
233 }
234 }
235 if let Some(env_store) = EnvStoreResource::get_from_project(config, name, project_id) {
236 return Some(Self::EnvStore(env_store));
237 }
238 if let Some(secret_store) = SecretStoreResource::get_from_project(config, name, project_id)
239 {
240 return Some(Self::SecretStore(secret_store));
241 }
242 if let Some(trigger) = TriggerResource::get_from_project(config, name, project_id) {
243 return Some(Self::Trigger(trigger));
244 }
245 None
246 }
247
248 fn delete_from_project(
249 config: &mut OrchestratorConfig,
250 name: &str,
251 project_id: Option<&str>,
252 ) -> bool {
253 if WorkspaceResource::delete_from_project(config, name, project_id) {
255 return true;
256 }
257 if AgentResource::delete_from_project(config, name, project_id) {
258 return true;
259 }
260 if WorkflowResource::delete_from_project(config, name, project_id) {
261 return true;
262 }
263 if ProjectResource::delete_from_project(config, name, project_id) {
264 return true;
265 }
266 if StepTemplateResource::delete_from_project(config, name, project_id) {
267 return true;
268 }
269 if ExecutionProfileResource::delete_from_project(config, name, project_id) {
270 return true;
271 }
272 if EnvStoreResource::delete_from_project(config, name, project_id) {
273 return true;
274 }
275 if SecretStoreResource::delete_from_project(config, name, project_id) {
276 return true;
277 }
278 if TriggerResource::delete_from_project(config, name, project_id) {
279 return true;
280 }
281 false
282 }
283}