diff --git a/rust/stackable-cockpit/src/engine/kind/mod.rs b/rust/stackable-cockpit/src/engine/kind/mod.rs index 117b4787..ef4f73d8 100644 --- a/rust/stackable-cockpit/src/engine/kind/mod.rs +++ b/rust/stackable-cockpit/src/engine/kind/mod.rs @@ -35,10 +35,10 @@ pub enum Error { CommandErroredOut { error: String }, #[snafu(display("missing required binary: {binary}"))] - MissingBinaryError { binary: String }, + MissingBinary { binary: String }, #[snafu(display("failed to determine if Docker is running"))] - DockerError { source: docker::Error }, + DockerCheckCommand { source: docker::Error }, #[snafu(display("failed to covert kind config to YAML"))] ConfigSerialization { source: serde_yaml::Error }, @@ -71,11 +71,13 @@ impl Cluster { // Check if required binaries are present if let Some(binary) = binaries_present_with_name(&["docker", "kind"]) { - return Err(Error::MissingBinaryError { binary }); + return Err(Error::MissingBinary { binary }); } // Check if Docker is running - check_if_docker_is_running().await.context(DockerSnafu)?; + check_if_docker_is_running() + .await + .context(DockerCheckCommandSnafu)?; debug!("Creating kind cluster config"); let config = Config::new(self.node_count, self.cp_node_count); diff --git a/rust/stackable-cockpit/src/engine/minikube/mod.rs b/rust/stackable-cockpit/src/engine/minikube/mod.rs index 31213d30..c92b795e 100644 --- a/rust/stackable-cockpit/src/engine/minikube/mod.rs +++ b/rust/stackable-cockpit/src/engine/minikube/mod.rs @@ -22,10 +22,10 @@ pub enum Error { MissingBinary { binary: String }, #[snafu(display("failed to execute minikube command"))] - CommandError { source: std::io::Error }, + MinikubeCommand { source: std::io::Error }, #[snafu(display("failed to determine if Docker is running"))] - DockerError { source: docker::Error }, + DockerCheckCommand { source: docker::Error }, } #[derive(Debug)] @@ -55,7 +55,9 @@ impl Cluster { } // Check if Docker is running - check_if_docker_is_running().await.context(DockerSnafu)?; + check_if_docker_is_running() + .await + .context(DockerCheckCommandSnafu)?; // Create local cluster via minikube debug!("Creating minikube cluster"); @@ -66,7 +68,7 @@ impl Cluster { .args(["-p", self.name.as_str()]) .status() .await - .context(CommandSnafu)?; + .context(MinikubeCommandSnafu)?; Ok(()) } diff --git a/rust/stackable-cockpit/src/helm.rs b/rust/stackable-cockpit/src/helm.rs index 61356630..2333260a 100644 --- a/rust/stackable-cockpit/src/helm.rs +++ b/rust/stackable-cockpit/src/helm.rs @@ -93,7 +93,7 @@ pub enum InstallReleaseError { /// is not typed, as the error is a plain string coming directly from the /// FFI bindings. #[snafu(display("helm error: {error}"))] - HelmWrapperError { error: String }, + HelmWrapper { error: String }, } #[derive(Debug)] @@ -282,7 +282,7 @@ fn install_release( ); return Err(Error::InstallRelease { - source: InstallReleaseError::HelmWrapperError { error }, + source: InstallReleaseError::HelmWrapper { error }, }); } diff --git a/rust/stackable-cockpit/src/platform/cluster/resource_request.rs b/rust/stackable-cockpit/src/platform/cluster/resource_request.rs index 71fcca9a..873b4792 100644 --- a/rust/stackable-cockpit/src/platform/cluster/resource_request.rs +++ b/rust/stackable-cockpit/src/platform/cluster/resource_request.rs @@ -44,10 +44,10 @@ impl Display for ResourceRequests { #[derive(Debug, Snafu)] pub enum ResourceRequestsError { #[snafu(display("failed to create kube client"))] - KubeClientError { source: Error }, + KubeClientCreate { source: Error }, #[snafu(display("failed to retrieve cluster info"))] - ClusterInfoError { source: Error }, + ClusterInfo { source: Error }, #[snafu(display("failed to parse cpu resource requirements"))] ParseCpuResourceRequirements { @@ -92,7 +92,7 @@ impl ResourceRequests { /// resources to the available ones in the current cluster. `object_name` /// should be `stack` or `demo`. pub async fn validate_cluster_size(&self, object_name: &str) -> Result<()> { - let kube_client = Client::new().await.context(KubeClientSnafu)?; + let kube_client = Client::new().await.context(KubeClientCreateSnafu)?; let cluster_info = kube_client .get_cluster_info() .await diff --git a/rust/stackable-cockpit/src/platform/credentials.rs b/rust/stackable-cockpit/src/platform/credentials.rs index d880fb0a..01bbd503 100644 --- a/rust/stackable-cockpit/src/platform/credentials.rs +++ b/rust/stackable-cockpit/src/platform/credentials.rs @@ -11,7 +11,7 @@ pub type Result = std::result::Result; #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("failed to fetch data from kubernetes API"))] - KubeClientFetchError { source: k8s::Error }, + KubeClientFetch { source: k8s::Error }, #[snafu(display("no credentials secret found"))] NoSecret, diff --git a/rust/stackable-cockpit/src/platform/demo/spec.rs b/rust/stackable-cockpit/src/platform/demo/spec.rs index e634a982..1b55e505 100644 --- a/rust/stackable-cockpit/src/platform/demo/spec.rs +++ b/rust/stackable-cockpit/src/platform/demo/spec.rs @@ -38,7 +38,7 @@ pub enum Error { InstallDemoManifests { source: stack::Error }, #[snafu(display("demo resource requests error"), context(false))] - DemoResourceRequestsError { source: ResourceRequestsError }, + DemoResourceRequests { source: ResourceRequestsError }, #[snafu(display("cannot install demo in namespace '{requested}', only '{}' supported", supported.join(", ")))] UnsupportedNamespace { diff --git a/rust/stackable-cockpit/src/platform/namespace.rs b/rust/stackable-cockpit/src/platform/namespace.rs index cbf0665b..5060f3f0 100644 --- a/rust/stackable-cockpit/src/platform/namespace.rs +++ b/rust/stackable-cockpit/src/platform/namespace.rs @@ -5,7 +5,7 @@ use crate::utils::k8s; #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("failed to create kubernetes client"))] - KubeClientCreateError { source: k8s::Error }, + KubeClientCreate { source: k8s::Error }, #[snafu(display("permission denied - try to create the namespace manually or choose an already existing one to which you have access to"))] PermissionDenied, @@ -20,12 +20,12 @@ pub async fn create_if_needed(name: String) -> Result<(), Error> { .create_namespace_if_needed(name) .await .map_err(|err| match err { - k8s::Error::KubeError { source } => match source { + k8s::Error::KubeClientCreate { source } => match source { kube::Error::Api(err) if err.code == 401 => Error::PermissionDenied, - _ => Error::KubeClientCreateError { - source: k8s::Error::KubeError { source }, + _ => Error::KubeClientCreate { + source: k8s::Error::KubeClientCreate { source }, }, }, - _ => Error::KubeClientCreateError { source: err }, + _ => Error::KubeClientCreate { source: err }, }) } diff --git a/rust/stackable-cockpit/src/platform/release/spec.rs b/rust/stackable-cockpit/src/platform/release/spec.rs index ba365338..5b3343f6 100644 --- a/rust/stackable-cockpit/src/platform/release/spec.rs +++ b/rust/stackable-cockpit/src/platform/release/spec.rs @@ -19,10 +19,10 @@ pub enum Error { OperatorSpecParse { source: operator::SpecParseError }, #[snafu(display("failed to install release using Helm"))] - HelmInstallError { source: helm::Error }, + HelmInstall { source: helm::Error }, #[snafu(display("failed to uninstall release using Helm"))] - HelmUninstallError { source: helm::Error }, + HelmUninstall { source: helm::Error }, } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/rust/stackable-cockpit/src/platform/service.rs b/rust/stackable-cockpit/src/platform/service.rs index 5b8fadc5..99a41840 100644 --- a/rust/stackable-cockpit/src/platform/service.rs +++ b/rust/stackable-cockpit/src/platform/service.rs @@ -18,7 +18,7 @@ use crate::utils::k8s::{self, ListParamsExt}; #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("failed to fetch data from kubernetes API"))] - KubeClientFetchError { source: k8s::Error }, + KubeClientFetch { source: k8s::Error }, #[snafu(display("missing namespace for service '{service}'"))] MissingServiceNamespace { service: String }, diff --git a/rust/stackable-cockpit/src/platform/stack/spec.rs b/rust/stackable-cockpit/src/platform/stack/spec.rs index 0fbf0ded..0ea0450a 100644 --- a/rust/stackable-cockpit/src/platform/stack/spec.rs +++ b/rust/stackable-cockpit/src/platform/stack/spec.rs @@ -37,7 +37,7 @@ pub enum Error { /// This error indicates that parsing a string into stack / demo parameters /// failed. #[snafu(display("failed to parse demo / stack parameters"))] - ParameterError { source: IntoParametersError }, + ParameterParse { source: IntoParametersError }, /// This error indicates that the requested release doesn't exist in the /// loaded list of releases. @@ -46,12 +46,12 @@ pub enum Error { /// This error indicates that the release failed to install. #[snafu(display("failed to install release"))] - ReleaseInstallError { source: release::Error }, + ReleaseInstall { source: release::Error }, /// This error indicates that the Helm wrapper failed to add the Helm /// repository. #[snafu(display("failed to add Helm repository {repo_name}"))] - HelmAddRepositoryError { + HelmAddRepository { source: helm::Error, repo_name: String, }, @@ -59,37 +59,37 @@ pub enum Error { /// This error indicates that the Hlm wrapper failed to install the Helm /// release. #[snafu(display("failed to install Helm release {release_name}"))] - HelmInstallReleaseError { + HelmInstallRelease { release_name: String, source: helm::Error, }, /// This error indicates that the creation of a kube client failed. #[snafu(display("failed to create kubernetes client"))] - KubeClientCreateError { source: k8s::Error }, + KubeClientCreate { source: k8s::Error }, /// This error indicates that the kube client failed to deloy manifests. #[snafu(display("failed to deploy manifests using the kube client"))] - ManifestDeployError { source: k8s::Error }, + ManifestDeploy { source: k8s::Error }, /// This error indicates that Helm chart options could not be serialized /// into YAML. #[snafu(display("failed to serialize Helm chart options"))] - SerializeOptionsError { source: serde_yaml::Error }, + SerializeOptions { source: serde_yaml::Error }, #[snafu(display("stack resource requests error"), context(false))] - StackResourceRequestsError { source: ResourceRequestsError }, + StackResourceRequests { source: ResourceRequestsError }, /// This error indicates that parsing a string into a path or URL failed. #[snafu(display("failed to parse '{path_or_url}' as path/url"))] - PathOrUrlParseError { + PathOrUrlParse { source: PathOrUrlParseError, path_or_url: String, }, /// This error indicates that receiving remote content failed. #[snafu(display("failed to receive remote content"))] - TransferError { source: xfer::Error }, + FileTransfer { source: xfer::Error }, /// This error indicates that the stack doesn't support being installed in /// the provided namespace. @@ -212,7 +212,7 @@ impl StackSpec { let parameters = parameters .to_owned() .into_params(&self.parameters) - .context(ParameterSnafu)?; + .context(ParameterParseSnafu)?; Self::install_manifests( &self.manifests, @@ -238,7 +238,7 @@ impl StackSpec { let parameters = demo_parameters .to_owned() .into_params(valid_demo_parameters) - .context(ParameterSnafu)?; + .context(ParameterParseSnafu)?; Self::install_manifests(manifests, ¶meters, product_namespace, transfer_client).await?; Ok(()) @@ -267,7 +267,7 @@ impl StackSpec { let helm_chart: helm::Chart = transfer_client .get(&helm_file, &Template::new(parameters).then(Yaml::new())) .await - .context(TransferSnafu)?; + .context(FileTransferSnafu)?; info!( "Installing Helm chart {} ({})", @@ -315,7 +315,7 @@ impl StackSpec { let manifests = transfer_client .get(&path_or_url, &Template::new(parameters)) .await - .context(TransferSnafu)?; + .context(FileTransferSnafu)?; let kube_client = k8s::Client::new().await.context(KubeClientCreateSnafu)?; diff --git a/rust/stackable-cockpit/src/platform/stacklet/grafana.rs b/rust/stackable-cockpit/src/platform/stacklet/grafana.rs index c1408010..e77eef8b 100644 --- a/rust/stackable-cockpit/src/platform/stacklet/grafana.rs +++ b/rust/stackable-cockpit/src/platform/stacklet/grafana.rs @@ -4,7 +4,7 @@ use snafu::ResultExt; use crate::{ platform::{ service::get_endpoint_urls, - stacklet::{Error, KubeClientFetchSnafu, ServiceSnafu, Stacklet}, + stacklet::{Error, KubeClientFetchSnafu, ServiceFetchSnafu, Stacklet}, }, utils::k8s::{Client, ListParamsExt, ProductLabel}, }; @@ -25,7 +25,7 @@ pub(super) async fn list( let service_name = service.name_any(); let endpoints = get_endpoint_urls(kube_client, &service, &service_name) .await - .context(ServiceSnafu)?; + .context(ServiceFetchSnafu)?; stacklets.push(Stacklet { conditions: Vec::new(), diff --git a/rust/stackable-cockpit/src/platform/stacklet/minio.rs b/rust/stackable-cockpit/src/platform/stacklet/minio.rs index 84e0dfa0..749fcc07 100644 --- a/rust/stackable-cockpit/src/platform/stacklet/minio.rs +++ b/rust/stackable-cockpit/src/platform/stacklet/minio.rs @@ -4,7 +4,7 @@ use snafu::ResultExt; use crate::{ platform::{ service::get_endpoint_urls, - stacklet::{Error, KubeClientFetchSnafu, ServiceSnafu, Stacklet}, + stacklet::{Error, KubeClientFetchSnafu, ServiceFetchSnafu, Stacklet}, }, utils::k8s::Client, }; @@ -30,7 +30,7 @@ pub(super) async fn list( let service_name = service.name_any(); let endpoints = get_endpoint_urls(kube_client, service, &service_name) .await - .context(ServiceSnafu)?; + .context(ServiceFetchSnafu)?; stacklets.push(Stacklet { product: "minio".to_string(), diff --git a/rust/stackable-cockpit/src/platform/stacklet/mod.rs b/rust/stackable-cockpit/src/platform/stacklet/mod.rs index f203495c..95c67547 100644 --- a/rust/stackable-cockpit/src/platform/stacklet/mod.rs +++ b/rust/stackable-cockpit/src/platform/stacklet/mod.rs @@ -46,19 +46,19 @@ pub struct Stacklet { #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("failed to create kubernetes client"))] - KubeClientCreateError { source: k8s::Error }, + KubeClientCreate { source: k8s::Error }, #[snafu(display("failed to fetch data from the kubernetes api"))] - KubeClientFetchError { source: k8s::Error }, + KubeClientFetch { source: k8s::Error }, #[snafu(display("no namespace set for custom resource '{crd_name}'"))] - CustomCrdNamespaceError { crd_name: String }, + CustomCrdNamespace { crd_name: String }, #[snafu(display("failed to deserialize cluster conditions from JSON"))] - DeserializeConditionsError { source: serde_json::Error }, + DeserializeConditions { source: serde_json::Error }, - #[snafu(display("service error"))] - ServiceError { source: service::Error }, + #[snafu(display("failed to receive service information"))] + ServiceFetch { source: service::Error }, } /// Lists all installed stacklets. If `namespace` is [`None`], stacklets from ALL @@ -102,8 +102,8 @@ pub async fn get_credentials_for_product( let credentials = match credentials::get(&kube_client, product_name, &product_cluster).await { Ok(credentials) => credentials, Err(credentials::Error::NoSecret) => None, - Err(credentials::Error::KubeClientFetchError { source }) => { - return Err(Error::KubeClientFetchError { source }) + Err(credentials::Error::KubeClientFetch { source }) => { + return Err(Error::KubeClientFetch { source }) } }; @@ -150,7 +150,7 @@ async fn list_stackable_stacklets( let endpoints = service::get_endpoints(kube_client, product_name, &object_name, &object_namespace) .await - .context(ServiceSnafu)?; + .context(ServiceFetchSnafu)?; stacklets.push(Stacklet { namespace: Some(object_namespace), diff --git a/rust/stackable-cockpit/src/platform/stacklet/opensearch.rs b/rust/stackable-cockpit/src/platform/stacklet/opensearch.rs index d866bc63..5a65ec49 100644 --- a/rust/stackable-cockpit/src/platform/stacklet/opensearch.rs +++ b/rust/stackable-cockpit/src/platform/stacklet/opensearch.rs @@ -4,7 +4,7 @@ use snafu::ResultExt; use crate::{ platform::{ service::get_endpoint_urls, - stacklet::{Error, KubeClientFetchSnafu, ServiceSnafu, Stacklet}, + stacklet::{Error, KubeClientFetchSnafu, ServiceFetchSnafu, Stacklet}, }, utils::k8s::{Client, ListParamsExt, ProductLabel}, }; @@ -25,7 +25,7 @@ pub(super) async fn list( let service_name = service.name_any(); let endpoints = get_endpoint_urls(kube_client, &service, &service_name) .await - .context(ServiceSnafu)?; + .context(ServiceFetchSnafu)?; // TODO: Add "Logs view" extra info from old stackablectl once "Extra info" field is supported. // see https://github.com/stackabletech/stackablectl/blob/eda45945cfcf5c6581cf1b88c782d98fada8065f/src/services/opensearch.rs#L41 diff --git a/rust/stackable-cockpit/src/platform/stacklet/prometheus.rs b/rust/stackable-cockpit/src/platform/stacklet/prometheus.rs index a0d3dcac..cd8a2560 100644 --- a/rust/stackable-cockpit/src/platform/stacklet/prometheus.rs +++ b/rust/stackable-cockpit/src/platform/stacklet/prometheus.rs @@ -4,7 +4,7 @@ use snafu::ResultExt; use crate::{ platform::{ service::get_endpoint_urls, - stacklet::{Error, KubeClientFetchSnafu, ServiceSnafu, Stacklet}, + stacklet::{Error, KubeClientFetchSnafu, ServiceFetchSnafu, Stacklet}, }, utils::k8s::Client, }; @@ -26,7 +26,7 @@ pub(super) async fn list( let service_name = service.name_any(); let endpoints = get_endpoint_urls(kube_client, &service, &service_name) .await - .context(ServiceSnafu)?; + .context(ServiceFetchSnafu)?; stacklets.push(Stacklet { product: "prometheus".to_string(), diff --git a/rust/stackable-cockpit/src/utils/k8s/client.rs b/rust/stackable-cockpit/src/utils/k8s/client.rs index 8e609f95..70c172ca 100644 --- a/rust/stackable-cockpit/src/utils/k8s/client.rs +++ b/rust/stackable-cockpit/src/utils/k8s/client.rs @@ -26,26 +26,32 @@ pub type Result = std::result::Result; #[derive(Debug, Snafu)] pub enum Error { - #[snafu(display("kubernetes error"))] - KubeError { source: kube::error::Error }, + #[snafu(display("failed to create kubernetes client"))] + KubeClientCreate { source: kube::error::Error }, + + #[snafu(display("failed to fetch data from kubernetes API"))] + KubeClientFetch { source: kube::error::Error }, + + #[snafu(display("failed to patch/create kubernetes object"))] + KubeClientPatch { source: kube::error::Error }, #[snafu(display("failed to deserialize YAML data"))] - DeserializeYamlError { source: serde_yaml::Error }, + DeserializeYaml { source: serde_yaml::Error }, #[snafu(display("failed to deploy manifest because type of object {object:?} is not set"))] - ObjectTypeError { object: DynamicObject }, + ObjectType { object: DynamicObject }, #[snafu(display("failed to deploy manifest because GVK {gvk:?} cannot be resolved"))] - DiscoveryError { gvk: GroupVersionKind }, + DiscoveryResolve { gvk: GroupVersionKind }, #[snafu(display("failed to convert byte string into UTF-8 string"))] - ByteStringConvertError { source: FromUtf8Error }, + ByteStringConvert { source: FromUtf8Error }, #[snafu(display("missing namespace for service '{service}'"))] MissingServiceNamespace { service: String }, #[snafu(display("failed to retrieve cluster information"))] - ClusterError { source: cluster::Error }, + ClusterInformation { source: cluster::Error }, #[snafu(display("invalid or empty secret data in '{secret_name}'"))] InvalidSecretData { secret_name: String }, @@ -66,11 +72,14 @@ impl Client { /// Tries to create a new default Kubernetes client and immediately runs /// a discovery. pub async fn new() -> Result { - let client = kube::Client::try_default().await.context(KubeSnafu)?; + let client = kube::Client::try_default() + .await + .context(KubeClientCreateSnafu)?; + let discovery = Discovery::new(client.clone()) .run() .await - .context(KubeSnafu)?; + .context(KubeClientFetchSnafu)?; Ok(Self { client, discovery }) } @@ -93,7 +102,7 @@ impl Client { let (resource, capabilities) = self .discovery .resolve_gvk(&gvk) - .ok_or(DiscoverySnafu { gvk }.build())?; + .ok_or(DiscoveryResolveSnafu { gvk }.build())?; let api: Api = match capabilities.scope { Scope::Cluster => { @@ -111,7 +120,7 @@ impl Client { &Patch::Apply(object), ) .await - .context(KubeSnafu)?; + .context(KubeClientPatchSnafu)?; } Ok(()) @@ -143,7 +152,7 @@ impl Client { let objects = object_api .list(&ListParams::default()) .await - .context(KubeSnafu)?; + .context(KubeClientFetchSnafu)?; Ok(Some(objects)) } @@ -162,7 +171,9 @@ impl Client { }; let api = Api::namespaced_with(self.client.clone(), namespace, &object_api_resource); - Ok(Some(api.get(object_name).await.context(KubeSnafu)?)) + Ok(Some( + api.get(object_name).await.context(KubeClientFetchSnafu)?, + )) } /// Lists [`Service`]s by matching labels. The services can be matched by @@ -179,7 +190,11 @@ impl Client { None => Api::all(self.client.clone()), }; - let services = service_api.list(list_params).await.context(KubeSnafu)?; + let services = service_api + .list(list_params) + .await + .context(KubeClientFetchSnafu)?; + Ok(services) } @@ -196,7 +211,10 @@ impl Client { ) -> Result { let secret_api: Api = Api::namespaced(self.client.clone(), secret_namespace); - let secret = secret_api.get(secret_name).await.context(KubeSnafu)?; + let secret = secret_api + .get(secret_name) + .await + .context(KubeClientFetchSnafu)?; let secret_name = secret.name_any(); let secret_data = secret.data.context(InvalidSecretDataSnafu { @@ -233,7 +251,10 @@ impl Client { None => Api::all(self.client.clone()), }; - let deployments = deployment_api.list(list_params).await.context(KubeSnafu)?; + let deployments = deployment_api + .list(list_params) + .await + .context(KubeClientFetchSnafu)?; Ok(deployments) } @@ -254,7 +275,7 @@ impl Client { let stateful_sets = stateful_set_api .list(list_params) .await - .context(KubeSnafu)?; + .context(KubeClientFetchSnafu)?; Ok(stateful_sets) } @@ -265,7 +286,7 @@ impl Client { let nodes = node_api .list(&ListParams::default()) .await - .context(KubeSnafu)?; + .context(KubeClientFetchSnafu)?; Ok(nodes) } @@ -274,7 +295,10 @@ impl Client { /// exist, this method returns [`None`]. pub async fn get_namespace(&self, name: &str) -> Result> { let namespace_api: Api = Api::all(self.client.clone()); - namespace_api.get_opt(name).await.context(KubeSnafu) + namespace_api + .get_opt(name) + .await + .context(KubeClientFetchSnafu) } /// Creates a [`Namespace`] with `name` in the cluster. This method will @@ -297,7 +321,7 @@ impl Client { }, ) .await - .context(KubeSnafu)?; + .context(KubeClientPatchSnafu)?; Ok(()) } @@ -317,12 +341,12 @@ impl Client { /// resources. These values don't reflect currently available resources. pub async fn get_cluster_info(&self) -> Result { let nodes = self.list_nodes().await?; - cluster::ClusterInfo::from_nodes(nodes).context(ClusterSnafu) + cluster::ClusterInfo::from_nodes(nodes).context(ClusterInformationSnafu) } pub async fn get_endpoints(&self, namespace: &str, name: &str) -> Result { let endpoints_api: Api = Api::namespaced(self.client.clone(), namespace); - endpoints_api.get(name).await.context(KubeSnafu) + endpoints_api.get(name).await.context(KubeClientFetchSnafu) } /// Extracts the [`GroupVersionKind`] from [`TypeMeta`]. diff --git a/rust/stackable-cockpit/src/utils/params.rs b/rust/stackable-cockpit/src/utils/params.rs index 112ca018..2fb70070 100644 --- a/rust/stackable-cockpit/src/utils/params.rs +++ b/rust/stackable-cockpit/src/utils/params.rs @@ -33,7 +33,7 @@ pub struct Parameter { #[derive(Debug, Snafu, PartialEq)] pub enum IntoParametersError { #[snafu(display("failed to parse raw parameter"))] - ParseError { source: RawParameterParseError }, + RawParse { source: RawParameterParseError }, #[snafu(display("invalid parameter '{parameter}', expected one of {expected}"))] InvalidParameter { parameter: String, expected: String }, @@ -47,7 +47,7 @@ pub trait IntoParameters: Sized + IntoRawParameters { where T: AsRef<[Parameter]>, { - let raw_parameters = self.into_raw_params().context(ParseSnafu)?; + let raw_parameters = self.into_raw_params().context(RawParseSnafu)?; let parameters = valid_parameters.as_ref(); let mut parameters: HashMap = parameters diff --git a/rust/stackable-cockpit/src/utils/path.rs b/rust/stackable-cockpit/src/utils/path.rs index 331f1538..f71493e5 100644 --- a/rust/stackable-cockpit/src/utils/path.rs +++ b/rust/stackable-cockpit/src/utils/path.rs @@ -12,7 +12,7 @@ pub enum PathOrUrl { #[derive(Debug, Snafu)] pub enum PathOrUrlParseError { #[snafu(display("failed to parse URL"))] - UrlParseError { source: ParseError }, + UrlParse { source: ParseError }, } pub trait IntoPathOrUrl: Sized { diff --git a/rust/stackable-cockpit/src/xfer/cache.rs b/rust/stackable-cockpit/src/xfer/cache.rs index 69f06621..b76cc681 100644 --- a/rust/stackable-cockpit/src/xfer/cache.rs +++ b/rust/stackable-cockpit/src/xfer/cache.rs @@ -20,14 +20,23 @@ pub type Result = std::result::Result; #[derive(Debug, Snafu)] pub enum Error { - #[snafu(display("filesystem io error"))] - CacheIoError { source: io::Error }, + #[snafu(display("failed to rereive filesystem metadata"))] + IoMetadata { source: io::Error }, + + #[snafu(display("failed to read from filesystem"))] + IoRead { source: io::Error }, + + #[snafu(display("failed to write to filesystem"))] + IoWrite { source: io::Error }, + + #[snafu(display("failed to delete file from filesystem"))] + IoDelete { source: io::Error }, #[snafu(display("system time error"))] - SystemTimeError { source: SystemTimeError }, + SystemTime { source: SystemTimeError }, #[snafu(display("failed to parse last auto-purge timestamp from file"))] - ParseIntError { source: ParseIntError }, + ParsePurgeTimestamp { source: ParseIntError }, #[snafu(display("tried to write file with disabled cache"))] WriteDisabled, @@ -66,9 +75,9 @@ impl Cache { let modified = file_path .metadata() - .context(CacheIoSnafu {})? + .context(IoMetadataSnafu)? .modified() - .context(CacheIoSnafu {})?; + .context(IoMetadataSnafu)?; let elapsed = modified.elapsed().context(SystemTimeSnafu {})?; @@ -104,17 +113,17 @@ impl Cache { Backend::Disk { base_path } => { let mut files = Vec::new(); - let mut entries = fs::read_dir(base_path).await.context(CacheIoSnafu)?; + let mut entries = fs::read_dir(base_path).await.context(IoReadSnafu)?; - while let Some(entry) = entries.next_entry().await.context(CacheIoSnafu)? { - let metadata = entry.metadata().await.context(CacheIoSnafu)?; + while let Some(entry) = entries.next_entry().await.context(IoReadSnafu)? { + let metadata = entry.metadata().await.context(IoMetadataSnafu)?; // Skip protected files if is_protected_file(entry.file_name()) { continue; } - files.push((entry.path(), metadata.modified().context(CacheIoSnafu)?)) + files.push((entry.path(), metadata.modified().context(IoMetadataSnafu)?)) } Ok(files) @@ -128,10 +137,10 @@ impl Cache { pub async fn purge(&self, delete_filter: DeleteFilter) -> Result<()> { match &self.backend { Backend::Disk { base_path } => { - let mut entries = fs::read_dir(base_path).await.context(CacheIoSnafu)?; + let mut entries = fs::read_dir(base_path).await.context(IoReadSnafu)?; - while let Some(entry) = entries.next_entry().await.context(CacheIoSnafu)? { - let metadata = entry.metadata().await.context(CacheIoSnafu)?; + while let Some(entry) = entries.next_entry().await.context(IoReadSnafu)? { + let metadata = entry.metadata().await.context(IoMetadataSnafu)?; let should_delete_file = match delete_filter { // Skip protected files @@ -143,7 +152,7 @@ impl Cache { DeleteFilter::OnlyExpired => { metadata .modified() - .context(CacheIoSnafu)? + .context(IoMetadataSnafu)? .elapsed() .context(SystemTimeSnafu)? > self.max_age @@ -151,7 +160,7 @@ impl Cache { }; if should_delete_file { - fs::remove_file(entry.path()).await.context(CacheIoSnafu)?; + fs::remove_file(entry.path()).await.context(IoDeleteSnafu)?; } } @@ -168,11 +177,12 @@ impl Cache { // Read and covert timestamp let last_purged_at = match fs::read_to_string(&cache_auto_purge_filepath).await { - Ok(timestamp) => Some( - UNIX_EPOCH + Duration::from_secs(timestamp.parse().context(ParseIntSnafu)?), - ), + Ok(timestamp) => { + let ts = timestamp.parse().context(ParsePurgeTimestampSnafu)?; + Some(UNIX_EPOCH + Duration::from_secs(ts)) + } Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, - Err(err) => return Err(err).context(CacheIoSnafu), + Err(err) => return Err(err).context(IoReadSnafu), }; // If the auto purge interval elapsed, run purge and write @@ -202,13 +212,13 @@ impl Cache { } async fn read(file_path: PathBuf) -> Result { - fs::read_to_string(file_path).await.context(CacheIoSnafu {}) + fs::read_to_string(file_path).await.context(IoReadSnafu) } async fn write(file_path: PathBuf, file_content: &str) -> Result<()> { fs::write(file_path, file_content) .await - .context(CacheIoSnafu {}) + .context(IoWriteSnafu {}) } fn file_path(base_path: &Path, file_url: &Url) -> PathBuf { @@ -266,7 +276,7 @@ impl Settings { pub async fn try_into_cache(self) -> Result { match &self.backend { Backend::Disk { base_path } => { - fs::create_dir_all(base_path).await.context(CacheIoSnafu)?; + fs::create_dir_all(base_path).await.context(IoWriteSnafu)?; Ok(Cache::new( self.backend, @@ -305,7 +315,7 @@ async fn write_cache_auto_purge_file(path: &Path) -> Result<()> { .as_bytes(), ) .await - .context(CacheIoSnafu) + .context(IoWriteSnafu) } fn is_protected_file(filename: OsString) -> bool { diff --git a/rust/stackable-cockpit/src/xfer/processor.rs b/rust/stackable-cockpit/src/xfer/processor.rs index 02e68ff0..e6b0252e 100644 --- a/rust/stackable-cockpit/src/xfer/processor.rs +++ b/rust/stackable-cockpit/src/xfer/processor.rs @@ -10,10 +10,10 @@ pub type Result = std::result::Result; #[derive(Debug, Snafu)] pub enum ProcessorError { #[snafu(display("failed to deserialize YAML content"))] - DeserializeYamlError { source: serde_yaml::Error }, + DeserializeYaml { source: serde_yaml::Error }, #[snafu(display("failed to render templated content"))] - TemplatingError { source: tera::Error }, + RenderTemplate { source: tera::Error }, } pub trait Processor: Sized { @@ -96,7 +96,7 @@ impl<'a> Processor for Template<'a> { type Output = String; fn process(&self, input: Self::Input) -> Result { - templating::render(&input, self.0).context(TemplatingSnafu) + templating::render(&input, self.0).context(RenderTemplateSnafu) } } diff --git a/rust/stackablectl/src/args/cluster.rs b/rust/stackablectl/src/args/cluster.rs index 66c1fb22..aa332ef5 100644 --- a/rust/stackablectl/src/args/cluster.rs +++ b/rust/stackablectl/src/args/cluster.rs @@ -9,10 +9,10 @@ use stackable_cockpit::{ #[derive(Debug, Snafu)] pub enum CommonClusterArgsError { #[snafu(display("failed to create kind cluster"))] - KindClusterError { source: kind::Error }, + KindClusterCreate { source: kind::Error }, #[snafu(display("minikube cluster error"))] - MinikubeClusterError { source: minikube::Error }, + MinikubeClusterCreate { source: minikube::Error }, #[snafu(display( "invalid total node count - at least two nodes in total are needed to run a local cluster" @@ -92,7 +92,7 @@ impl CommonClusterArgs { kind_cluster .create_if_not_exists() .await - .context(KindClusterSnafu) + .context(KindClusterCreateSnafu) } ClusterType::Minikube => { let minikube_cluster = minikube::Cluster::new(self.cluster_nodes, name); @@ -100,7 +100,7 @@ impl CommonClusterArgs { minikube_cluster .create_if_not_exists() .await - .context(MinikubeClusterSnafu) + .context(MinikubeClusterCreateSnafu) } } } diff --git a/rust/stackablectl/src/cmds/cache.rs b/rust/stackablectl/src/cmds/cache.rs index b345555f..3827d449 100644 --- a/rust/stackablectl/src/cmds/cache.rs +++ b/rust/stackablectl/src/cmds/cache.rs @@ -34,8 +34,11 @@ pub struct CacheCleanArgs { #[derive(Debug, Snafu)] pub enum CmdError { - #[snafu(display("failed to read from cache"))] - CacheError { source: cache::Error }, + #[snafu(display("failed to list cached files"))] + ListCachedFiles { source: cache::Error }, + + #[snafu(display("failed to purge cached files"))] + PurgeCachedFiles { source: cache::Error }, } impl CacheArgs { @@ -51,7 +54,7 @@ impl CacheArgs { async fn list_cmd(cache: Cache, cli: &Cli) -> Result { info!("Listing cached files"); - let files = cache.list().await.context(CacheSnafu)?; + let files = cache.list().await.context(ListCachedFilesSnafu)?; if files.is_empty() { return Ok("No cached files".into()); @@ -93,6 +96,10 @@ async fn clean_cmd(args: &CacheCleanArgs, cache: Cache) -> Result Result { let mut buf = Vec::new(); generate(shell, &mut cmd, "stackablectl", &mut buf); - String::from_utf8(buf).context(StringSnafu) + String::from_utf8(buf).context(StringConvertSnafu) } diff --git a/rust/stackablectl/src/cmds/demo.rs b/rust/stackablectl/src/cmds/demo.rs index 90c25047..9e02e3b3 100644 --- a/rust/stackablectl/src/cmds/demo.rs +++ b/rust/stackablectl/src/cmds/demo.rs @@ -11,7 +11,7 @@ use stackable_cockpit::{ constants::{DEFAULT_OPERATOR_NAMESPACE, DEFAULT_PRODUCT_NAMESPACE}, platform::{demo, namespace, release, stack}, utils::path::PathOrUrlParseError, - xfer::{cache::Cache, Client, Error}, + xfer::{cache::Cache, Client}, }; use crate::{ @@ -107,11 +107,11 @@ pub struct DemoUninstallArgs {} #[derive(Debug, Snafu)] pub enum CmdError { - #[snafu(display("unable to format YAML output"))] - YamlOutputFormatError { source: serde_yaml::Error }, + #[snafu(display("failed to serialize YAML output"))] + SerializeYamlOutput { source: serde_yaml::Error }, - #[snafu(display("unable to format JSON output"))] - JsonOutputFormatError { source: serde_json::Error }, + #[snafu(display("failed to serialize JSON output"))] + SerializeJsonOutput { source: serde_json::Error }, #[snafu(display("no demo with name '{name}'"))] NoSuchDemo { name: String }, @@ -119,23 +119,20 @@ pub enum CmdError { #[snafu(display("no stack with name '{name}'"))] NoSuchStack { name: String }, - #[snafu(display("list error"))] - ListError { source: list::Error }, + #[snafu(display("failed to build demo/stack/release list"))] + BuildList { source: list::Error }, - #[snafu(display("demo error"))] - DemoError { source: demo::Error }, + #[snafu(display("failed to install demo"))] + DemoInstall { source: demo::Error }, #[snafu(display("path/url parse error"))] - PathOrUrlParseError { source: PathOrUrlParseError }, + PathOrUrlParse { source: PathOrUrlParseError }, #[snafu(display("cluster argument error"))] - CommonClusterArgsError { source: CommonClusterArgsError }, - - #[snafu(display("file transfer error"))] - TransferError { source: Error }, + CommonClusterArgs { source: CommonClusterArgsError }, #[snafu(display("failed to create namespace '{namespace}'"))] - NamespaceError { + NamespaceCreate { source: namespace::Error, namespace: String, }, @@ -154,7 +151,7 @@ impl DemoArgs { let list = demo::List::build(&files, &transfer_client) .await - .context(ListSnafu)?; + .context(BuildListSnafu)?; match &self.subcommand { DemoCommands::List(args) => list_cmd(args, cli, list).await, @@ -203,8 +200,8 @@ async fn list_cmd(args: &DemoListArgs, cli: &Cli, list: demo::List) -> Result serde_json::to_string(&list.inner()).context(JsonOutputFormatSnafu), - OutputType::Yaml => serde_yaml::to_string(&list.inner()).context(YamlOutputFormatSnafu), + OutputType::Json => serde_json::to_string(&list.inner()).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&list.inner()).context(SerializeYamlOutputSnafu), } } @@ -250,8 +247,8 @@ async fn describe_cmd( Ok(result.render()) } - OutputType::Json => serde_json::to_string(&demo).context(JsonOutputFormatSnafu), - OutputType::Yaml => serde_yaml::to_string(&demo).context(YamlOutputFormatSnafu), + OutputType::Json => serde_json::to_string(&demo).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&demo).context(SerializeYamlOutputSnafu), } } @@ -276,13 +273,13 @@ async fn install_cmd( let files = cli.get_stack_files().context(PathOrUrlParseSnafu)?; let stack_list = stack::List::build(&files, transfer_client) .await - .context(ListSnafu)?; + .context(BuildListSnafu)?; let files = cli.get_release_files().context(PathOrUrlParseSnafu)?; let release_list = release::List::build(&files, transfer_client) .await - .context(ListSnafu)?; + .context(BuildListSnafu)?; // Install local cluster if needed args.local_cluster @@ -305,14 +302,14 @@ async fn install_cmd( if !args.skip_release { namespace::create_if_needed(operator_namespace.clone()) .await - .context(NamespaceSnafu { + .context(NamespaceCreateSnafu { namespace: operator_namespace.clone(), })?; } namespace::create_if_needed(product_namespace.clone()) .await - .context(NamespaceSnafu { + .context(NamespaceCreateSnafu { namespace: product_namespace.clone(), })?; @@ -328,7 +325,7 @@ async fn install_cmd( args.skip_release, ) .await - .context(DemoSnafu)?; + .context(DemoInstallSnafu)?; let operator_cmd = format!( "stackablectl operator installed{}", diff --git a/rust/stackablectl/src/cmds/operator.rs b/rust/stackablectl/src/cmds/operator.rs index 3ac388b0..5d9ea575 100644 --- a/rust/stackablectl/src/cmds/operator.rs +++ b/rust/stackablectl/src/cmds/operator.rs @@ -120,29 +120,26 @@ pub struct OperatorInstalledArgs { #[derive(Debug, Snafu)] pub enum CmdError { - #[snafu(display("invalid repo name"))] - InvalidRepoNameError { source: InvalidRepoNameError }, + #[snafu(display("invalid repository name"))] + InvalidRepoName { source: InvalidRepoNameError }, - #[snafu(display("unknown repo name: {name}"))] - UnknownRepoNameError { name: String }, + #[snafu(display("unknown repository name '{name}'"))] + UnknownRepoName { name: String }, #[snafu(display("Helm error"))] HelmError { source: helm::Error }, #[snafu(display("cluster argument error"))] - CommonClusterArgsError { source: CommonClusterArgsError }, + CommonClusterArgs { source: CommonClusterArgsError }, - #[snafu(display("semver parse error"))] - SemVerParseError { source: semver::Error }, + #[snafu(display("failed to serialize YAML output"))] + SerializeYamlOutput { source: serde_yaml::Error }, - #[snafu(display("unable to format YAML output"))] - YamlOutputFormatError { source: serde_yaml::Error }, - - #[snafu(display("unable to format JSON output"))] - JsonOutputFormatError { source: serde_json::Error }, + #[snafu(display("failed to serialize JSON output"))] + SerializeJsonOutput { source: serde_json::Error }, #[snafu(display("failed to create namespace '{namespace}'"))] - NamespaceError { + NamespaceCreate { source: namespace::Error, namespace: String, }, @@ -213,12 +210,8 @@ async fn list_cmd(args: &OperatorListArgs, cli: &Cli) -> Result { - Ok(serde_json::to_string(&versions_list).context(JsonOutputFormatSnafu)?) - } - OutputType::Yaml => { - Ok(serde_yaml::to_string(&versions_list).context(YamlOutputFormatSnafu)?) - } + OutputType::Json => serde_json::to_string(&versions_list).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&versions_list).context(SerializeYamlOutputSnafu), } } @@ -270,8 +263,8 @@ async fn describe_cmd(args: &OperatorDescribeArgs, cli: &Cli) -> Result serde_json::to_string(&versions_list).context(JsonOutputFormatSnafu), - OutputType::Yaml => serde_yaml::to_string(&versions_list).context(YamlOutputFormatSnafu), + OutputType::Json => serde_json::to_string(&versions_list).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&versions_list).context(SerializeYamlOutputSnafu), } } @@ -286,17 +279,16 @@ async fn install_cmd(args: &OperatorInstallArgs, cli: &Cli) -> Result println!("Installed {} operator", operator), - Err(err) => { - return Err(CmdError::HelmError { source: err }); - } - }; + operator + .install(&args.operator_namespace) + .context(HelmSnafu)?; + + println!("Installed {} operator", operator); } let mut result = cli.result(); @@ -410,8 +402,8 @@ fn installed_cmd(args: &OperatorInstalledArgs, cli: &Cli) -> Result Ok(serde_json::to_string(&installed).context(JsonOutputFormatSnafu)?), - OutputType::Yaml => Ok(serde_yaml::to_string(&installed).context(YamlOutputFormatSnafu)?), + OutputType::Json => serde_json::to_string(&installed).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&installed).context(SerializeYamlOutputSnafu), } } diff --git a/rust/stackablectl/src/cmds/release.rs b/rust/stackablectl/src/cmds/release.rs index 808251b8..2c62bfa2 100644 --- a/rust/stackablectl/src/cmds/release.rs +++ b/rust/stackablectl/src/cmds/release.rs @@ -11,7 +11,7 @@ use stackable_cockpit::{ constants::DEFAULT_OPERATOR_NAMESPACE, platform::{namespace, release}, utils::path::PathOrUrlParseError, - xfer::{cache::Cache, Client, Error}, + xfer::{cache::Cache, Client}, }; use crate::{ @@ -94,32 +94,29 @@ pub struct ReleaseUninstallArgs { #[derive(Debug, Snafu)] pub enum CmdError { - #[snafu(display("unable to format YAML output"))] - YamlOutputFormatError { source: serde_yaml::Error }, + #[snafu(display("failed to serialize YAML output"))] + SerializeYamlOutput { source: serde_yaml::Error }, - #[snafu(display("unable to format JSON output"))] - JsonOutputFormatError { source: serde_json::Error }, + #[snafu(display("failed to serialize JSON output"))] + SerializeJsonOutput { source: serde_json::Error }, - #[snafu(display("path/url parse error"))] - PathOrUrlParseError { source: PathOrUrlParseError }, + #[snafu(display("failed to parse path/url"))] + PathOrUrlParse { source: PathOrUrlParseError }, - #[snafu(display("list error"))] - ListError { source: list::Error }, + #[snafu(display("failed to build release list"))] + BuildList { source: list::Error }, - #[snafu(display("release install error"))] - ReleaseInstallError { source: release::Error }, + #[snafu(display("failed to install release"))] + ReleaseInstall { source: release::Error }, - #[snafu(display("release uninstall error"))] - ReleaseUninstallError { source: release::Error }, + #[snafu(display("failed to uninstall release"))] + ReleaseUninstall { source: release::Error }, #[snafu(display("cluster argument error"))] - CommonClusterArgsError { source: CommonClusterArgsError }, - - #[snafu(display("transfer error"))] - TransferError { source: Error }, + CommonClusterArgs { source: CommonClusterArgsError }, #[snafu(display("failed to create namespace '{namespace}'"))] - NamespaceError { + NamespaceCreate { source: namespace::Error, namespace: String, }, @@ -130,12 +127,10 @@ impl ReleaseArgs { debug!("Handle release args"); let transfer_client = Client::new_with(cache); - let files = cli.get_release_files().context(PathOrUrlParseSnafu)?; - let release_list = release::List::build(&files, &transfer_client) .await - .context(ListSnafu)?; + .context(BuildListSnafu)?; if release_list.inner().is_empty() { return Ok("No releases".into()); @@ -195,8 +190,8 @@ async fn list_cmd( Ok(result.render()) } - OutputType::Json => serde_json::to_string(&release_list).context(JsonOutputFormatSnafu), - OutputType::Yaml => serde_yaml::to_string(&release_list).context(YamlOutputFormatSnafu), + OutputType::Json => serde_json::to_string(&release_list).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&release_list).context(SerializeYamlOutputSnafu), } } @@ -249,8 +244,8 @@ async fn describe_cmd( Ok(result.render()) } - OutputType::Json => serde_json::to_string(&release).context(JsonOutputFormatSnafu), - OutputType::Yaml => serde_yaml::to_string(&release).context(YamlOutputFormatSnafu), + OutputType::Json => serde_json::to_string(&release).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&release).context(SerializeYamlOutputSnafu), }, None => Ok("No such release".into()), } @@ -277,7 +272,7 @@ async fn install_cmd( // Create operator namespace if needed namespace::create_if_needed(args.operator_namespace.clone()) .await - .context(NamespaceSnafu { + .context(NamespaceCreateSnafu { namespace: args.operator_namespace.clone(), })?; diff --git a/rust/stackablectl/src/cmds/stack.rs b/rust/stackablectl/src/cmds/stack.rs index b4286d9b..ee59b852 100644 --- a/rust/stackablectl/src/cmds/stack.rs +++ b/rust/stackablectl/src/cmds/stack.rs @@ -11,7 +11,7 @@ use stackable_cockpit::{ constants::{DEFAULT_OPERATOR_NAMESPACE, DEFAULT_PRODUCT_NAMESPACE}, platform::{namespace, release, stack}, utils::path::PathOrUrlParseError, - xfer::{cache::Cache, Client, Error}, + xfer::{cache::Cache, Client}, }; use crate::{ @@ -101,28 +101,25 @@ Use \"stackablectl stack describe \" to list available parameters for eac #[derive(Debug, Snafu)] pub enum CmdError { #[snafu(display("path/url parse error"))] - PathOrUrlParseError { source: PathOrUrlParseError }, + PathOrUrlParse { source: PathOrUrlParseError }, - #[snafu(display("unable to format YAML output"))] - YamlOutputFormatError { source: serde_yaml::Error }, + #[snafu(display("failed to serialize YAML output"))] + SerializeYamlOutput { source: serde_yaml::Error }, - #[snafu(display("unable to format JSON output"))] - JsonOutputFormatError { source: serde_json::Error }, + #[snafu(display("failed to serialize JSON output"))] + SerializeJsonOutput { source: serde_json::Error }, - #[snafu(display("stack error"))] - StackError { source: stack::Error }, + #[snafu(display("failed to install stack"))] + StackInstall { source: stack::Error }, - #[snafu(display("list error"))] - ListError { source: list::Error }, + #[snafu(display("failed to build stack/release list"))] + BuildList { source: list::Error }, #[snafu(display("cluster argument error"))] - CommonClusterArgsError { source: CommonClusterArgsError }, - - #[snafu(display("transfer error"))] - TransferError { source: Error }, + CommonClusterArgs { source: CommonClusterArgsError }, #[snafu(display("failed to create namespace '{namespace}'"))] - NamespaceError { + NamespaceCreate { source: namespace::Error, namespace: String, }, @@ -134,10 +131,9 @@ impl StackArgs { let transfer_client = Client::new_with(cache); let files = cli.get_stack_files().context(PathOrUrlParseSnafu)?; - let stack_list = stack::List::build(&files, &transfer_client) .await - .context(ListSnafu)?; + .context(BuildListSnafu)?; match &self.subcommand { StackCommands::List(args) => list_cmd(args, cli, stack_list), @@ -186,8 +182,8 @@ fn list_cmd(args: &StackListArgs, cli: &Cli, stack_list: stack::List) -> Result< Ok(result.render()) } - OutputType::Json => serde_json::to_string(&stack_list).context(JsonOutputFormatSnafu {}), - OutputType::Yaml => serde_yaml::to_string(&stack_list).context(YamlOutputFormatSnafu {}), + OutputType::Json => serde_json::to_string(&stack_list).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&stack_list).context(SerializeYamlOutputSnafu), } } @@ -241,8 +237,8 @@ fn describe_cmd( Ok(result.render()) } - OutputType::Json => serde_json::to_string(&stack).context(JsonOutputFormatSnafu {}), - OutputType::Yaml => serde_yaml::to_string(&stack).context(YamlOutputFormatSnafu {}), + OutputType::Json => serde_json::to_string(&stack).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&stack).context(SerializeYamlOutputSnafu), }, None => Ok("No such stack".into()), } @@ -258,10 +254,9 @@ async fn install_cmd( info!("Installing stack {}", args.stack_name); let files = cli.get_release_files().context(PathOrUrlParseSnafu)?; - let release_list = release::List::build(&files, transfer_client) .await - .context(ListSnafu)?; + .context(BuildListSnafu)?; let product_namespace = args .namespaces @@ -289,20 +284,20 @@ async fn install_cmd( stack_spec .check_prerequisites(&product_namespace) .await - .context(StackSnafu)?; + .context(StackInstallSnafu)?; // Install release if not opted out if !args.skip_release { namespace::create_if_needed(operator_namespace.clone()) .await - .context(NamespaceSnafu { + .context(NamespaceCreateSnafu { namespace: operator_namespace.clone(), })?; stack_spec .install_release(release_list, &operator_namespace, &product_namespace) .await - .context(StackSnafu)?; + .context(StackInstallSnafu)?; } else { info!("Skipping release installation during stack installation process"); } @@ -310,7 +305,7 @@ async fn install_cmd( // Create product namespace if needed namespace::create_if_needed(product_namespace.clone()) .await - .context(NamespaceSnafu { + .context(NamespaceCreateSnafu { namespace: product_namespace.clone(), })?; @@ -322,7 +317,7 @@ async fn install_cmd( transfer_client, ) .await - .context(StackSnafu)?; + .context(StackInstallSnafu)?; let operator_cmd = format!( "stackablectl operator installed{}", diff --git a/rust/stackablectl/src/cmds/stacklet.rs b/rust/stackablectl/src/cmds/stacklet.rs index 3f80c8af..7f71ec97 100644 --- a/rust/stackablectl/src/cmds/stacklet.rs +++ b/rust/stackablectl/src/cmds/stacklet.rs @@ -8,7 +8,7 @@ use tracing::{info, instrument}; use stackable_cockpit::{ constants::DEFAULT_PRODUCT_NAMESPACE, - platform::stacklet::{get_credentials_for_product, list_stacklets, Error}, + platform::stacklet::{self, get_credentials_for_product, list_stacklets}, utils::k8s::DisplayCondition, }; @@ -66,16 +66,16 @@ pub struct StackletListArgs { #[derive(Debug, Snafu)] pub enum CmdError { #[snafu(display("failed to list stacklets"))] - StackletListError { source: Error }, + StackletList { source: stacklet::Error }, #[snafu(display("failed to retrieve credentials for stacklet"))] - StackletCredentialsError { source: Error }, + StackletCredentials { source: stacklet::Error }, - #[snafu(display("unable to format YAML output"))] - YamlOutputFormatError { source: serde_yaml::Error }, + #[snafu(display("failed to serialize YAML output"))] + SerializeYamlOutput { source: serde_yaml::Error }, - #[snafu(display("unable to format JSON output"))] - JsonOutputFormatError { source: serde_json::Error }, + #[snafu(display("failed to serialize JSON output"))] + SerializeJsonOutput { source: serde_json::Error }, } impl StackletArgs { @@ -185,8 +185,8 @@ async fn list_cmd(args: &StackletListArgs, cli: &Cli) -> Result serde_json::to_string(&stacklets).context(JsonOutputFormatSnafu), - OutputType::Yaml => serde_yaml::to_string(&stacklets).context(YamlOutputFormatSnafu), + OutputType::Json => serde_json::to_string(&stacklets).context(SerializeJsonOutputSnafu), + OutputType::Yaml => serde_yaml::to_string(&stacklets).context(SerializeYamlOutputSnafu), } } diff --git a/rust/stackablectl/src/output/mod.rs b/rust/stackablectl/src/output/mod.rs index 6c9790d1..528f628b 100644 --- a/rust/stackablectl/src/output/mod.rs +++ b/rust/stackablectl/src/output/mod.rs @@ -19,10 +19,7 @@ pub type Result = std::result::Result; #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("failed to create output renderer"))] - CreationError { source: tera::Error }, - - #[snafu(display("failed to render console output"))] - RenderError { source: tera::Error }, + CreateRenderer { source: tera::Error }, } #[derive(Debug)] @@ -123,7 +120,7 @@ where ("result", include_str!("templates/result.tpl")), ("error", include_str!("templates/error.tpl")), ]) - .context(CreationSnafu)?; + .context(CreateRendererSnafu)?; Ok(renderer) }