Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions locales/hive.yaml
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sort alphabetically

Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,63 @@ systems.form.field.id.placeholder:
systems.form.field.id.tip:
en: Use only lowercase letters, numbers, or dashes
sv: Använd endast gemener, siffror eller bindestreck
systems.integrations.control.run-task:
en: Run Task
sv: Kör uppgift
systems.integrations.control.task-finished:
en: Task Finished
sv: Uppgift slutförd
systems.integrations.details.logs.title:
en: Logs
sv: Loggar
systems.integrations.details.settings.title:
en: Settings
sv: Inställningar
systems.integrations.logs.col.kind:
en: Level
sv: Nivå
systems.integrations.logs.col.message:
en: Message
sv: Meddelande
systems.integrations.logs.col.timestamp:
en: Timestamp
sv: Tidsstämpel
systems.integrations.logs.control.kind.label:
en: Log Level
sv: Loggnivå
systems.integrations.logs.control.kind.option.error:
en: Error
sv: Fel
systems.integrations.logs.control.kind.option.info:
en: Info
sv: Info
systems.integrations.logs.control.kind.option.warning:
en: Warning
sv: Varning
systems.integrations.logs.control.run.label:
en: Time of task run
sv: Tid för körning
systems.integrations.logs.empty:
en: This run has no logs
sv: Den här körningen har inga loggar
systems.integrations.logs.not-finished:
en: This run did not finish
sv: Den här körningen blev inte klar
systems.integrations.settings.col.key:
en: Key
sv: Nyckel
systems.integrations.settings.col.value:
en: Value
sv: Värde
systems.integrations.settings.col.value.hidden:
en: The setting is secret
sv: Inställningen är hemlig
systems.integrations.settings.col.value.not-set:
en: The setting is not set
sv: Inställningen är inte satt
systems.integrations.settings.empty:
en: This integrations has no settings
sv: Den här integrationen har inga inställningar
systems.list.action.create:
en: Create
sv: Skapa ny
Expand Down
2 changes: 1 addition & 1 deletion src/dto/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use serde::Serialize;
const BROWSER_DATE_TIME_FORMAT: &str = "%Y-%m-%dT%H:%M";
const BROWSER_DATE_FORMAT: &str = "%Y-%m-%d";

#[derive(sqlx::Type, Serialize, Clone, Debug)]
#[derive(sqlx::Type, Serialize, Clone, Debug, PartialEq)]
#[sqlx(transparent)]
#[serde(transparent)]
pub struct BrowserDateTimeDto(pub DateTime<Local>);
Expand Down
6 changes: 6 additions & 0 deletions src/dto/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ pub struct EditSystemDto<'v> {
#[field(validate = len(3..))]
pub description: TrimmedStr<'v>,
}

pub enum SettingDisplay {
Value(serde_json::Value),
Hidden,
NotSet
}
2 changes: 1 addition & 1 deletion src/integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ async fn setup_integration(manifest: &Manifest, db: &PgPool) {
}
}

async fn dispatch_task_run(integration_id: &str, task: &Task, db: &PgPool) -> AppResult<()> {
pub async fn dispatch_task_run(integration_id: &str, task: &Task, db: &PgPool) -> AppResult<()> {
let run: IntegrationTaskRun = sqlx::query_as(
"INSERT INTO integration_task_runs
(integration_id, task_id)
Expand Down
36 changes: 32 additions & 4 deletions src/models.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use std::{fmt, hash};
use std::{
cmp::Ordering,
fmt::{self, Display},
hash,
};

use chrono::{DateTime, Local, NaiveDate};
use rocket::{Either, FromFormField, UriDisplayQuery};
use sqlx::{types::JsonValue, FromRow};
use sqlx::{FromRow, types::JsonValue};
use uuid::Uuid;

use crate::{
Expand Down Expand Up @@ -461,7 +465,7 @@ impl fmt::Display for TargetKind {
}
}

#[derive(FromRow)]
#[derive(FromRow, Debug, Clone)]
pub struct IntegrationTaskRun {
pub run_id: Uuid,
pub task_id: String,
Expand All @@ -477,7 +481,7 @@ pub struct IntegrationTaskLogEntry {
pub message: String,
}

#[derive(sqlx::Type, Clone, Copy)]
#[derive(sqlx::Type, Clone, Copy, PartialEq, Eq, FromFormField, UriDisplayQuery)]
#[sqlx(
type_name = "integration_task_log_entry_kind",
rename_all = "snake_case"
Expand All @@ -487,3 +491,27 @@ pub enum IntegrationTaskLogEntryKind {
Warning,
Info,
}

impl PartialOrd for IntegrationTaskLogEntryKind {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(Self::Error, Self::Error) => Some(Ordering::Equal),
(Self::Error, _) => Some(Ordering::Greater),
(Self::Warning, Self::Error) => Some(Ordering::Less),
(Self::Warning, Self::Warning) => Some(Ordering::Equal),
(Self::Warning, Self::Info) => Some(Ordering::Greater),
(Self::Info, Self::Info) => Some(Ordering::Equal),
(Self::Info, _) => Some(Ordering::Less),
}
}
}

impl Display for IntegrationTaskLogEntryKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
IntegrationTaskLogEntryKind::Error => write!(f, "Error"),
IntegrationTaskLogEntryKind::Warning => write!(f, "Warning"),
IntegrationTaskLogEntryKind::Info => write!(f, "Info"),
}
}
}
95 changes: 94 additions & 1 deletion src/services/integrations.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
use std::collections::HashMap;

