Skip to content

Commit 16f7be2

Browse files
authored
Add apply_only argument. Add force_conflicts option. (#148)
* add apply_only argument * add force_conflicts option. * It is obvious not to load the config if the exec is explicitly mentioned. #119
1 parent db60339 commit 16f7be2

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

docs/resources/kubectl_manifest.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ YAML
4242
* `sensitive_fields` - Optional. List of fields (dot-syntax) which are sensitive and should be obfuscated in output. Defaults to `["data"]` for Secrets.
4343
* `force_new` - Optional. Forces delete & create of resources if the `yaml_body` changes. Default `false`.
4444
* `server_side_apply` - Optional. Allow using server-side-apply method. Default `false`.
45+
* `force_conflicts` - Optional. Allow using force_conflicts. Default `false`.
46+
* `apply_only` - Optional. It does not delete resource in any case Default `false`.
4547
* `ignore_fields` - Optional. List of map fields to ignore when applying the manifest. See below for more details.
4648
* `override_namespace` - Optional. Override the namespace to apply the kubernetes resource to, ignoring any declared namespace in the `yaml_body`.
4749
* `validate_schema` - Optional. Setting to `false` will mimic `kubectl apply --validate=false` mode. Default `true`.
@@ -73,7 +75,7 @@ resource "kubectl_manifest" "test" {
7375
sensitive_fields = [
7476
"metadata.annotations.my-secret-annotation"
7577
]
76-
78+
7779
yaml_body = <<YAML
7880
apiVersion: admissionregistration.k8s.io/v1beta1
7981
kind: MutatingWebhookConfiguration

kubernetes/provider.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,20 @@ func initializeConfiguration(d *schema.ResourceData) (*restclient.Config, error)
279279
configPaths = filepath.SplitList(v)
280280
}
281281

282-
if d.Get("load_config_file").(bool) && len(configPaths) > 0 {
282+
if v, ok := d.GetOk("exec"); ok {
283+
exec := &clientcmdapi.ExecConfig{}
284+
if spec, ok := v.([]interface{})[0].(map[string]interface{}); ok {
285+
exec.APIVersion = spec["api_version"].(string)
286+
exec.Command = spec["command"].(string)
287+
exec.Args = expandStringSlice(spec["args"].([]interface{}))
288+
for kk, vv := range spec["env"].(map[string]interface{}) {
289+
exec.Env = append(exec.Env, clientcmdapi.ExecEnvVar{Name: kk, Value: vv.(string)})
290+
}
291+
} else {
292+
return nil, fmt.Errorf("Failed to parse exec")
293+
}
294+
overrides.AuthInfo.Exec = exec
295+
} else if d.Get("load_config_file").(bool) && len(configPaths) > 0 {
283296
expandedPaths := []string{}
284297
for _, p := range configPaths {
285298
path, err := homedir.Expand(p)
@@ -361,21 +374,6 @@ func initializeConfiguration(d *schema.ResourceData) (*restclient.Config, error)
361374
overrides.AuthInfo.Token = v.(string)
362375
}
363376

364-
if v, ok := d.GetOk("exec"); ok {
365-
exec := &clientcmdapi.ExecConfig{}
366-
if spec, ok := v.([]interface{})[0].(map[string]interface{}); ok {
367-
exec.APIVersion = spec["api_version"].(string)
368-
exec.Command = spec["command"].(string)
369-
exec.Args = expandStringSlice(spec["args"].([]interface{}))
370-
for kk, vv := range spec["env"].(map[string]interface{}) {
371-
exec.Env = append(exec.Env, clientcmdapi.ExecEnvVar{Name: kk, Value: vv.(string)})
372-
}
373-
} else {
374-
return nil, fmt.Errorf("Failed to parse exec")
375-
}
376-
overrides.AuthInfo.Exec = exec
377-
}
378-
379377
cc := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loader, overrides)
380378
cfg, err := cc.ClientConfig()
381379
if err != nil {

kubernetes/resource_kubectl_manifest.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ metadata:
187187
_ = d.Set("name", metaObjLive.GetName())
188188
_ = d.Set("force_new", false)
189189
_ = d.Set("server_side_apply", false)
190+
_ = d.Set("apply_only", false)
190191

191192
// clear out fields user can't set to try and get parity with yaml_body
192193
meta_v1_unstruct.RemoveNestedField(metaObjLive.Raw.Object, "metadata", "creationTimestamp")
@@ -396,6 +397,18 @@ var (
396397
Optional: true,
397398
Default: false,
398399
},
400+
"force_conflicts": {
401+
Type: schema.TypeBool,
402+
Description: "Default false.",
403+
Optional: true,
404+
Default: false,
405+
},
406+
"apply_only": {
407+
Type: schema.TypeBool,
408+
Description: "Apply only. In other words, it does not delete resource in any case.",
409+
Optional: true,
410+
Default: false,
411+
},
399412
"ignore_fields": {
400413
Type: schema.TypeList,
401414
Elem: &schema.Schema{Type: schema.TypeString},
@@ -478,6 +491,10 @@ func resourceKubectlManifestApply(ctx context.Context, d *schema.ResourceData, m
478491
applyOptions.FieldManager = "kubectl"
479492
}
480493

494+
if d.Get("force_conflicts").(bool) {
495+
applyOptions.ForceConflicts = true
496+
}
497+
481498
if manifest.HasNamespace() {
482499
applyOptions.Namespace = manifest.GetNamespace()
483500
}
@@ -596,6 +613,9 @@ func resourceKubectlManifestReadUsingClient(ctx context.Context, d *schema.Resou
596613
}
597614

598615
func resourceKubectlManifestDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) error {
616+
if d.Get("apply_only").(bool) {
617+
return nil
618+
}
599619
yamlBody := d.Get("yaml_body").(string)
600620
manifest, err := yaml.ParseYAML(yamlBody)
601621
if err != nil {

0 commit comments

Comments
 (0)