Skip to main content

rkubectl_app/cli/command/basic/
create.rs

1use super::*;
2
3use rkubectl_ui::Created;
4
5use clusterrole::CreateClusterRole;
6use namespace::CreateNamespace;
7use secret::CreateSecret;
8
9mod clusterrole;
10mod namespace;
11mod secret;
12
13/// Create a resource from a file or from stdin.
14///
15///  JSON and YAML formats are accepted.
16///
17/// Examples:
18///   # Create a pod using the data in pod.json
19///   kubectl create -f ./pod.json
20///
21///   # Create a pod based on the JSON passed into stdin
22///   cat pod.json | kubectl create -f -
23///
24///   # Edit the data in registry.yaml in JSON then create the resource using the edited data
25///   kubectl create -f registry.yaml --edit -o json
26
27#[derive(Clone, Debug, Args)]
28#[command(arg_required_else_help(true), subcommand_negates_reqs(true))]
29pub struct Create {
30    /// If client strategy, only print the object that would be sent, without sending it.
31    /// If server strategy, submit server-side request without persisting the resource.
32    #[arg(
33        long,
34        value_enum,
35        default_value_t = DryRun::None,
36        // value_parser = PossibleValuesParser::new(["none", "server", "client"]),
37    )]
38    dry_run: DryRun,
39
40    /// Edit the API resource before creating
41    #[arg(long)]
42    edit: bool,
43
44    /// Name of the manager used to track field ownership.
45    #[arg(long, default_value = "kubectl-create")]
46    field_manager: String,
47
48    /// Filename, directory, or URL to files to use to create the resource
49    #[arg(short, long, required = true)]
50    filename: Option<String>,
51
52    /// Process the directory used in -f, --filename recursively.
53    /// Useful when you want to manage related manifests organized within the same directory.
54    #[arg(long, short = 'R', requires = "filename")]
55    recursive: bool,
56
57    /// If true, the configuration of current object will be saved in its annotation.
58    /// Otherwise, the annotation will be unchanged.
59    /// This flag is useful when you want to perform kubectl apply on this object in the future.
60    #[arg(long)]
61    save_config: bool,
62
63    /// If true, keep the managedFields when printing objects in JSON or YAML format.
64    #[arg(long)]
65    show_managed_fields: bool,
66
67    #[command(subcommand)]
68    command: Option<CreateResource>,
69}
70
71#[derive(Clone, Debug, Subcommand)]
72#[command(rename_all = "lowercase")]
73pub enum CreateResource {
74    /// Create a cluster role
75    ClusterRole(CreateClusterRole),
76    /// Create a cluster role binding for a particular cluster role
77    ClusterRoleBinding,
78    /// Create a config map from a local file, directory or literal value
79    ConfigMap,
80    /// Create a cron job with the specified name
81    CronJob,
82    /// Create a deployment with the specified name
83    Deployment,
84    /// Create an ingress with the specified name
85    Ingress,
86    /// Create a job with the specified name
87    Job,
88    /// Create a namespace with the specified name
89    #[command(visible_alias = "ns")]
90    Namespace(CreateNamespace),
91    /// Create a pod disruption budget with the specified name
92    PodDisruptionBudget,
93    /// Create a priority class with the specified name
94    PriorityClass,
95    /// Create a quota with the specified name
96    Quota,
97    /// Create a role with single rule
98    Role,
99    /// Create a role binding for a particular role or cluster role
100    RoleBinding,
101    /// Create a secret using a specified subcommand
102    #[command(subcommand)]
103    Secret(CreateSecret),
104    /// Create a service using a specified subcommand
105    Service,
106    /// Create a service account with the specified name
107    ServiceAccount,
108    /// Request a service account token
109    Token,
110}
111
112impl Create {
113    pub async fn exec(self, context: &Context) -> RkResult<()> {
114        let kubeapi = context.kubeapi();
115        let created = if let Some(filename) = &self.filename {
116            self.create_from_file(filename, kubeapi).await
117        } else {
118            self.create_resource(kubeapi).await
119        }?;
120
121        let namespace = kubeapi.show_namespace();
122        let params = self.params();
123        let output = context.output_deprecated();
124        println!("{}", created.output(namespace, params, output));
125        Ok(())
126    }
127
128    async fn create_from_file(&self, filename: &str, kubeapi: &Kubeapi) -> RkResult<Box<dyn Show>> {
129        let pp = kubeapi.post_params_with_manager(&self.field_manager);
130        println!("Creating from {filename} [{pp:?}]");
131        Err(RkError::todo())
132    }
133
134    async fn create_resource(&self, kubeapi: &Kubeapi) -> RkResult<Box<dyn Show>> {
135        if let Some(command) = &self.command {
136            let pp = kubeapi.post_params_with_manager(&self.field_manager);
137            command.exec(kubeapi, &pp).await
138        } else {
139            unreachable!()
140        }
141    }
142
143    fn params(&self) -> ShowParams {
144        ShowParams {
145            show_managed_fields: self.show_managed_fields,
146            ..default()
147        }
148    }
149}
150
151impl CreateResource {
152    pub async fn exec(&self, kubeapi: &Kubeapi, pp: &api::PostParams) -> RkResult<Box<dyn Show>> {
153        match self {
154            Self::ClusterRole(cluster_role) => cluster_role.exec(kubeapi, pp).await,
155            Self::ClusterRoleBinding => Err(RkError::todo()),
156            Self::ConfigMap => Err(RkError::todo()),
157            Self::CronJob => Err(RkError::todo()),
158            Self::Deployment => Err(RkError::todo()),
159            Self::Ingress => Err(RkError::todo()),
160            Self::Job => Err(RkError::todo()),
161            Self::Namespace(namespace) => namespace.exec(kubeapi, pp).await,
162            Self::PodDisruptionBudget => Err(RkError::todo()),
163            Self::PriorityClass => Err(RkError::todo()),
164            Self::Quota => Err(RkError::todo()),
165            Self::Role => Err(RkError::todo()),
166            Self::RoleBinding => Err(RkError::todo()),
167            Self::Secret(secret) => secret.exec(kubeapi, pp).await,
168            Self::Service => Err(RkError::todo()),
169            Self::ServiceAccount => Err(RkError::todo()),
170            Self::Token => Err(RkError::todo()),
171        }
172    }
173}