如何使用 Rust 编辑 Kubernetes 机密?

问题描述 投票:0回答:1

我想更新一个秘密。它有一个

data
字段,其值需要更新。在 Rust 中,我可以使用 API
create
delete
,但没有
update
edit

但是,我可以使用

kubectl edit
命令来编辑现有秘密。

async fn create_k8s_secret(secrets: &Api<Secret>, secret: &Secret) -> bool {
    let secret_name = secret.metadata.name.as_ref().unwrap().clone();
    match secrets.create(&PostParams::default(), &secret).await {
        Ok(_) => {
            debug!("Successfully created secret: {}", secret_name);
            true
        }
        Err(kube::Error::Api(ErrorResponse { code, reason, .. }))
            if code == 409 && reason == "AlreadyExists" =>
        {
            debug!("Secret {} already exists. Ignoring...", secret_name);
            true
        }
        Err(e) => {
            error!("Error creating secret {}: {}", secret_name, e);
            false
        }
    }
}

async fn delete_k8s_secret(secrets: &Api<Secret>, secret: &Secret) -> bool {
    let secret_name = secret.metadata.name.as_ref().unwrap().clone();
    let delete_options = kube::api::DeleteParams::default();
    match secrets.delete(&secret_name, &delete_options).await {
        Ok(_) => {
            debug!("Successfully deleted the secret: {}", secret_name);
            true
        }
        Err(kube::Error::Api(ErrorResponse { code, reason, .. }))
            if code == 404 && reason == "NotFound" =>
        {
            debug!("Secret {} does not exist. Ignoring...", secret_name);
            true
        }
        Err(e) => {
            error!("Error deleting secret {}: {}", secret_name, e);
            false
        }
    }
}

我可以以编程方式执行的唯一方法是首先删除秘密,然后创建一个新的。

使用 Rust 在 Kubernetes 中编辑现有

secret
的最优化、最安全的方法是什么?

kubernetes rust kubectl
1个回答
0
投票

您应该能够使用

patch
方法就地更新您的秘密(无需删除/重新创建):

use k8s_openapi::api::core::v1::Secret;
use kube::{
    api::{Api, Patch, PatchParams},
    Client, Error,
};
use std::collections::HashMap;

async fn update_k8s_secret(
    secrets: &Api<Secret>,
    secret_namespace: String,
    secret_name: String,
    secret_data: HashMap<String, String>,
) -> bool {
    let patch_data = generate_patch_json(
        secret_namespace.clone(),
        secret_name.clone(),
        secret_data.clone(),
    );
    let patch = Patch::Apply(patch_data);
    let params = PatchParams::apply("kube");

    match secrets.patch(&secret_name, &params, &patch).await {
        Ok(_) => {
            println!("Successfully updated the secret: {}", secret_name);
            true
        }
        Err(e) => {
            println!("Error updating secret {}: {}", secret_name, e);
            false
        }
    }
}

例如,要更新

mysecret
命名空间中的秘密
default
内的数据:

let client = Client::try_default().await?;
let secrets: Api<Secret> = Api::default_namespaced(client);

let secret_namespace = "default".to_string();
let secret_name = "mysecret".to_string();
let secret_data = HashMap::from([
    ("key1".to_string(), "value1".to_string()),
    ("key2".to_string(), "value2".to_string()),
]);

let updated = update_k8s_secret(&secrets, secret_namespace, secret_name, secret_data).await;
println!("Updated: {}", updated);

generate_patch_json
中使用的
update_k8s_secret
方法旨在将秘密命名空间、名称和数据转换为可由
patch
方法使用的JSON对象。例如:

let secret_namespace = "default".to_string();
let secret_name = "mysecret".to_string();
let secret_data = HashMap::from([
    ("key1".to_string(), "value1".to_string()),
    ("key2".to_string(), "value2".to_string()),
]);
generate_patch_json(secret_namespace, secret_name, secret_data);

应该返回:

{
    "apiVersion": "v1",
    "kind": "Secret",
    "metadata": {
        "namespace": "default",
        "name": "mysecret",
    },
    "stringData": {
        "key1": "value1",
        "key2": "value2"
    }
}

我还远不是 Rust 专家/用户,所以请耐心等待,但我仍然会将我的实现放在这里。它可能不是最佳的,也不使用最佳实践,但是嘿,这可行!

fn generate_patch_json(
    secret_namespace: String,
    secret_name: String,
    secret_data: HashMap<String, String>,
) -> serde_json::Map<String, serde_json::Value> {
    let mut secret_data_map = serde_json::Map::new();
    for (key, value) in secret_data {
        secret_data_map.insert(key, value.into());
    }

    let mut metadata_map = serde_json::Map::new();
    metadata_map.insert("namespace".to_string(), secret_namespace.into());
    metadata_map.insert("name".to_string(), secret_name.clone().into());

    let mut patch_data = serde_json::Map::new();
    patch_data.insert("apiVersion".to_string(), "v1".into());
    patch_data.insert("kind".to_string(), "Secret".into());
    patch_data.insert(
        "metadata".to_string(),
        serde_json::Value::Object(metadata_map),
    );
    patch_data.insert(
        "stringData".to_string(),
        serde_json::Value::Object(secret_data_map),
    );

    patch_data
}
© www.soinside.com 2019 - 2024. All rights reserved.