Skip to content

Commit

Permalink
First pass at:
Browse files Browse the repository at this point in the history
  - Credentials handling
  - Google configuration
  - Stackdriver configuration
  - /fetch entrypoint (mainly a placeholder at the moment)
  • Loading branch information
duftler committed Feb 18, 2017
1 parent bda95a0 commit 2ec1ee3
Show file tree
Hide file tree
Showing 26 changed files with 928 additions and 2 deletions.
4 changes: 4 additions & 0 deletions kayenta-core/kayenta-core.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies {
compile spinnaker.dependency('bootWeb')
spinnaker.group('jackson')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.config;

import com.netflix.spinnaker.kayenta.metrics.MapBackedMetricsServiceRepository;
import com.netflix.spinnaker.kayenta.metrics.MetricsServiceRepository;
import com.netflix.spinnaker.kayenta.security.AccountCredentialsRepository;
import com.netflix.spinnaker.kayenta.security.MapBackedAccountCredentialsRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

public class KayentaConfiguration {

@Bean
@ConditionalOnMissingBean(AccountCredentialsRepository.class)
AccountCredentialsRepository accountCredentialsRepository() {
return new MapBackedAccountCredentialsRepository();
}

@Bean
@ConditionalOnMissingBean(MetricsServiceRepository.class)
MetricsServiceRepository metricsServiceRepository() {
return new MapBackedMetricsServiceRepository();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.metrics;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class MapBackedMetricsServiceRepository implements MetricsServiceRepository {

@Autowired
List<MetricsService> metricsServices;

@Override
public MetricsService getOne(String accountName) {
for (MetricsService metricsService : metricsServices) {
if (metricsService.servicesAccount(accountName)) {
return metricsService;
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.metrics;

import java.io.IOException;
import java.util.Map;

public interface MetricsService {
boolean servicesAccount(String accountName);
Map queryMetrics(String accountName,
String instanceNamePrefix,
String intervalStartTime,
String intervalEndTime) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.metrics;

public interface MetricsServiceRepository {
MetricsService getOne(String accountName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.security;

import com.fasterxml.jackson.annotation.JsonIgnore;

import java.util.List;

public interface AccountCredentials<T> {
String getName();

List<Type> getSupportedTypes();

@JsonIgnore
T getCredentials();

enum Type {
METRICS_STORE,
OBJECT_STORE
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.security;

import java.util.Set;

public interface AccountCredentialsRepository {
AccountCredentials getOne(String name);

AccountCredentials getOne(AccountCredentials.Type credentialsType);

Set<? extends AccountCredentials> getAll();

AccountCredentials save(String name, AccountCredentials credentials);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.security;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class MapBackedAccountCredentialsRepository implements AccountCredentialsRepository {

private final Map<String, AccountCredentials> map = new ConcurrentHashMap<>();

@Override
public AccountCredentials getOne(String name) {
return map.get(name);
}

@Override
public AccountCredentials getOne(AccountCredentials.Type credentialsType) {
for (AccountCredentials accountCredentials : map.values()) {
if (accountCredentials.getSupportedTypes().contains(credentialsType)) {
return accountCredentials;
}
}

return null;
}

@Override
public Set<AccountCredentials> getAll() {
return new HashSet<>(map.values());
}

@Override
public AccountCredentials save(String name, AccountCredentials credentials) {
return map.put(credentials.getName(), credentials);
}
}
8 changes: 8 additions & 0 deletions kayenta-google/kayenta-google.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dependencies {
compile project(":kayenta-core")
compile spinnaker.dependency('bootWeb')
compile spinnaker.dependency('lombok')
spinnaker.group('google')

compile 'com.google.apis:google-api-services-monitoring:v3-rev35-1.22.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.google.config;

import com.netflix.spinnaker.kayenta.google.security.GoogleCredentials;
import com.netflix.spinnaker.kayenta.google.security.GoogleJsonCredentials;
import com.netflix.spinnaker.kayenta.google.security.GoogleNamedAccountCredentials;
import com.netflix.spinnaker.kayenta.security.AccountCredentials;
import com.netflix.spinnaker.kayenta.security.AccountCredentialsRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.List;

@Configuration
@EnableConfigurationProperties
@ConditionalOnProperty("kayenta.google.enabled")
@ComponentScan({"com.netflix.spinnaker.kayenta.google"})
@Slf4j
public class GoogleConfiguration {

@Bean
@ConfigurationProperties("kayenta.google")
GoogleConfigurationProperties googleConfigurationProperties() {
return new GoogleConfigurationProperties();
}

@Bean
boolean registerGoogleCredentials(GoogleConfigurationProperties googleConfigurationProperties, AccountCredentialsRepository accountCredentialsRepository) throws IOException {
for (GoogleManagedAccount googleManagedAccount : googleConfigurationProperties.getAccounts()) {
String name = googleManagedAccount.getName();
String project = googleManagedAccount.getProject();
List<AccountCredentials.Type> supportedTypes = googleManagedAccount.getSupportedTypes();

log.info("Registering Google account {} for project {} of type {}.", name, project, AccountCredentials.Type.METRICS_STORE);

try {
String jsonKey = googleManagedAccount.getJsonKey();
GoogleCredentials googleCredentials =
StringUtils.hasLength(jsonKey)
? new GoogleJsonCredentials(project, jsonKey)
: new GoogleCredentials(project);

GoogleNamedAccountCredentials.GoogleNamedAccountCredentialsBuilder googleNamedAccountCredentialsBuilder =
GoogleNamedAccountCredentials
.builder()
.name(name)
.project(project)
.credentials(googleCredentials)
.monitoring(googleCredentials.getMonitoring("the-spinnaker-user-agent"));

if (!CollectionUtils.isEmpty(supportedTypes)) {
googleNamedAccountCredentialsBuilder.supportedTypes(supportedTypes);
}

GoogleNamedAccountCredentials googleNamedAccountCredentials = googleNamedAccountCredentialsBuilder.build();
accountCredentialsRepository.save(name, googleNamedAccountCredentials);
} catch (Throwable t) {
log.error("Could not load Google account " + name + ".", t);
}
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2017 Google, Inc.
*
* 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.kayenta.google.config;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

public class GoogleConfigurationProperties {

@Getter
private List<GoogleManagedAccount> accounts = new ArrayList<>();
}
Loading

0 comments on commit 2ec1ee3

Please sign in to comment.