From e1bd180553c104a777ab731f419bb8673ebbccc3 Mon Sep 17 00:00:00 2001 From: German Muzquiz <35276119+german-muzquiz@users.noreply.github.com> Date: Thu, 10 Oct 2019 09:09:58 -0500 Subject: [PATCH 1/3] feat(secrets/gcs): Support for decrypting spinnaker secrets in GCS (#1441) --- halyard-config/halyard-config.gradle | 1 + halyard-core/halyard-core.gradle | 1 + 2 files changed, 2 insertions(+) diff --git a/halyard-config/halyard-config.gradle b/halyard-config/halyard-config.gradle index f8579e8746..64ced41982 100644 --- a/halyard-config/halyard-config.gradle +++ b/halyard-config/halyard-config.gradle @@ -15,6 +15,7 @@ dependencies { implementation "com.netflix.spinnaker.front50:front50-s3:$front50Version" implementation 'com.netflix.spinnaker.kork:kork-secrets' implementation 'com.netflix.spinnaker.kork:kork-secrets-aws' + implementation 'com.netflix.spinnaker.kork:kork-secrets-gcp' implementation "com.netflix.spinnaker.kork:kork-web" implementation 'com.amazonaws:aws-java-sdk-core:1.11.534' implementation 'com.amazonaws:aws-java-sdk-s3:1.11.534' diff --git a/halyard-core/halyard-core.gradle b/halyard-core/halyard-core.gradle index 243b003435..b0353b79d7 100644 --- a/halyard-core/halyard-core.gradle +++ b/halyard-core/halyard-core.gradle @@ -8,6 +8,7 @@ dependencies { implementation "com.netflix.spinnaker.clouddriver:clouddriver-aws:$clouddriverVersion" implementation 'com.netflix.spinnaker.kork:kork-secrets' implementation 'com.netflix.spinnaker.kork:kork-secrets-aws' + implementation 'com.netflix.spinnaker.kork:kork-secrets-gcp' implementation 'com.google.apis:google-api-services-storage' implementation 'com.google.api.grpc:grpc-google-common-protos:1.0.5' implementation 'org.apache.commons:commons-exec' From b4de6f0e0c5a4044136b8454527dc43849d10c19 Mon Sep 17 00:00:00 2001 From: Jared Welch Date: Thu, 10 Oct 2019 13:14:47 -0700 Subject: [PATCH 2/3] feat(monitoring): add new relic monitoring daemon config (#1442) * feat(canary): add new relic monitoring daemon config * feat(monitoring): replace short description for metric store commands s/authentication method/metric store --- docs/commands.md | 86 +++++++++++++++++-- .../v1/config/MetricStoresCommand.java | 2 + .../AbstractEditMetricStoreCommand.java | 2 +- .../newrelic/EditNewrelicCommand.java | 76 ++++++++++++++++ .../newrelic/NewrelicCommand.java | 34 ++++++++ .../metricStores/newrelic/NewrelicStore.java | 50 +++++++++++ .../config/model/v1/node/MetricStores.java | 10 ++- .../services/v1/MetricStoresService.java | 4 + ...innakerMonitoringDaemonProfileFactory.java | 6 ++ 9 files changed, 261 insertions(+), 9 deletions(-) create mode 100644 halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/EditNewrelicCommand.java create mode 100644 halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/NewrelicCommand.java create mode 100644 halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/metricStores/newrelic/NewrelicStore.java diff --git a/docs/commands.md b/docs/commands.md index e687880dd7..ff92cc23a9 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -308,6 +308,10 @@ * [**hal config metric-stores datadog edit**](#hal-config-metric-stores-datadog-edit) * [**hal config metric-stores datadog enable**](#hal-config-metric-stores-datadog-enable) * [**hal config metric-stores edit**](#hal-config-metric-stores-edit) + * [**hal config metric-stores newrelic**](#hal-config-metric-stores-newrelic) + * [**hal config metric-stores newrelic disable**](#hal-config-metric-stores-newrelic-disable) + * [**hal config metric-stores newrelic edit**](#hal-config-metric-stores-newrelic-edit) + * [**hal config metric-stores newrelic enable**](#hal-config-metric-stores-newrelic-enable) * [**hal config metric-stores prometheus**](#hal-config-metric-stores-prometheus) * [**hal config metric-stores prometheus disable**](#hal-config-metric-stores-prometheus-disable) * [**hal config metric-stores prometheus edit**](#hal-config-metric-stores-prometheus-edit) @@ -6004,6 +6008,7 @@ hal config metric-stores [parameters] [subcommands] #### Subcommands * `datadog`: Configure your datadog metric store. * `edit`: Configure global metric stores properties. + * `newrelic`: Configure your newrelic metric store. * `prometheus`: Configure your prometheus metric store. * `stackdriver`: Configure your stackdriver metric store. @@ -6023,7 +6028,7 @@ hal config metric-stores datadog [parameters] [subcommands] #### Subcommands * `disable`: Set the datadog method as disabled - * `edit`: Edit the datadog authentication method. + * `edit`: Edit the datadog metric store. * `enable`: Set the datadog method as enabled --- @@ -6044,7 +6049,7 @@ hal config metric-stores datadog disable [parameters] --- ## hal config metric-stores datadog edit -Edit the datadog authentication method. +Edit the datadog metric store. #### Usage ``` @@ -6092,6 +6097,75 @@ hal config metric-stores edit [parameters] * `--period`: (*Required*) Set the polling period for the monitoring daemon. +--- +## hal config metric-stores newrelic + +Configure your newrelic metric store. + +#### Usage +``` +hal config metric-stores newrelic [parameters] [subcommands] +``` + +#### Parameters + * `--deployment`: If supplied, use this Halyard deployment. This will _not_ create a new deployment. + * `--no-validate`: (*Default*: `false`) Skip validation. + +#### Subcommands + * `disable`: Set the newrelic method as disabled + * `edit`: Edit the newrelic metric store. + * `enable`: Set the newrelic method as enabled + +--- +## hal config metric-stores newrelic disable + +Set the newrelic method as disabled + +#### Usage +``` +hal config metric-stores newrelic disable [parameters] +``` + +#### Parameters + * `--deployment`: If supplied, use this Halyard deployment. This will _not_ create a new deployment. + * `--no-validate`: (*Default*: `false`) Skip validation. + + +--- +## hal config metric-stores newrelic edit + +Edit the newrelic metric store. + +#### Usage +``` +hal config metric-stores newrelic edit [parameters] +``` + +#### Parameters + * `--add-tag`: Add this tag to the list of tags. Use the format key:value i.e. --add-tag app:test + * `--deployment`: If supplied, use this Halyard deployment. This will _not_ create a new deployment. + * `--host`: The URL to post metric data to. In almost all cases, this is set correctly by default and should not be used. + * `--insert-key`: Your New Relic Insights insert key + * `--no-validate`: (*Default*: `false`) Skip validation. + * `--remove-tag`: Remove this tag from the list of tags. Use the name of the tag you want to remove i.e. --remove-tag app + * `--tags`: (*Default*: `[]`) Your custom tags. Please delimit the KVP with colons i.e. --tags app:test env:dev + + +--- +## hal config metric-stores newrelic enable + +Set the newrelic method as enabled + +#### Usage +``` +hal config metric-stores newrelic enable [parameters] +``` + +#### Parameters + * `--deployment`: If supplied, use this Halyard deployment. This will _not_ create a new deployment. + * `--no-validate`: (*Default*: `false`) Skip validation. + + --- ## hal config metric-stores prometheus @@ -6108,7 +6182,7 @@ hal config metric-stores prometheus [parameters] [subcommands] #### Subcommands * `disable`: Set the prometheus method as disabled - * `edit`: Edit the prometheus authentication method. + * `edit`: Edit the prometheus metric store. * `enable`: Set the prometheus method as enabled --- @@ -6129,7 +6203,7 @@ hal config metric-stores prometheus disable [parameters] --- ## hal config metric-stores prometheus edit -Edit the prometheus authentication method. +Edit the prometheus metric store. #### Usage ``` @@ -6173,7 +6247,7 @@ hal config metric-stores stackdriver [parameters] [subcommands] #### Subcommands * `disable`: Set the stackdriver method as disabled - * `edit`: Edit the stackdriver authentication method. + * `edit`: Edit the stackdriver metric store. * `enable`: Set the stackdriver method as enabled --- @@ -6194,7 +6268,7 @@ hal config metric-stores stackdriver disable [parameters] --- ## hal config metric-stores stackdriver edit -Edit the stackdriver authentication method. +Edit the stackdriver metric store. #### Usage ``` diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/MetricStoresCommand.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/MetricStoresCommand.java index 48d68034ec..9933808552 100644 --- a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/MetricStoresCommand.java +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/MetricStoresCommand.java @@ -20,6 +20,7 @@ import com.beust.jcommander.Parameters; import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.EditMetricStoresCommand; import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.datadog.DatadogCommand; +import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.newrelic.NewrelicCommand; import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.prometheus.PrometheusCommand; import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.stackdriver.StackdriverCommand; import com.netflix.spinnaker.halyard.cli.services.v1.Daemon; @@ -45,6 +46,7 @@ public class MetricStoresCommand extends AbstractConfigCommand { public MetricStoresCommand() { registerSubcommand(new EditMetricStoresCommand()); registerSubcommand(new DatadogCommand()); + registerSubcommand(new NewrelicCommand()); registerSubcommand(new PrometheusCommand()); registerSubcommand(new StackdriverCommand()); } diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/AbstractEditMetricStoreCommand.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/AbstractEditMetricStoreCommand.java index bb6461f7f7..f491533815 100644 --- a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/AbstractEditMetricStoreCommand.java +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/AbstractEditMetricStoreCommand.java @@ -40,7 +40,7 @@ public abstract class AbstractEditMetricStoreCommand protected abstract MetricStore editMetricStore(T metricStore); public String getShortDescription() { - return "Edit the " + getMetricStoreType().getId() + " authentication method."; + return "Edit the " + getMetricStoreType().getId() + " metric store."; } @Override diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/EditNewrelicCommand.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/EditNewrelicCommand.java new file mode 100644 index 0000000000..02b250a554 --- /dev/null +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/EditNewrelicCommand.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019 New Relic Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.newrelic; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.AbstractEditMetricStoreCommand; +import com.netflix.spinnaker.halyard.config.model.v1.metricStores.newrelic.NewrelicStore; +import com.netflix.spinnaker.halyard.config.model.v1.node.MetricStore; +import com.netflix.spinnaker.halyard.config.model.v1.node.MetricStores; +import java.util.ArrayList; +import java.util.List; + +@Parameters(separators = "=") +public class EditNewrelicCommand extends AbstractEditMetricStoreCommand { + public MetricStores.MetricStoreType getMetricStoreType() { + return MetricStores.MetricStoreType.NEWRELIC; + } + + @Parameter(names = "--insert-key", description = "Your New Relic Insights insert key") + private String insertKey; + + @Parameter( + names = "--host", + description = + "The URL to post metric data to. In almost all cases, this is set correctly by default and should not be used.") + private String host; + + @Parameter( + names = "--tags", + variableArity = true, + description = + "Your custom tags. Please delimit the KVP with colons i.e. --tags app:test env:dev") + private List tags = new ArrayList<>(); + + @Parameter( + names = "--add-tag", + description = + "Add this tag to the list of tags. Use the format key:value i.e. --add-tag app:test") + private String addTag; + + @Parameter( + names = "--remove-tag", + description = + "Remove this tag from the list of tags. Use the name of the tag you want to remove i.e. --remove-tag app") + private String removeTag; + + @Override + protected MetricStore editMetricStore(NewrelicStore newrelicStore) { + newrelicStore.setInsertKey(isSet(insertKey) ? insertKey : newrelicStore.getInsertKey()); + newrelicStore.setHost(isSet(host) ? host : newrelicStore.getHost()); + + try { + newrelicStore.setTags(updateStringList(newrelicStore.getTags(), tags, addTag, removeTag)); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Set either --tags or --[add/remove]-tag"); + } + + return newrelicStore; + } +} diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/NewrelicCommand.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/NewrelicCommand.java new file mode 100644 index 0000000000..4f6106da93 --- /dev/null +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/metricStores/newrelic/NewrelicCommand.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 New Relic Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.newrelic; + +import com.beust.jcommander.Parameters; +import com.netflix.spinnaker.halyard.cli.command.v1.config.metricStores.MetricStoreCommand; +import com.netflix.spinnaker.halyard.config.model.v1.node.MetricStores; + +@Parameters(separators = "=") +public class NewrelicCommand extends MetricStoreCommand { + public MetricStores.MetricStoreType getMetricStoreType() { + return MetricStores.MetricStoreType.NEWRELIC; + } + + public NewrelicCommand() { + super(); + registerSubcommand(new EditNewrelicCommand()); + } +} diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/metricStores/newrelic/NewrelicStore.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/metricStores/newrelic/NewrelicStore.java new file mode 100644 index 0000000000..49347fc28d --- /dev/null +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/metricStores/newrelic/NewrelicStore.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019 New Relic Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.netflix.spinnaker.halyard.config.model.v1.metricStores.newrelic; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.netflix.spinnaker.halyard.config.model.v1.node.MetricStore; +import com.netflix.spinnaker.halyard.config.model.v1.node.MetricStores; +import com.netflix.spinnaker.halyard.config.model.v1.node.Secret; +import java.util.ArrayList; +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class NewrelicStore extends MetricStore { + @Override + public String getNodeName() { + return "newrelic"; + } + + @JsonIgnore + private MetricStores.MetricStoreType metricStoreType = MetricStores.MetricStoreType.NEWRELIC; + + @Secret(alwaysDecrypt = true) + @JsonProperty("insert_key") + private String insertKey; + + @JsonProperty("host") + private String host; + + @JsonProperty("tags") + private List tags = new ArrayList<>(); +} diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/node/MetricStores.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/node/MetricStores.java index 4bd5cf48db..621049ab7c 100644 --- a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/node/MetricStores.java +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/model/v1/node/MetricStores.java @@ -18,6 +18,7 @@ package com.netflix.spinnaker.halyard.config.model.v1.node; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.datadog.DatadogStore; +import com.netflix.spinnaker.halyard.config.model.v1.metricStores.newrelic.NewrelicStore; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.prometheus.PrometheusStore; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.stackdriver.StackdriverStore; import java.lang.reflect.Field; @@ -33,10 +34,14 @@ public class MetricStores extends Node { private DatadogStore datadog = new DatadogStore(); private PrometheusStore prometheus = new PrometheusStore(); private StackdriverStore stackdriver = new StackdriverStore(); + private NewrelicStore newrelic = new NewrelicStore(); private int period = 30; public boolean isEnabled() { - return datadog.isEnabled() || prometheus.isEnabled() || stackdriver.isEnabled(); + return datadog.isEnabled() + || prometheus.isEnabled() + || stackdriver.isEnabled() + || newrelic.isEnabled(); } public void setEnabled(boolean ignored) {} @@ -64,7 +69,8 @@ public static Class translateMetricStoreType(String metri public enum MetricStoreType { DATADOG("datadog"), PROMETHEUS("prometheus"), - STACKDRIVER("stackdriver"); + STACKDRIVER("stackdriver"), + NEWRELIC("newrelic"); @Getter private final String id; diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/MetricStoresService.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/MetricStoresService.java index 9ff1396c7c..5b670bb1ee 100644 --- a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/MetricStoresService.java +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/MetricStoresService.java @@ -18,6 +18,7 @@ package com.netflix.spinnaker.halyard.config.services.v1; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.datadog.DatadogStore; +import com.netflix.spinnaker.halyard.config.model.v1.metricStores.newrelic.NewrelicStore; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.prometheus.PrometheusStore; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.stackdriver.StackdriverStore; import com.netflix.spinnaker.halyard.config.model.v1.node.DeploymentConfiguration; @@ -111,6 +112,9 @@ public void setMetricStore(String deploymentName, MetricStore metricStore) { case DATADOG: metricStores.setDatadog((DatadogStore) metricStore); break; + case NEWRELIC: + metricStores.setNewrelic((NewrelicStore) metricStore); + break; case PROMETHEUS: metricStores.setPrometheus((PrometheusStore) metricStore); break; diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/profile/SpinnakerMonitoringDaemonProfileFactory.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/profile/SpinnakerMonitoringDaemonProfileFactory.java index 24e122511f..d329de8d2d 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/profile/SpinnakerMonitoringDaemonProfileFactory.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/profile/SpinnakerMonitoringDaemonProfileFactory.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.datadog.DatadogStore; +import com.netflix.spinnaker.halyard.config.model.v1.metricStores.newrelic.NewrelicStore; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.prometheus.PrometheusStore; import com.netflix.spinnaker.halyard.config.model.v1.metricStores.stackdriver.StackdriverStore; import com.netflix.spinnaker.halyard.config.model.v1.node.DeploymentConfiguration; @@ -73,6 +74,11 @@ protected void setProfile( files.addAll(backupRequiredFiles(stackdriverStore, deploymentConfiguration.getName())); } + NewrelicStore newrelicStore = metricStores.getNewrelic(); + if (newrelicStore.isEnabled()) { + enabledMetricStores.add("newrelic"); + } + profile.appendContents(yamlToString(deploymentConfiguration.getName(), profile, metricStores)); Server server = From 0a103d9b80cb8b4b694855e35660394a566418e2 Mon Sep 17 00:00:00 2001 From: Jared Welch Date: Mon, 14 Oct 2019 10:43:23 -0700 Subject: [PATCH 3/3] feat(kubernetes): add flag for Kubernetes custom resources (#1436) * feat(kubernetes): add flag for Kubernetes custom resources Adds flag `--custom-resources` to specify CRDs that should be cached by clouddriver. Defining custom resources here is required for them to be used in patch and delete pipeline stages. * feat(kubernetes) validation for customResources and allow setting all fields * Update docs for custom resources flag * feat(kubernetes): clean up CLI arguments for adding custom resources Switched from serialized format for setting fields to only allowing adding custom resource when editing an account. `--spinnaker-kind` and `--versioned` are optional but are not valid arguments without `--add-custom-resource`. * feat(kubernetes): fix docs --- docs/commands.md | 4 ++ .../KubernetesAddAccountCommand.java | 1 + .../KubernetesCommandProperties.java | 3 + .../KubernetesEditAccountCommand.java | 55 +++++++++++++++++++ .../KubernetesAccountValidator.java | 11 ++++ 5 files changed, 74 insertions(+) diff --git a/docs/commands.md b/docs/commands.md index ff92cc23a9..1cf2a9d3cb 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -8810,6 +8810,7 @@ hal config provider kubernetes account edit ACCOUNT [parameters] #### Parameters `ACCOUNT`: The name of the account to operate on. + * `--add-custom-resource`: (V2 Only) Add Kubernetes custom resource to the list of custom resources to managed by clouddriver and made available for use in patch and delete manifest stages. Fields besides the Kubernetes Kind (resource name) can be set using the flags "--spinnaker-kind" and "--versioned" * `--add-docker-registry`: Add this docker registry to the list of docker registries to use as a source of images. * `--add-kind`: Add this kind to the list of kinds to manage. * `--add-namespace`: Add this namespace to the list of namespaces to manage. @@ -8846,6 +8847,7 @@ This can only be set when --namespaces is empty or not set. created by Spinnaker; as opposed to attempting to configure applications for resources already present in Kubernetes. * `--provider-version`: Some providers support multiple versions/release tracks. This allows you to pick the version of the provider (not the resources it manages) to run within Spinnaker. * `--read-permissions`: A user must have at least one of these roles in order to view this account's cloud resources. + * `--remove-custom-resource`: Remove this Kubernetes custom resource by name from the list of custom resources to manage. * `--remove-docker-registry`: Remove this docker registry from the list of docker registries to use as a source of images. * `--remove-kind`: Remove this kind to the list of kinds to manage. * `--remove-namespace`: Remove this namespace to the list of namespaces to manage. @@ -8856,6 +8858,8 @@ created by Spinnaker; as opposed to attempting to configure applications for res * `--remove-write-permission`: Remove this permission to from list of write permissions. * `--required-group-membership`: A user must be a member of at least one specified group in order to make changes to this account's cloud resources. * `--service-account`: When true, Spinnaker attempt to authenticate against Kubernetes using a Kubernetes service account. This only works when Halyard & Spinnaker are deployed in Kubernetes. Read more about service accounts here: [https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/). + * `--spinnaker-kind`: Set the Spinnaker kind for custom resource being added. + * `--versioned`: Configure whether the custom resource being added is versioned by Spinnaker. * `--write-permissions`: A user must have at least one of these roles in order to make changes to this account's cloud resources. diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesAddAccountCommand.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesAddAccountCommand.java index 6f2e67b991..f05b2812bc 100644 --- a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesAddAccountCommand.java +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesAddAccountCommand.java @@ -143,6 +143,7 @@ protected Account buildAccount(String accountName) { account.setCheckPermissionsOnStartup(checkPermissionsOnStartup); account.setLiveManifestCalls(liveManifestCalls); account.setCacheThreads(cacheThreads); + return account; } diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesCommandProperties.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesCommandProperties.java index bc5209aa7b..cf6ed38617 100644 --- a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesCommandProperties.java +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesCommandProperties.java @@ -69,4 +69,7 @@ public class KubernetesCommandProperties { static final String CACHE_THREADS = "Number of caching agents for this kubernetes account. Each agent handles a subset of the namespaces available to this account. " + "By default, only 1 agent caches all kinds for all namespaces in the account."; + static final String CUSTOM_RESOURCES = + "(V2 Only) Add Kubernetes custom resource to the list of custom resources to managed by clouddriver and made available for use in patch and delete manifest stages. " + + "Fields besides the Kubernetes Kind (resource name) can be set using the flags \"--spinnaker-kind\" and \"--versioned\""; } diff --git a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesEditAccountCommand.java b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesEditAccountCommand.java index bad35b6615..ce7cddf5cf 100644 --- a/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesEditAccountCommand.java +++ b/halyard-cli/src/main/java/com/netflix/spinnaker/halyard/cli/command/v1/config/providers/kubernetes/KubernetesEditAccountCommand.java @@ -154,6 +154,31 @@ protected String getProviderName() { @Parameter(names = "--naming-strategy", hidden = true) public String namingStrategy; + @Parameter( + names = "--add-custom-resource", + arity = 1, + description = KubernetesCommandProperties.CUSTOM_RESOURCES) + public String addCustomResourceName; + + @Parameter( + names = "--spinnaker-kind", + arity = 1, + description = "Set the Spinnaker kind for custom resource being added.") + public String addCustomResourceSpinnakerKind; + + @Parameter( + names = "--versioned", + arity = 1, + description = "Configure whether the custom resource being added is versioned by Spinnaker.") + public Boolean addCustomResourceVersioned; + + @Parameter( + names = "--remove-custom-resource", + arity = 1, + description = + "Remove this Kubernetes custom resource by name from the list of custom resources to manage.") + public String removeCustomResource; + @Parameter( names = "--service-account", arity = 1, @@ -244,6 +269,36 @@ protected Account editAccount(KubernetesAccount account) { throw new IllegalArgumentException("Set either --omit-kinds or --[add/remove]-omit-kind"); } + if (isSet(addCustomResourceName)) { + KubernetesAccount.CustomKubernetesResource customKubernetesResource = + new KubernetesAccount.CustomKubernetesResource(); + customKubernetesResource.setKubernetesKind(addCustomResourceName); + customKubernetesResource.setSpinnakerKind( + isSet(addCustomResourceSpinnakerKind) + ? addCustomResourceSpinnakerKind + : customKubernetesResource.getSpinnakerKind()); + customKubernetesResource.setVersioned( + isSet(addCustomResourceVersioned) + ? addCustomResourceVersioned + : customKubernetesResource.isVersioned()); + account.getCustomResources().add(customKubernetesResource); + } else { + if (isSet(addCustomResourceSpinnakerKind) || isSet(addCustomResourceVersioned)) { + throw new IllegalArgumentException( + "\"--spinnaker-kind\" and \"--versioned\" can only be used with \"--add-custom-resource\" " + + "to set the name for the custom resource."); + } + } + + if (isSet(removeCustomResource)) { + List newCustomResources = + account.getCustomResources().stream() + .filter(entry -> !entry.getKubernetesKind().equals(removeCustomResource)) + .collect(Collectors.toList()); + + account.setCustomResources(newCustomResources); + } + try { List oldRegistries = account.getDockerRegistries().stream() diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/kubernetes/KubernetesAccountValidator.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/kubernetes/KubernetesAccountValidator.java index 2bc4386e3e..5966500596 100644 --- a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/kubernetes/KubernetesAccountValidator.java +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/kubernetes/KubernetesAccountValidator.java @@ -111,6 +111,17 @@ private void validateKindConfig(ConfigProblemSetBuilder psBuilder, KubernetesAcc psBuilder.addProblem(ERROR, "At most one of \"kinds\" and \"omitKinds\" may be specified."); } + if (CollectionUtils.isNotEmpty(customResources)) { + List kubernetesKindNotSet = + customResources.stream() + .map(KubernetesAccount.CustomKubernetesResource::getKubernetesKind) + .filter(cr -> (cr == null || cr.isEmpty())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(kubernetesKindNotSet)) { + psBuilder.addProblem(ERROR, "Missing custom resource name (Kubernetes Kind)."); + } + } + if (CollectionUtils.isNotEmpty(kinds) && CollectionUtils.isNotEmpty(customResources)) { List unmatchedKinds = customResources.stream()