Skip to content

Commit

Permalink
feat(provider/dcos): Add support for DC/OS pipelines (#1363)
Browse files Browse the repository at this point in the history
  • Loading branch information
willgorman authored and Matt Duftler committed Jun 7, 2017
1 parent a179a3a commit cacc137
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 2 deletions.
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@

Netflix, Inc <*@netflix.com>
Google, Inc <*@google.com>
Pivotal, Inc <*@pivotal.io>
Pivotal, Inc <*@pivotal.io>
Cerner Corporation <*@cerner.com>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2017 Cerner Corporation
*
* 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.orca.clouddriver.tasks.providers.dcos

import com.netflix.spinnaker.orca.pipeline.model.Pipeline
import com.netflix.spinnaker.orca.pipeline.model.Stage

class DcosContainerFinder {
static void populateFromStage(Map operation, Stage stage) {
// If this is a stage in a pipeline, look in the context for the baked image.
def deploymentDetails = (stage.context.deploymentDetails ?: []) as List<Map>

def imageDescription = (Map<String, Object>) operation.docker.image

if (imageDescription.fromContext) {
def image = deploymentDetails.find {
// stageId is used here to match the source of the image to the find image stage specified by the user.
// Previously, this was done by matching the pattern used to the pattern selected in the deploy stage, but
// if the deploy stage's selected pattern wasn't updated before submitting the stage, this step here could fail.
it.refId == imageDescription.stageId
}
if (!image) {
throw new IllegalStateException("No image found in context for pattern $imageDescription.pattern.")
} else {
imageDescription.registry = image.registry
imageDescription.tag = image.tag
imageDescription.repository = image.repository
imageDescription.imageId = buildImageId(image.registry, image.repository, image.tag)
}
}

if (imageDescription.fromTrigger) {
if (stage.execution instanceof Pipeline) {
Map trigger = ((Pipeline) stage.execution).trigger

if (trigger?.account == imageDescription.account && trigger?.repository == imageDescription.repository) {
imageDescription.tag = trigger.tag
}

imageDescription.imageId = buildImageId(imageDescription.registry, imageDescription.repository, imageDescription.tag)
}

if (!imageDescription.tag) {
throw new IllegalStateException("No tag found for image ${imageDescription.registry}/${imageDescription.repository} in trigger context.")
}
}
}

static String buildImageId(Object registry, Object repo, Object tag) {
if (registry) {
return "$registry/$repo:$tag"
} else {
return "$repo:$tag"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2017 Cerner Corporation
*
* 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.orca.clouddriver.tasks.providers.dcos

import com.netflix.spinnaker.orca.clouddriver.tasks.job.JobRunner
import com.netflix.spinnaker.orca.pipeline.model.Stage
import groovy.util.logging.Slf4j
import org.springframework.stereotype.Component

@Slf4j
@Component
class DcosJobRunner implements JobRunner {

boolean katoResultExpected = false
String cloudProvider = "dcos"

@Override
List<Map> getOperations(Stage stage) {
def operation = [:]

// If this stage was synthesized by a parallel deploy stage, the operation properties will be under 'cluster'.
if (stage.context.containsKey("cluster")) {
operation.putAll(stage.context.cluster as Map)
} else {
operation.putAll(stage.context)
}

DcosContainerFinder.populateFromStage(operation, stage)

return [[(OPERATION): operation]]
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2017 Cerner Corporation
*
* 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.orca.clouddriver.tasks.providers.dcos

import com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ServerGroupCreator
import com.netflix.spinnaker.orca.pipeline.model.Stage
import groovy.util.logging.Slf4j
import org.springframework.stereotype.Component

@Slf4j
@Component
class DcosServerGroupCreator implements ServerGroupCreator {

boolean katoResultExpected = false
String cloudProvider = "dcos"

@Override
List<Map> getOperations(Stage stage) {
def operation = [:]

// TODO: this is side-effecty and not good... but it works.
//
// Have to do this here because during a deploy stage in a pipeline run, a disconnect between how the region is
// sent in from deck (which may contain forward slashes) and how the region is formatted and written by clouddriver
// (using underscores) causes the ParallelDeployStage to fail when trying to lookup server groups keyed by region.
// The map contains a region with underscores, but the lookup occurs using a region with forward slashes.
stage.context.region = stage.context.region.replaceAll('/', '_')

// If this stage was synthesized by a parallel deploy stage, the operation properties will be under 'cluster'.
if (stage.context.containsKey("cluster")) {
operation.putAll(stage.context.cluster as Map)
} else {
operation.putAll(stage.context)
}

DcosContainerFinder.populateFromStage(operation, stage)

return [[(OPERATION): operation]]
}

@Override
Optional<String> getHealthProviderName() {
return Optional.empty()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Only the tasks which are specific to DCOS should belong to this package
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.netflix.spinnaker.orca.clouddriver.tasks

import com.netflix.spinnaker.orca.ExecutionStatus
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.aws.AmazonServerGroupCreator
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.dcos.DcosServerGroupCreator
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.gce.GoogleServerGroupCreator
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.kubernetes.KubernetesServerGroupCreator
import com.netflix.spinnaker.orca.clouddriver.tasks.providers.titus.TitusServerGroupCreator
Expand All @@ -37,7 +38,7 @@ class DetermineHealthProvidersTaskSpec extends Specification {
def task = new DetermineHealthProvidersTask(
new Optional<Front50Service>(front50Service),
[],
[new KubernetesServerGroupCreator(), new AmazonServerGroupCreator(), new GoogleServerGroupCreator(), new TitusServerGroupCreator()]
[new KubernetesServerGroupCreator(), new AmazonServerGroupCreator(), new GoogleServerGroupCreator(), new TitusServerGroupCreator(), new DcosServerGroupCreator()]
)

@Unroll
Expand Down

0 comments on commit cacc137

Please sign in to comment.