Skip to content

Commit 28241a1

Browse files
committed
agent-permissions: cli integration
1 parent d8cf103 commit 28241a1

46 files changed

Lines changed: 4116 additions & 317 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cli/golem-cli/src/command_handler/component/mod.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::model::app_raw;
3131
use crate::model::component::{
3232
AgentTypeManifestProvisionConfig, ComponentDeployProperties, ComponentNameMatchKind,
3333
ComponentRevisionSelection, ComponentView, SelectedComponents,
34+
initial_permission_from_manifest_card, initial_permission_recipient_context,
3435
};
3536
use crate::model::config::{collect_unused_leaf_paths, value_at_path};
3637
use crate::model::deploy::{
@@ -879,6 +880,16 @@ impl ComponentCommandHandler {
879880
&agent_type.type_name,
880881
materialize_agent_config_entries(agent_type, resolved_agent.config()),
881882
)?,
883+
initial_card: resolved_agent
884+
.initial_card()
885+
.map(initial_permission_from_manifest_card)
886+
.transpose()
887+
.with_context(|| {
888+
format!(
889+
"Invalid initialCard for component {} and agent {}",
890+
component_name.0, agent_type.type_name.0
891+
)
892+
})?,
882893
files_source: component.source().to_path_buf(),
883894
files: resolved_agent.files().to_vec(),
884895
plugins: resolve_plugin_parameters(component_name, resolved_agent.plugins())?,
@@ -1047,6 +1058,20 @@ impl ComponentCommandHandler {
10471058
config,
10481059
files_by_path,
10491060
plugins_by_grant_id,
1061+
initial_permission: {
1062+
let context = initial_permission_recipient_context(
1063+
environment,
1064+
component_name,
1065+
agent_type_name,
1066+
);
1067+
let initial_permission = manifest_config.to_initial_permission(&context);
1068+
diff::AgentTypeInitialPermission {
1069+
lower_positive: initial_permission.lower_bound.positive.0,
1070+
lower_negative: initial_permission.lower_bound.negative.0,
1071+
upper_positive: initial_permission.upper_bound.positive.0,
1072+
upper_negative: initial_permission.upper_bound.negative.0,
1073+
}
1074+
},
10501075
};
10511076

10521077
agent_type_provision_configs.insert(agent_type_name.0.clone(), provision_config.into());
@@ -1097,7 +1122,7 @@ impl ComponentCommandHandler {
10971122
component_name: component_name.clone(),
10981123
agent_types,
10991124
agent_type_provision_configs: component_stager
1100-
.agent_type_provision_configs()
1125+
.agent_type_provision_configs(environment, component_name)
11011126
.await?,
11021127
},
11031128
wasm,
@@ -1199,7 +1224,11 @@ impl ComponentCommandHandler {
11991224
current_revision: component.revision,
12001225
agent_types,
12011226
agent_type_provision_config_updates: component_stager
1202-
.agent_type_provision_config_updates(&changed_files)
1227+
.agent_type_provision_config_updates(
1228+
environment,
1229+
&component.name,
1230+
&changed_files,
1231+
)
12031232
.await
12041233
.map_err(UpdateStagedComponentError::Other)?,
12051234
allow_incompatible_config,

cli/golem-cli/src/command_handler/component/staging.rs

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,18 @@ use crate::model::app::{
2222
CanonicalFilePathWithPermissions, InitialComponentFile, InitialComponentFileSource,
2323
};
2424
use crate::model::app_raw;
25+
use crate::model::component::initial_permission_recipient_context;
2526
use crate::model::component::{AgentTypeManifestProvisionConfig, ComponentDeployProperties};
27+
use crate::model::environment::ResolvedEnvironmentIdentity;
2628
use crate::model::text::plugin::PluginNameAndVersion;
2729
use anyhow::{Context as AnyhowContext, anyhow};
2830
use golem_client::model::EnvironmentPluginGrantWithDetails;
2931
use golem_common::model::agent::AgentTypeName;
3032
use golem_common::model::component::{
31-
AgentFileOptions, AgentFilePath, AgentFilePermissions, AgentTypeProvisionConfigCreation,
32-
AgentTypeProvisionConfigUpdate, ArchiveFilePath, PluginInstallation, PluginInstallationAction,
33-
PluginInstallationUpdate, PluginPriority, PluginUninstallation,
33+
AgentFileOptions, AgentFilePath, AgentFilePermissions, AgentTypeInitialPermission,
34+
AgentTypeProvisionConfigCreation, AgentTypeProvisionConfigUpdate, ArchiveFilePath,
35+
ComponentName, PluginInstallation, PluginInstallationAction, PluginInstallationUpdate,
36+
PluginPriority, PluginUninstallation,
3437
};
3538
use golem_common::model::diff::{self, AgentFileDiff, AgentTypeProvisionConfigDiff};
3639
use golem_common::model::environment_plugin_grant::EnvironmentPluginGrantId;
@@ -526,6 +529,8 @@ impl<'a> ComponentStager<'a> {
526529

527530
pub async fn agent_type_provision_configs(
528531
&self,
532+
environment: &ResolvedEnvironmentIdentity,
533+
component_name: &ComponentName,
529534
) -> anyhow::Result<BTreeMap<AgentTypeName, AgentTypeProvisionConfigCreation>> {
530535
let all_files = self.all_manifest_files().await?;
531536
let archive_paths_by_source =
@@ -535,7 +540,14 @@ impl<'a> ComponentStager<'a> {
535540
&self.component_deploy_properties.agent_type_configs
536541
{
537542
let resolved_plugins = self.resolve_plugins_for(manifest_config)?;
538-
let mut creation = manifest_config.to_provision_config_creation(resolved_plugins);
543+
let initial_permission = self.normalize_initial_permission(
544+
environment,
545+
component_name,
546+
agent_type_name,
547+
manifest_config,
548+
)?;
549+
let mut creation = manifest_config
550+
.to_provision_config_creation(resolved_plugins, initial_permission)?;
539551
creation.files = self
540552
.resolve_archive_files_for_agent(agent_type_name, &archive_paths_by_source)
541553
.await?;
@@ -547,6 +559,8 @@ impl<'a> ComponentStager<'a> {
547559

548560
pub async fn agent_type_provision_config_updates(
549561
&self,
562+
environment: &ResolvedEnvironmentIdentity,
563+
component_name: &ComponentName,
550564
changed_files: &ChangedComponentFiles,
551565
) -> anyhow::Result<Option<BTreeMap<AgentTypeName, AgentTypeProvisionConfigUpdate>>> {
552566
let changed = match self.diff.changed_agent_types() {
@@ -556,8 +570,14 @@ impl<'a> ComponentStager<'a> {
556570
for (name, manifest_config) in &self.component_deploy_properties.agent_type_configs
557571
{
558572
let resolved_plugins = self.resolve_plugins_for(manifest_config)?;
559-
let mut creation =
560-
manifest_config.to_provision_config_creation(resolved_plugins);
573+
let initial_permission = self.normalize_initial_permission(
574+
environment,
575+
component_name,
576+
name,
577+
manifest_config,
578+
)?;
579+
let mut creation = manifest_config
580+
.to_provision_config_creation(resolved_plugins, initial_permission)?;
561581
creation.files = self
562582
.resolve_archive_files_for_agent(
563583
name,
@@ -577,6 +597,7 @@ impl<'a> ComponentStager<'a> {
577597
result.insert(
578598
name.clone(),
579599
AgentTypeProvisionConfigUpdate {
600+
initial_permission: Some(creation.initial_permission),
580601
env: Some(creation.env),
581602
config: Some(creation.config),
582603
files_to_add_or_update: self
@@ -606,7 +627,14 @@ impl<'a> ComponentStager<'a> {
606627
.filter(|(name, _)| changed.contains(name.0.as_str()))
607628
{
608629
let resolved_plugins = self.resolve_plugins_for(manifest_config)?;
609-
let mut creation = manifest_config.to_provision_config_creation(resolved_plugins);
630+
let initial_permission = self.normalize_initial_permission(
631+
environment,
632+
component_name,
633+
name,
634+
manifest_config,
635+
)?;
636+
let mut creation = manifest_config
637+
.to_provision_config_creation(resolved_plugins, initial_permission)?;
610638
creation.files = self
611639
.resolve_archive_files_for_agent(name, &changed_files.archive_paths_by_source)
612640
.await?;
@@ -680,6 +708,8 @@ impl<'a> ComponentStager<'a> {
680708
result.insert(
681709
name.clone(),
682710
AgentTypeProvisionConfigUpdate {
711+
initial_permission: self
712+
.initial_permission_update_for(name, creation.initial_permission),
683713
env: Some(creation.env),
684714
config: Some(creation.config),
685715
files_to_add_or_update: self
@@ -693,4 +723,41 @@ impl<'a> ComponentStager<'a> {
693723

694724
Ok(Some(result))
695725
}
726+
727+
fn normalize_initial_permission(
728+
&self,
729+
environment: &ResolvedEnvironmentIdentity,
730+
component_name: &ComponentName,
731+
agent_type_name: &AgentTypeName,
732+
manifest_config: &AgentTypeManifestProvisionConfig,
733+
) -> anyhow::Result<AgentTypeInitialPermission> {
734+
let context =
735+
initial_permission_recipient_context(environment, component_name, agent_type_name);
736+
Ok(manifest_config.to_initial_permission(&context))
737+
}
738+
739+
fn initial_permission_update_for(
740+
&self,
741+
name: &AgentTypeName,
742+
initial_permission: AgentTypeInitialPermission,
743+
) -> Option<AgentTypeInitialPermission> {
744+
match &self.diff {
745+
ComponentDiff::All => Some(initial_permission),
746+
ComponentDiff::Diff { diff } => {
747+
match diff
748+
.agent_type_provision_config_changes
749+
.get(name.0.as_str())
750+
{
751+
Some(diff::BTreeMapDiffValue::Create)
752+
| Some(diff::BTreeMapDiffValue::Update(diff::DiffForHashOf::HashDiff {
753+
..
754+
})) => Some(initial_permission),
755+
Some(diff::BTreeMapDiffValue::Update(diff::DiffForHashOf::ValueDiff {
756+
diff,
757+
})) if diff.initial_permission_changed => Some(initial_permission),
758+
_ => None,
759+
}
760+
}
761+
}
762+
}
696763
}

cli/golem-cli/src/command_handler/worker/mod.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,16 +1064,13 @@ impl WorkerCommandHandler {
10641064
let parsed_agent_type_name =
10651065
ParsedAgentId::parse_agent_type_name(&raw_agent_name).ok();
10661066

1067-
let defaults = parsed_agent_type_name
1068-
.as_ref()
1069-
.and_then(|agent_type_name| {
1070-
worker_component
1071-
.metadata
1072-
.agent_type_provision_configs()
1073-
.get(agent_type_name)
1074-
.cloned()
1075-
})
1076-
.unwrap_or_default();
1067+
let defaults = parsed_agent_type_name.as_ref().and_then(|agent_type_name| {
1068+
worker_component
1069+
.metadata
1070+
.agent_type_provision_configs()
1071+
.get(agent_type_name)
1072+
.cloned()
1073+
});
10771074

10781075
let source_language = parsed_agent_type_name
10791076
.as_ref()
@@ -1265,8 +1262,7 @@ impl WorkerCommandHandler {
12651262
.metadata
12661263
.agent_type_provision_configs()
12671264
.get(&agent_name_match.agent_type_name)
1268-
.cloned()
1269-
.unwrap_or_default();
1265+
.cloned();
12701266

12711267
let mut metadata_view = AgentMetadataView::from(metadata)
12721268
.with_defaults(defaults)

cli/golem-cli/src/model/app.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ impl Application {
610610

611611
let template_agent_props = app_raw::AgentLayerProperties {
612612
config: template_layer_props.config.value().clone(),
613+
initial_card: template_layer_props.initial_card.value().clone(),
613614
env_merge_mode: None,
614615
env: Some(template_layer_props.env.value().clone()),
615616
plugins_merge_mode: None,
@@ -1467,6 +1468,10 @@ impl<'a> Agent<'a> {
14671468
self.resolved.properties.config.as_ref()
14681469
}
14691470

1471+
pub fn initial_card(&self) -> Option<&app_raw::ManifestInitialCard> {
1472+
self.resolved.properties.initial_card.as_ref()
1473+
}
1474+
14701475
pub fn env(&self) -> &BTreeMap<String, String> {
14711476
&self.resolved.properties.env
14721477
}
@@ -1633,6 +1638,7 @@ impl<'a> Component<'a> {
16331638
pub fn agent_base_properties(&self) -> app_raw::AgentLayerProperties {
16341639
app_raw::AgentLayerProperties {
16351640
config: self.layer_properties().config.value().clone(),
1641+
initial_card: self.layer_properties().initial_card.value().clone(),
16361642
env_merge_mode: None,
16371643
env: Some(self.layer_properties().env.value().clone()),
16381644
plugins_merge_mode: None,
@@ -1660,6 +1666,7 @@ pub struct ComponentLayerProperties {
16601666
pub custom_commands: MapProperty<ComponentLayer, String, Vec<app_raw::ExternalCommand>>,
16611667
pub clean: VecProperty<ComponentLayer, String>,
16621668
pub config: JsonProperty<ComponentLayer>,
1669+
pub initial_card: OptionalProperty<ComponentLayer, app_raw::ManifestInitialCard>,
16631670
#[serde(skip_serializing_if = "Option::is_none")]
16641671
pub env_merge_mode: Option<MapMergeMode>,
16651672
pub env: MapProperty<ComponentLayer, String, String>,
@@ -1682,6 +1689,7 @@ impl From<app_raw::ComponentLayerProperties> for ComponentLayerProperties {
16821689
custom_commands: value.custom_commands.into(),
16831690
clean: value.clean.into(),
16841691
config: value.agent_properties.config.into(),
1692+
initial_card: value.agent_properties.initial_card.into(),
16851693
env_merge_mode: value.agent_properties.env_merge_mode,
16861694
env: value.agent_properties.env.unwrap_or_default().into(),
16871695
plugins_merge_mode: value.agent_properties.plugins_merge_mode,
@@ -1700,6 +1708,7 @@ impl ComponentLayerProperties {
17001708
self.custom_commands.compact_trace();
17011709
self.clean.compact_trace();
17021710
self.config.compact_trace();
1711+
self.initial_card.compact_trace();
17031712
self.env.compact_trace();
17041713
self.plugins.compact_trace();
17051714
self.files.compact_trace();
@@ -1866,6 +1875,9 @@ impl Layer for AgentLayer {
18661875
value
18671876
.config
18681877
.apply_layer(id, selection, properties.config.clone());
1878+
value
1879+
.initial_card
1880+
.apply_layer(id, selection, properties.initial_card.clone());
18691881
value.env.apply_layer(
18701882
id,
18711883
selection,
@@ -1904,6 +1916,7 @@ pub struct AgentLayerProperties {
19041916
)]
19051917
pub applied_layers: Vec<(AgentLayerId, Option<String>)>,
19061918
config: JsonProperty<AgentLayer>,
1919+
initial_card: OptionalProperty<AgentLayer, app_raw::ManifestInitialCard>,
19071920
env: MapProperty<AgentLayer, String, String>,
19081921
plugins: VecProperty<AgentLayer, app_raw::PluginInstallation>,
19091922
files: VecProperty<AgentLayer, app_raw::InitialComponentFile>,
@@ -1922,6 +1935,7 @@ impl AgentLayerProperties {
19221935

19231936
pub fn compact_traces(&mut self) {
19241937
self.config.compact_trace();
1938+
self.initial_card.compact_trace();
19251939
self.env.compact_trace();
19261940
self.plugins.compact_trace();
19271941
self.files.compact_trace();
@@ -1956,6 +1970,7 @@ impl AgentLayerProperties {
19561970
#[derive(Clone, Debug)]
19571971
pub struct AgentProperties {
19581972
pub config: Option<JsonValue>,
1973+
pub initial_card: Option<app_raw::ManifestInitialCard>,
19591974
pub env: BTreeMap<String, String>,
19601975
pub plugins: Vec<app_raw::PluginInstallation>,
19611976
pub files: Vec<app_raw::InitialComponentFile>,
@@ -1965,6 +1980,7 @@ impl AgentProperties {
19651980
fn from_resolved(layer_properties: &AgentLayerProperties) -> Self {
19661981
Self {
19671982
config: layer_properties.config.value().clone(),
1983+
initial_card: layer_properties.initial_card.value().clone(),
19681984
env: layer_properties
19691985
.env
19701986
.value()
@@ -1990,6 +2006,7 @@ pub struct ComponentProperties {
19902006
pub plugins: Vec<PluginInstallation>,
19912007
pub env: BTreeMap<String, String>,
19922008
pub config: Option<JsonValue>,
2009+
pub initial_card: Option<app_raw::ManifestInitialCard>,
19932010
}
19942011

19952012
impl ComponentProperties {
@@ -2022,6 +2039,7 @@ impl ComponentProperties {
20222039
plugins,
20232040
env: Self::validate_and_normalize_env(validation, merged.env.value().iter()),
20242041
config: merged.config.value().clone(),
2042+
initial_card: merged.initial_card.value().clone(),
20252043
};
20262044

20272045
for (name, value) in [("componentWasm", &properties.component_wasm)] {

0 commit comments

Comments
 (0)