use serde_json::json;
use uuid::Uuid;

use crate::{
errors::AppResult,
models::{ActionKind, TagAssignment, TargetKind},
integrations::MANIFESTS,
models::{
ActionKind, IntegrationTaskLogEntry, IntegrationTaskRun, System, TagAssignment, TargetKind,
},
services::audit_logs,
};

Expand Down Expand Up @@ -92,3 +98,90 @@ where

Ok(())
}

pub async fn list_integrations<'x, X>(db: X) -> AppResult<Vec<System>>
where
X: sqlx::Executor<'x, Database = sqlx::Postgres>,
{
let integration_ids: Vec<String> = MANIFESTS
.iter()
.map(|integration| integration.id.to_owned())
.collect();

let integrations = sqlx::query_as(
"SELECT name, description
FROM systems
WHERE system_id IN (SELECT UNNEST($1::TEXT[]))
ORDER BY id",
)
.bind(integration_ids)
.fetch_all(db)
.await?;

Ok(integrations)
}

pub async fn list_settings<'x, X>(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include in this listing, or (best) don't show value for settings marked secret in the manifest. Probably return them here with value None, and then in the html template show (hidden) or some graphical thing. In general, secret values should never be displayed, only allowed to be overwritten, just like e.g. GitHub Actions Secrets

integration_id: &str,
db: X,
) -> AppResult<HashMap<String, serde_json::Value>>
where
X: sqlx::Executor<'x, Database = sqlx::Postgres>,
{
let settings: HashMap<String, serde_json::Value> = sqlx::query_as(
"SELECT setting_id, setting_value
FROM integration_settings
WHERE integration_id = $1
ORDER BY setting_id",
)
.bind(integration_id)
.fetch_all(db)
.await?
.into_iter()
.collect();

Ok(settings)
}

pub async fn list_runs<'x, X>(integration_id: &str, db: X) -> AppResult<Vec<IntegrationTaskRun>>
where
X: sqlx::Executor<'x, Database = sqlx::Postgres>,
{
let runs = sqlx::query_as(
"SELECT
run_id,
task_id,
start_stamp,
end_stamp,
succeeded
FROM integration_task_runs
WHERE integration_id = $1
ORDER BY start_stamp ASC",
)
.bind(integration_id)
.fetch_all(db)
.await?
.into_iter()
.collect();

Ok(runs)
}

pub async fn list_logs<'x, X>(run_id: Uuid, db: X) -> AppResult<Vec<IntegrationTaskLogEntry>>
where
X: sqlx::Executor<'x, Database = sqlx::Postgres>,
{
let logs = sqlx::query_as(
"SELECT stamp, kind, message
FROM integration_task_logs
WHERE run_id = $1
ORDER BY stamp ASC",
)
.bind(run_id)
.fetch_all(db)
.await?
.into_iter()
.collect();

Ok(logs)
}
2 changes: 1 addition & 1 deletion src/web/logs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rinja::Template;
use rocket::{response::content::RawHtml, Either, State};
use rocket::{Either, State, response::content::RawHtml};
use sqlx::PgPool;

use crate::{
Expand Down
Loading