use of com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount in project halyard by spinnaker.
the class KubernetesV2Service method stageConfig.
default List<ConfigSource> stageConfig(AccountDeploymentDetails<KubernetesAccount> details, GenerateService.ResolvedConfiguration resolvedConfiguration) {
Map<String, Profile> profiles = resolvedConfiguration.getProfilesForService(getService().getType());
String stagingPath = getSpinnakerStagingPath(details.getDeploymentName());
Map<String, Set<Profile>> profilesByDirectory = new HashMap<>();
List<String> requiredFiles = new ArrayList<>();
List<ConfigSource> configSources = new ArrayList<>();
String secretNamePrefix = getServiceName() + "-files";
String namespace = getNamespace(resolvedConfiguration.getServiceSettings(getService()));
KubernetesAccount account = details.getAccount();
for (Entry<String, Profile> entry : profiles.entrySet()) {
Profile profile = entry.getValue();
String outputFile = profile.getOutputFile();
String mountPoint = Paths.get(outputFile).getParent().toString();
Set<Profile> profilesInDirectory = profilesByDirectory.getOrDefault(mountPoint, new HashSet<>());
profilesInDirectory.add(profile);
requiredFiles.addAll(profile.getRequiredFiles());
profilesByDirectory.put(mountPoint, profilesInDirectory);
}
for (Entry<String, Set<Profile>> entry : profilesByDirectory.entrySet()) {
Set<Profile> profilesInDirectory = entry.getValue();
String mountPath = entry.getKey();
List<SecretMountPair> files = profilesInDirectory.stream().map(p -> {
File input = new File(p.getStagedFile(stagingPath));
File output = new File(p.getOutputFile());
return new SecretMountPair(input, output);
}).collect(Collectors.toList());
Map<String, String> env = profilesInDirectory.stream().map(Profile::getEnv).map(Map::entrySet).flatMap(Collection::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
String name = KubernetesV2Utils.createSecret(account, namespace, secretNamePrefix, files);
configSources.add(new ConfigSource().setId(name).setMountPath(mountPath).setEnv(env));
}
if (!requiredFiles.isEmpty()) {
List<SecretMountPair> files = requiredFiles.stream().map(File::new).map(SecretMountPair::new).collect(Collectors.toList());
String name = KubernetesV2Utils.createSecret(account, namespace, secretNamePrefix, files);
configSources.add(new ConfigSource().setId(name).setMountPath(files.get(0).getContents().getParent()));
}
return configSources;
}
use of com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount in project halyard by spinnaker.
the class KubernetesV2Service method getResourceYaml.
default String getResourceYaml(AccountDeploymentDetails<KubernetesAccount> details, GenerateService.ResolvedConfiguration resolvedConfiguration) {
ServiceSettings settings = resolvedConfiguration.getServiceSettings(getService());
String namespace = getNamespace(settings);
List<ConfigSource> configSources = stageConfig(details, resolvedConfiguration);
Map<String, String> env = configSources.stream().map(ConfigSource::getEnv).map(Map::entrySet).flatMap(Collection::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
env.putAll(settings.getEnv());
List<String> volumes = configSources.stream().map(c -> {
TemplatedResource volume = new JinjaJarResource("/kubernetes/manifests/volume.yml");
volume.addBinding("name", c.getId());
return volume.toString();
}).collect(Collectors.toList());
List<String> volumeMounts = configSources.stream().map(c -> {
TemplatedResource volume = new JinjaJarResource("/kubernetes/manifests/volumeMount.yml");
volume.addBinding("name", c.getId());
volume.addBinding("mountPath", c.getMountPath());
return volume.toString();
}).collect(Collectors.toList());
TemplatedResource probe;
if (StringUtils.isNotEmpty(settings.getHealthEndpoint())) {
probe = new JinjaJarResource("/kubernetes/manifests/execReadinessProbe.yml");
probe.addBinding("command", getReadinessExecCommand(settings));
} else {
probe = new JinjaJarResource("/kubernetes/manifests/tcpSocketReadinessProbe.yml");
probe.addBinding("port", settings.getPort());
}
TemplatedResource container = new JinjaJarResource("/kubernetes/manifests/container.yml");
container.addBinding("name", getService().getCanonicalName());
container.addBinding("imageId", settings.getArtifactId());
container.addBinding("port", settings.getPort());
container.addBinding("volumeMounts", volumeMounts);
container.addBinding("probe", probe.toString());
container.addBinding("env", env);
List<String> containers = Collections.singletonList(container.toString());
TemplatedResource podSpec = new JinjaJarResource("/kubernetes/manifests/podSpec.yml").addBinding("containers", containers).addBinding("volumes", volumes);
return new JinjaJarResource("/kubernetes/manifests/deployment.yml").addBinding("name", getService().getCanonicalName()).addBinding("namespace", namespace).addBinding("replicas", settings.getTargetSize()).addBinding("podAnnotations", settings.getKubernetes().getPodAnnotations()).addBinding("podSpec", podSpec.toString()).toString();
}
use of com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount in project halyard by spinnaker.
the class KubernetesEditAccountCommand method editAccount.
@Override
protected Account editAccount(KubernetesAccount account) {
boolean contextSet = context != null && !context.isEmpty();
if (contextSet && !clearContext) {
account.setContext(context);
} else if (!contextSet && clearContext) {
account.setContext(null);
} else if (contextSet && clearContext) {
throw new IllegalArgumentException("Set either --context or --clear-context");
}
account.setKubeconfigFile(isSet(kubeconfigFile) ? kubeconfigFile : account.getKubeconfigFile());
account.setConfigureImagePullSecrets(isSet(configureImagePullSecrets) ? configureImagePullSecrets : account.getConfigureImagePullSecrets());
account.setServiceAccount(isSet(serviceAccount) ? serviceAccount : account.getServiceAccount());
try {
account.setNamespaces(updateStringList(account.getNamespaces(), namespaces, addNamespace, removeNamespace));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Set either --namespaces or --[add/remove]-namespace");
}
try {
account.setOmitNamespaces(updateStringList(account.getOmitNamespaces(), omitNamespaces, addOmitNamespace, removeOmitNamespace));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Set either --omit-namespaces or --[add/remove]-omit-namespace");
}
try {
account.setKinds(updateStringList(account.getKinds(), kinds, addKind, removeKind));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Set either --kinds or --[add/remove]-kind");
}
try {
account.setOmitKinds(updateStringList(account.getOmitKinds(), omitKinds, addOmitKind, removeOmitKind));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Set either --omit-kinds or --[add/remove]-omit-kind");
}
try {
List<String> oldRegistries = account.getDockerRegistries().stream().map(DockerRegistryReference::getAccountName).collect(Collectors.toList());
List<DockerRegistryReference> newRegistries = updateStringList(oldRegistries, dockerRegistries, addDockerRegistry, removeDockerRegistry).stream().map(s -> new DockerRegistryReference().setAccountName(s)).collect(Collectors.toList());
account.setDockerRegistries(newRegistries);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Set either --docker-registries or --[add/remove]-docker-registry");
}
try {
account.setOAuthScopes(updateStringList(account.getOAuthScopes(), oAuthScopes, addOAuthScope, removeOAuthScope));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Set either --oauth-scopes or --[add/remove]-oauth-scope");
}
account.setOAuthServiceAccount(isSet(oAuthServiceAccount) ? oAuthServiceAccount : account.getOAuthServiceAccount());
account.setNamingStrategy(isSet(namingStrategy) ? namingStrategy : account.getNamingStrategy());
account.setSkin(isSet(skin) ? skin : account.getSkin());
return account;
}
use of com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount in project halyard by spinnaker.
the class KubernetesAccountValidator method validateKubeconfig.
private void validateKubeconfig(ConfigProblemSetBuilder psBuilder, KubernetesAccount account) {
io.fabric8.kubernetes.api.model.Config kubeconfig;
String context = account.getContext();
String kubeconfigFile = account.getKubeconfigFile();
String cluster = account.getCluster();
String user = account.getUser();
List<String> namespaces = account.getNamespaces();
List<String> omitNamespaces = account.getOmitNamespaces();
// This indicates if a first pass at the config looks OK. If we don't see any serious problems, we'll do one last check
// against the requested kubernetes cluster to ensure that we can run spinnaker.
boolean smoketest = true;
boolean namespacesProvided = namespaces != null && !namespaces.isEmpty();
boolean omitNamespacesProvided = omitNamespaces != null && !omitNamespaces.isEmpty();
if (namespacesProvided && omitNamespacesProvided) {
psBuilder.addProblem(ERROR, "At most one of \"namespaces\" and \"omitNamespaces\" can be supplied.");
smoketest = false;
}
// TODO(lwander) find a good resource / list of resources for generating kubeconfig files to link to here.
try {
if (ValidatingFileReader.contents(psBuilder, kubeconfigFile) == null) {
return;
}
File kubeconfigFileOpen = new File(kubeconfigFile);
kubeconfig = KubeConfigUtils.parseConfig(kubeconfigFileOpen);
} catch (IOException e) {
psBuilder.addProblem(ERROR, e.getMessage());
return;
}
System.out.println(context);
if (context != null && !context.isEmpty()) {
Optional<NamedContext> namedContext = kubeconfig.getContexts().stream().filter(c -> c.getName().equals(context)).findFirst();
if (!namedContext.isPresent()) {
psBuilder.addProblem(ERROR, "Context \"" + context + "\" not found in kubeconfig \"" + kubeconfigFile + "\".", "context").setRemediation("Either add this context to your kubeconfig, rely on the default context, or pick another kubeconfig file.");
smoketest = false;
}
} else {
String currentContext = kubeconfig.getCurrentContext();
if (StringUtils.isEmpty(currentContext)) {
psBuilder.addProblem(ERROR, "You have not specified a Kubernetes context, and your kubeconfig \"" + kubeconfigFile + "\" has no current-context.", "context").setRemediation("Either specify a context in your halconfig, or set a current-context in your kubeconfig.");
smoketest = false;
} else {
psBuilder.addProblem(WARNING, "You have not specified a Kubernetes context in your halconfig, Spinnaker will use \"" + currentContext + "\" instead.", "context").setRemediation("We recommend explicitly setting a context in your halconfig, to ensure changes to your kubeconfig won't break your deployment.");
}
}
if (smoketest) {
Config config = KubernetesConfigParser.parse(kubeconfigFile, context, cluster, user, namespaces, false);
try {
KubernetesClient client = new DefaultKubernetesClient(config);
client.namespaces().list();
} catch (Exception e) {
ConfigProblemBuilder pb = psBuilder.addProblem(ERROR, "Unable to communicate with your Kubernetes cluster: " + e.getMessage() + ".");
if (e.getMessage().contains("Token may have expired")) {
pb.setRemediation("If you downloaded these keys with gcloud, it's possible they are in the wrong format. To fix this, run \n\n" + "gcloud config set container/use_client_certificate true\n\ngcloud container clusters get-credentials $CLUSTERNAME");
} else {
pb.setRemediation("Unable to authenticate with your Kubernetes cluster. Try using kubectl to verify your credentials.");
}
}
}
}
use of com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount in project halyard by spinnaker.
the class KubernetesAccountValidator method validate.
@Override
public void validate(ConfigProblemSetBuilder psBuilder, KubernetesAccount account) {
DeploymentConfiguration deploymentConfiguration;
// TODO(lwander) this is still a little messy - I should use the filters to get the necessary docker account
Node parent = account.getParent();
while (!(parent instanceof DeploymentConfiguration)) {
// Note this will crash in the above check if the halconfig representation is corrupted
// (that's ok, because it indicates a more serious error than we want to validate).
parent = parent.getParent();
}
deploymentConfiguration = (DeploymentConfiguration) parent;
validateKindConfig(psBuilder, account);
// TODO(lwander) validate all config with clouddriver's v2 creds
switch(account.getProviderVersion()) {
case V1:
final List<String> dockerRegistryNames = account.getDockerRegistries().stream().map(DockerRegistryReference::getAccountName).collect(Collectors.toList());
validateDockerRegistries(psBuilder, deploymentConfiguration, dockerRegistryNames, Provider.ProviderType.KUBERNETES);
validateKubeconfig(psBuilder, account);
case V2:
break;
default:
throw new IllegalStateException("Unknown provider version " + account.getProviderVersion());
}
}
Aggregations