From 369c27b68fe303bac7d2bbe3946bd7f79690bf87 Mon Sep 17 00:00:00 2001 From: Geoffrey Arthaud <geoffrey.arthaud@developpement-durable.gouv.fr> Date: Mon, 18 Mar 2024 20:23:05 +0100 Subject: [PATCH] Fix compatibility with job token's permissions --- i18n/en-GB/gitlab_project_doctor.ftl | 3 +- i18n/fr-FR/gitlab_project_doctor.ftl | 3 +- src/diagnosis/container_analysis.rs | 4 +-- src/diagnosis/gitlab_connection.rs | 19 ++++-------- src/diagnosis/job_analysis.rs | 44 ++++++++++++++++------------ src/diagnosis/package_analysis.rs | 2 +- src/diagnosis/pipeline_analysis.rs | 2 +- src/diagnosis/pipeline_clean.rs | 43 ++++++++++++++------------- src/main.rs | 8 ++--- 9 files changed, 64 insertions(+), 64 deletions(-) diff --git a/i18n/en-GB/gitlab_project_doctor.ftl b/i18n/en-GB/gitlab_project_doctor.ftl index 5ad36a7..d9c5825 100644 --- a/i18n/en-GB/gitlab_project_doctor.ftl +++ b/i18n/en-GB/gitlab_project_doctor.ftl @@ -25,7 +25,8 @@ help-days = Number of days from which an element is considered "old", 30 by defa help-git-path = Analyze the project from a local path of a Git repository. Ignored if url option is specified help-token = (Not recommended) Gitlab private token for authentication, maintainer role is needed for objects deletion. It is strongly advised to use the environment variable GL_TOKEN instead of this argument, for security reasons. help-url = Analyze the project from the URL of Gitlab repository -no-cicd = No CI/CD configured for this project +no-cicd = No CI/CD configured for this project. +no-permission-jobanalysis = The token has no permission for job analysis. package-analysing = Analysis of packages package-clean-report = Deleted {$nb_packages} packages, {$size} saved. package-deleting = Deleting obsolete packages files diff --git a/i18n/fr-FR/gitlab_project_doctor.ftl b/i18n/fr-FR/gitlab_project_doctor.ftl index de2a036..43999a6 100644 --- a/i18n/fr-FR/gitlab_project_doctor.ftl +++ b/i18n/fr-FR/gitlab_project_doctor.ftl @@ -25,7 +25,8 @@ help-days = Nombre de jours d'ancienneté à partir duquel un élément est cons help-git-path = Analyse du projet à partir d'un chemin vers un dépôt Git. Ignoré si l'option url est spécifiée help-token = (Non recommandé) Token privé Gitlab d'authentification, avec le rôle maintainer nécessaire pour la suppression. Il est conseillé d'utiliser la variable GL_TOKEN à la place de cet argument, pour des raisons de sécurité. help-url = Analyse du projet à partir d'une URL Gitlab -no-cicd = Aucun CI/CD configuré pour ce projet +no-cicd = Aucun CI/CD configuré pour ce projet. +no-permission-jobanalysis = Le token n'a pas la permission d'analyser les jobs. package-analysing = Analyse du package registry package-clean-report = {$nb_packages} packages supprimés, {$size} récupérés. package-deleting = Suppression des fichiers de package obsolètes diff --git a/src/diagnosis/container_analysis.rs b/src/diagnosis/container_analysis.rs index 287ed9c..a546619 100644 --- a/src/diagnosis/container_analysis.rs +++ b/src/diagnosis/container_analysis.rs @@ -4,9 +4,9 @@ use gitlab::Gitlab; use human_bytes::human_bytes; use serde::Deserialize; -use crate::{api, fl, Reportable, ReportJob, ReportPending, ReportStatus}; -use crate::diagnosis::{CONTAINER_REGISTRY_LIMIT, warning_if}; use crate::diagnosis::gitlab_connection::{GitlabRepository, Project}; +use crate::diagnosis::{warning_if, CONTAINER_REGISTRY_LIMIT}; +use crate::{api, fl, ReportJob, ReportPending, ReportStatus, Reportable}; #[derive(Debug, Deserialize)] pub struct GitlabRawContainerRepository { diff --git a/src/diagnosis/gitlab_connection.rs b/src/diagnosis/gitlab_connection.rs index 0c1dfa8..3a436b3 100644 --- a/src/diagnosis/gitlab_connection.rs +++ b/src/diagnosis/gitlab_connection.rs @@ -9,8 +9,8 @@ use regex::Regex; use serde::{Deserialize, Serialize}; use crate::diagnosis::{ - ARTIFACT_JOBS_LIMIT, PACKAGE_REGISTRY_LIMIT, REPO_LIMIT, Reportable, ReportJob, ReportPending, - ReportStatus, STORAGE_LIMIT, warning_if, + warning_if, ReportJob, ReportPending, ReportStatus, Reportable, ARTIFACT_JOBS_LIMIT, + PACKAGE_REGISTRY_LIMIT, REPO_LIMIT, STORAGE_LIMIT, }; use crate::fl; @@ -149,10 +149,7 @@ impl ConnectionJob { Ok((client, project)) } - fn _gitlab_project_job_token( - server: &str, - token: &str, - ) -> Result<(Gitlab, Project)> { + fn _gitlab_project_job_token(server: &str, token: &str) -> Result<(Gitlab, Project)> { let client = Gitlab::new_job_token(server, token)?; let project = Project { id: env::var("CI_PROJECT_ID")?.parse()?, @@ -243,10 +240,7 @@ fn _report_artifact_storage(stats: &Statistics) -> ReportStatus { human_bytes(stats.job_artifacts_size as f64), 100 * stats.job_artifacts_size / stats.storage_size ); - warning_if( - stats.job_artifacts_size > ARTIFACT_JOBS_LIMIT, - msg, - ) + warning_if(stats.job_artifacts_size > ARTIFACT_JOBS_LIMIT, msg) } fn _report_package_storage(stats: &Statistics) -> ReportStatus { @@ -256,10 +250,7 @@ fn _report_package_storage(stats: &Statistics) -> ReportStatus { human_bytes(stats.packages_size as f64), 100 * stats.packages_size / stats.storage_size ); - warning_if( - stats.packages_size > PACKAGE_REGISTRY_LIMIT, - msg, - ) + warning_if(stats.packages_size > PACKAGE_REGISTRY_LIMIT, msg) } fn gitlab_url(repo: &Repository) -> Option<(String, String)> { diff --git a/src/diagnosis/job_analysis.rs b/src/diagnosis/job_analysis.rs index 2ffbcfa..eed9e04 100644 --- a/src/diagnosis/job_analysis.rs +++ b/src/diagnosis/job_analysis.rs @@ -1,13 +1,13 @@ use chrono::{DateTime, Local, TimeDelta}; -use gitlab::api::{Pagination, projects, Query}; use gitlab::api::paged; +use gitlab::api::{projects, Pagination, Query}; use gitlab::Gitlab; use human_bytes::human_bytes; use serde::Deserialize; -use crate::{Reportable, ReportJob, ReportPending}; use crate::diagnosis::gitlab_connection::{GitlabRepository, Project}; use crate::diagnosis::ReportStatus; +use crate::{fl, ReportJob, ReportPending, Reportable}; #[derive(Debug, Deserialize)] pub struct Artifact { @@ -38,6 +38,16 @@ impl Reportable for JobAnalysisReport { } } +impl JobAnalysisReport { + pub fn simple(status: ReportStatus) -> JobAnalysisReport { + JobAnalysisReport { + gitlab_jobs: vec![], + report_status: vec![status], + savable_bytes: 0, + } + } +} + impl ReportJob for JobAnalysisJob { type Diagnosis = JobAnalysisReport; @@ -47,27 +57,25 @@ impl ReportJob for JobAnalysisJob { job: { std::thread::spawn(move || { if !self.project.jobs_enabled { - return JobAnalysisReport { - report_status: vec![ReportStatus::NA( - "No CI/CD configured on this project".to_string(), - )], - gitlab_jobs: vec![], - savable_bytes: 0, - }; + return JobAnalysisReport::simple(ReportStatus::NA(fl!("no-cicd"))); } let endpoint = projects::jobs::Jobs::builder() .project(self.project.id) .build() .unwrap(); - let jobs: Vec<GitlabJob> = paged(endpoint, Pagination::All) - .query(&self.gitlab) - .unwrap(); - let (report, bytes_savable) = self._number_jobs(&jobs); - JobAnalysisReport { - report_status: vec![report], - gitlab_jobs: jobs, - savable_bytes: bytes_savable, - } + paged(endpoint, Pagination::All).query(&self.gitlab).map_or( + JobAnalysisReport::simple(ReportStatus::NA(fl!( + "no-permission-jobanalysis" + ))), + |jobs| { + let (report, bytes_savable) = self._number_jobs(&jobs); + JobAnalysisReport { + report_status: vec![report], + gitlab_jobs: jobs, + savable_bytes: bytes_savable, + } + }, + ) }) }, progress: None, diff --git a/src/diagnosis/package_analysis.rs b/src/diagnosis/package_analysis.rs index 035e2d9..f1152f1 100644 --- a/src/diagnosis/package_analysis.rs +++ b/src/diagnosis/package_analysis.rs @@ -6,9 +6,9 @@ use lazy_static::lazy_static; use regex::Regex; use serde::Deserialize; -use crate::{fl, Reportable, ReportJob, ReportPending, ReportStatus}; use crate::api::packages::{PackageFiles, Packages}; use crate::diagnosis::gitlab_connection::{GitlabRepository, Project}; +use crate::{fl, ReportJob, ReportPending, ReportStatus, Reportable}; #[derive(Debug, Deserialize)] pub struct GitlabPackage { diff --git a/src/diagnosis/pipeline_analysis.rs b/src/diagnosis/pipeline_analysis.rs index 61d23b0..062dba4 100644 --- a/src/diagnosis/pipeline_analysis.rs +++ b/src/diagnosis/pipeline_analysis.rs @@ -3,8 +3,8 @@ use gitlab::api::{Pagination, Query}; use gitlab::Gitlab; use serde::Deserialize; -use crate::{fl, Reportable, ReportJob, ReportPending, ReportStatus}; use crate::diagnosis::gitlab_connection::{GitlabRepository, Project}; +use crate::{fl, ReportJob, ReportPending, ReportStatus, Reportable}; #[derive(Debug, Deserialize)] pub struct GitlabPipeline { diff --git a/src/diagnosis/pipeline_clean.rs b/src/diagnosis/pipeline_clean.rs index 24b3873..46236c4 100644 --- a/src/diagnosis/pipeline_clean.rs +++ b/src/diagnosis/pipeline_clean.rs @@ -6,10 +6,10 @@ use gitlab::api::{ApiError, Query}; use gitlab::Gitlab; use human_bytes::human_bytes; -use crate::{fl, Reportable, ReportPending, ReportStatus}; -use crate::diagnosis::{GITLAB_SCOPE_ERROR, RemedyJob}; use crate::diagnosis::gitlab_connection::{Project, Statistics}; use crate::diagnosis::pipeline_analysis::{GitlabPipeline, PipelineAnalysisReport}; +use crate::diagnosis::{RemedyJob, GITLAB_SCOPE_ERROR}; +use crate::{fl, ReportPending, ReportStatus, Reportable}; pub struct PipelineCleanJob { pub pipeline_report: PipelineAnalysisReport, @@ -118,25 +118,26 @@ impl RemedyJob for PipelineCleanJob { let mut report_status = vec![]; - let saved_bytes = if let Some(stats) = self.pipeline_report.project.statistics.as_ref() { - let saved_bytes_value = PipelineCleanJob::_compute_saved_bytes( - &self.pipeline_report.gitlab, - &self.pipeline_report.project, - stats, - ); - report_status.push(ReportStatus::OK(fl!( - "pipeline-clean-report-size", - nb_pipelines = deleted_pipelines.len(), - size = human_bytes(saved_bytes_value as f64) - ))); - Some(saved_bytes_value) - } else { - report_status.push(ReportStatus::OK(fl!( - "pipeline-clean-report", - nb_pipelines = deleted_pipelines.len() - ))); - None - }; + let saved_bytes = + if let Some(stats) = self.pipeline_report.project.statistics.as_ref() { + let saved_bytes_value = PipelineCleanJob::_compute_saved_bytes( + &self.pipeline_report.gitlab, + &self.pipeline_report.project, + stats, + ); + report_status.push(ReportStatus::OK(fl!( + "pipeline-clean-report-size", + nb_pipelines = deleted_pipelines.len(), + size = human_bytes(saved_bytes_value as f64) + ))); + Some(saved_bytes_value) + } else { + report_status.push(ReportStatus::OK(fl!( + "pipeline-clean-report", + nb_pipelines = deleted_pipelines.len() + ))); + None + }; if last_is_old { report_status.push(ReportStatus::NA(fl!("pipeline-last-notdeleted"))); diff --git a/src/main.rs b/src/main.rs index 24ba522..f9f6456 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use i18n_embed::{ - DesktopLanguageRequester, fluent::{fluent_language_loader, FluentLanguageLoader}, + DesktopLanguageRequester, }; use lazy_static::lazy_static; use rust_embed::RustEmbed; @@ -9,7 +9,6 @@ use structopt::StructOpt; use cli::Args; -use crate::diagnosis::{RemedyJob, Reportable, ReportJob, ReportPending}; use crate::diagnosis::conf_analysis::{ConfAnalysisJob, ConfAnalysisReport}; use crate::diagnosis::container_analysis::{ContainerAnalysisJob, ContainerAnalysisReport}; use crate::diagnosis::gitlab_connection::{ConnectionJob, GitlabRepository, Statistics}; @@ -19,6 +18,7 @@ use crate::diagnosis::package_clean::PackageCleanJob; use crate::diagnosis::pipeline_analysis::{PipelineAnalysisJob, PipelineAnalysisReport}; use crate::diagnosis::pipeline_clean::PipelineCleanJob; use crate::diagnosis::ReportStatus; +use crate::diagnosis::{RemedyJob, ReportJob, ReportPending, Reportable}; pub mod api; pub mod cli; @@ -112,9 +112,7 @@ impl AnalysisReport { 0 }; (savable_repo * 9 + self.savable_bytes_jobs + self.savable_bytes_packages) * 100 - / (stats.repository_size * 9 - + stats.job_artifacts_size - + stats.packages_size) + / (stats.repository_size * 9 + stats.job_artifacts_size + stats.packages_size) } } -- GitLab