This commit is contained in:
mbecker20
2024-03-27 05:54:15 -07:00
parent 6dcc4b30de
commit 3492eb3126
7 changed files with 120 additions and 90 deletions

View File

@@ -298,10 +298,10 @@ async fn get_build_builder(
Builder::get_resource(&build.config.builder_id).await?;
match builder.config {
BuilderConfig::Server(config) => {
if config.id.is_empty() {
if config.server_id.is_empty() {
return Err(anyhow!("build has not configured a builder"));
}
let server = Server::get_resource(&config.id).await?;
let server = Server::get_resource(&config.server_id).await?;
let periphery = periphery_client(&server)?;
Ok((
periphery,

View File

@@ -111,7 +111,9 @@ impl Resolve<GetBuilderAvailableAccounts, User> for State {
BuilderConfig::Server(config) => {
let res = self
.resolve(
read::GetAvailableAccounts { server: config.id },
read::GetAvailableAccounts {
server: config.server_id,
},
user,
)
.await?;

View File

@@ -5,9 +5,12 @@ use async_trait::async_trait;
use monitor_client::{
api::write::*,
entities::{
builder::Builder,
builder::{
Builder, PartialBuilderConfig, PartialServerBuilderConfig,
},
monitor_timestamp,
permission::PermissionLevel,
server::Server,
update::{Log, ResourceTarget, Update},
user::User,
Operation,
@@ -29,17 +32,40 @@ use crate::{
state::State,
};
async fn validate_config(
config: &mut PartialBuilderConfig,
user: &User,
) -> anyhow::Result<()> {
match config {
PartialBuilderConfig::Server(PartialServerBuilderConfig {
server_id: Some(server_id),
}) if !server_id.is_empty() => {
let server = Server::get_resource_check_permissions(
server_id,
user,
PermissionLevel::Write,
)
.await?;
*server_id = server.id;
}
_ => {}
}
Ok(())
}
#[async_trait]
impl Resolve<CreateBuilder, User> for State {
async fn resolve(
&self,
CreateBuilder { name, config }: CreateBuilder,
CreateBuilder { name, mut config }: CreateBuilder,
user: User,
) -> anyhow::Result<Builder> {
let start_ts = monitor_timestamp();
if ObjectId::from_str(&name).is_ok() {
return Err(anyhow!("valid ObjectIds cannot be used as names"));
}
validate_config(&mut config, &user).await?;
let builder = Builder {
id: Default::default(),
name,
@@ -205,7 +231,7 @@ impl Resolve<DeleteBuilder, User> for State {
impl Resolve<UpdateBuilder, User> for State {
async fn resolve(
&self,
UpdateBuilder { id, config }: UpdateBuilder,
UpdateBuilder { id, mut config }: UpdateBuilder,
user: User,
) -> anyhow::Result<Builder> {
let builder = Builder::get_resource_check_permissions(
@@ -215,6 +241,8 @@ impl Resolve<UpdateBuilder, User> for State {
)
.await?;
validate_config(&mut config, &user).await?;
let mut update = Update {
target: ResourceTarget::Builder(id.clone()),
operation: Operation::UpdateBuilder,

View File

@@ -7,7 +7,10 @@ use monitor_client::{
entities::{
all_logs_success,
build::Build,
deployment::{Deployment, DeploymentImage, DockerContainerState},
deployment::{
Deployment, DeploymentImage, DockerContainerState,
PartialDeploymentConfig,
},
monitor_timestamp,
permission::PermissionLevel,
server::Server,
@@ -36,6 +39,55 @@ use crate::{
state::{action_states, State},
};
async fn validate_config(
config: &mut PartialDeploymentConfig,
user: &User,
) -> anyhow::Result<()> {
if let Some(server_id) = &config.server_id {
if !server_id.is_empty() {
let server = Server::get_resource_check_permissions(server_id, user, PermissionLevel::Write)
.await
.context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?;
config.server_id = Some(server.id);
}
}
if let Some(DeploymentImage::Build { build_id, version }) =
&config.image
{
if !build_id.is_empty() {
let build = Build::get_resource_check_permissions(build_id, user, PermissionLevel::Read)
.await
.context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?;
config.image = Some(DeploymentImage::Build {
build_id: build.id,
version: version.clone(),
});
}
}
if let Some(volumes) = &mut config.volumes {
volumes.retain(|v| {
!empty_or_only_spaces(&v.local)
&& !empty_or_only_spaces(&v.container)
})
}
if let Some(ports) = &mut config.ports {
ports.retain(|v| {
!empty_or_only_spaces(&v.local)
&& !empty_or_only_spaces(&v.container)
})
}
if let Some(environment) = &mut config.environment {
environment.retain(|v| {
!empty_or_only_spaces(&v.variable)
&& !empty_or_only_spaces(&v.value)
})
}
if let Some(extra_args) = &mut config.extra_args {
extra_args.retain(|v| !empty_or_only_spaces(v))
}
Ok(())
}
#[async_trait]
impl Resolve<CreateDeployment, User> for State {
async fn resolve(
@@ -47,27 +99,7 @@ impl Resolve<CreateDeployment, User> for State {
if ObjectId::from_str(&name).is_ok() {
return Err(anyhow!("valid ObjectIds cannot be used as names"));
}
if let Some(server_id) = &config.server_id {
if !server_id.is_empty() {
let server = Server::get_resource_check_permissions(server_id, &user, PermissionLevel::Write)
.await
.context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?;
config.server_id = Some(server.id);
}
}
if let Some(DeploymentImage::Build { build_id, version }) =
&config.image
{
if !build_id.is_empty() {
let build = Build::get_resource_check_permissions(build_id, &user, PermissionLevel::Read)
.await
.context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?;
config.image = Some(DeploymentImage::Build {
build_id: build.id,
version: version.clone(),
});
}
}
validate_config(&mut config, &user).await?;
let start_ts = monitor_timestamp();
let deployment = Deployment {
id: Default::default(),
@@ -333,40 +365,7 @@ impl Resolve<UpdateDeployment, User> for State {
let inner = || async move {
let start_ts = monitor_timestamp();
if let Some(server_id) = &config.server_id {
Server::get_resource_check_permissions(server_id, &user, PermissionLevel::Write)
.await
.context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?;
}
if let Some(DeploymentImage::Build { build_id, .. }) =
&config.image
{
Build::get_resource_check_permissions(build_id, &user, PermissionLevel::Read)
.await
.context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?;
}
if let Some(volumes) = &mut config.volumes {
volumes.retain(|v| {
!empty_or_only_spaces(&v.local)
&& !empty_or_only_spaces(&v.container)
})
}
if let Some(ports) = &mut config.ports {
ports.retain(|v| {
!empty_or_only_spaces(&v.local)
&& !empty_or_only_spaces(&v.container)
})
}
if let Some(environment) = &mut config.environment {
environment.retain(|v| {
!empty_or_only_spaces(&v.variable)
&& !empty_or_only_spaces(&v.value)
})
}
if let Some(extra_args) = &mut config.extra_args {
extra_args.retain(|v| !empty_or_only_spaces(v))
}
validate_config(&mut config, &user).await?;
update_one_by_id(
&db_client().await.deployments,

View File

@@ -7,7 +7,7 @@ use monitor_client::{
entities::{
monitor_timestamp,
permission::PermissionLevel,
repo::Repo,
repo::{PartialRepoConfig, Repo},
server::Server,
to_monitor_name,
update::{Log, ResourceTarget, Update},
@@ -33,6 +33,26 @@ use crate::{
state::{action_states, State},
};
async fn validate_config(
config: &mut PartialRepoConfig,
user: &User,
) -> anyhow::Result<()> {
match &config.server_id {
Some(server_id) if !server_id.is_empty() => {
let server = Server::get_resource_check_permissions(
server_id,
&user,
PermissionLevel::Write,
)
.await
.context("cannot create repo on this server. user must have update permissions on the server.")?;
config.server_id = Some(server.id);
}
_ => {}
}
Ok(())
}
#[async_trait]
impl Resolve<CreateRepo, User> for State {
async fn resolve(
@@ -44,18 +64,7 @@ impl Resolve<CreateRepo, User> for State {
if ObjectId::from_str(&name).is_ok() {
return Err(anyhow!("valid ObjectIds cannot be used as names"));
}
if let Some(server_id) = &config.server_id {
if !server_id.is_empty() {
let server = Server::get_resource_check_permissions(
server_id,
&user,
PermissionLevel::Write,
)
.await
.context("cannot create repo on this server. user must have update permissions on the server.")?;
config.server_id = Some(server.id);
}
}
validate_config(&mut config, &user).await?;
let start_ts = monitor_timestamp();
let repo = Repo {
id: Default::default(),
@@ -283,20 +292,10 @@ impl Resolve<DeleteRepo, User> for State {
impl Resolve<UpdateRepo, User> for State {
async fn resolve(
&self,
UpdateRepo { id, config }: UpdateRepo,
UpdateRepo { id, mut config }: UpdateRepo,
user: User,
) -> anyhow::Result<Repo> {
if let Some(server_id) = &config.server_id {
if !server_id.is_empty() {
Server::get_resource_check_permissions(
server_id,
&user,
PermissionLevel::Write,
)
.await
.context("cannot move repo to this server. user must have update permissions on the server.")?;
}
}
validate_config(&mut config, &user).await?;
let repo = Repo::get_resource_check_permissions(
&id,

View File

@@ -419,7 +419,7 @@ impl StateResource for Builder {
) -> anyhow::Result<BuilderListItem> {
let (provider, instance_type) = match builder.config {
BuilderConfig::Server(config) => {
("server".to_string(), Some(config.id))
("server".to_string(), Some(config.server_id))
}
BuilderConfig::Aws(config) => {
("aws ec2".to_string(), Some(config.instance_type))

View File

@@ -87,7 +87,7 @@ impl BuilderConfig {
PartialBuilderConfig::Server(partial) => match self {
BuilderConfig::Server(config) => {
let config = ServerBuilderConfig {
id: partial.id.unwrap_or(config.id),
server_id: partial.server_id.unwrap_or(config.server_id),
};
BuilderConfig::Server(config)
}
@@ -137,7 +137,9 @@ impl BuilderConfig {
#[skip_serializing_none]
#[partial_from]
pub struct ServerBuilderConfig {
pub id: String,
#[serde(alias = "server")]
#[partial_attr(serde(alias = "server"))]
pub server_id: String,
}
#[typeshare]