summaryrefslogtreecommitdiffstats
path: root/clover/spinnaker
diff options
context:
space:
mode:
Diffstat (limited to 'clover/spinnaker')
-rw-r--r--clover/spinnaker/__init__.py0
-rwxr-xr-xclover/spinnaker/halyard.py120
-rw-r--r--clover/spinnaker/halyard_sample.py41
-rw-r--r--clover/spinnaker/install/quick-install-spinnaker.yml376
-rw-r--r--clover/spinnaker/lib/__init__.py0
-rwxr-xr-xclover/spinnaker/lib/halyard_base.py157
6 files changed, 694 insertions, 0 deletions
diff --git a/clover/spinnaker/__init__.py b/clover/spinnaker/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clover/spinnaker/__init__.py
diff --git a/clover/spinnaker/halyard.py b/clover/spinnaker/halyard.py
new file mode 100755
index 0000000..20c0f4b
--- /dev/null
+++ b/clover/spinnaker/halyard.py
@@ -0,0 +1,120 @@
+#!/bin/python
+
+import lib.halyard_base as base
+import time
+from clover.orchestration.kube_client import KubeClient
+
+namespace = 'spinnaker'
+client = KubeClient()
+
+def list_accounts(provider):
+ account_list = base.list_accounts(provider)
+ return account_list
+
+def delete_account(provider, accountname):
+ result = base.delete_account(provider, accountname)
+ if result != "SUCCEEDED":
+ print "Delete account failed"
+ return result
+
+ apply_result = base.apply_deploy()
+ if apply_result == "SUCCEEDED":
+ print "Delete account successfully"
+ else:
+ print "Delete account failed"
+
+ return apply_result
+
+def add_k8s_account(accountname, kubeconfigfile,
+ providerversion=None, registries=[]):
+ # Note: if providerversion is V1, must provider registries.
+ if base.is_account_exist("kubernetes",accountname):
+ return "FAILED"
+ if providerversion == None or providerversion == 'V1':
+ providerversion = None
+ if 0 == len(registries) or isinstance(registries, list) == False:
+ print "please provider docker registries or the type of registries is not list"
+ return "FAILED"
+ # Copy kubectl file to halyard pod
+ hal_kubeconfigfile = "/home/spinnaker/config" + \
+ time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
+ spinnaker_pods = client.find_pod_by_namespace(namespace)
+ for pod in spinnaker_pods:
+ if pod.find("spin-halyard") == 0:
+ client.copy_file_to_pod(kubeconfigfile,
+ hal_kubeconfigfile,
+ pod, namespace)
+ dockerRegistries = []
+ for registry in registries:
+ if not base.is_account_exist("dockerRegistry",registry):
+ print ("Please add docker registry: %s" %registry)
+ return "FAILED"
+ docker_dict = {"accountName":registry, "namespaces":[]}
+ dockerRegistries.append(docker_dict)
+
+ data = {
+ "name": accountname,
+ "requiredGroupMembership": [],
+ "providerVersion": providerversion,
+ "permissions": {},
+ "dockerRegistries": dockerRegistries,
+ "context": None,
+ "cluster": None,
+ "user": None,
+ "configureImagePullSecrets": "true",
+ "serviceAccount": None,
+ "cacheThreads": 1,
+ "namespaces": [],
+ "omitNamespaces": [],
+ "kinds": [],
+ "omitKinds": [],
+ "customResources": [],
+ "cachingPolicies": [],
+ "kubeconfigFile": hal_kubeconfigfile,
+ "kubeconfigContents": None,
+ "kubectlPath": None,
+ "namingStrategy": None,
+ "skin": None,
+ "debug": None,
+ "oauthScopes": [],
+ "oauthServiceAccount": None,
+ "oAuthServiceAccount": None,
+ "oAuthScopes": []
+ }
+# print data
+ result = base.add_account("kubernetes",data)
+ return result
+
+def add_docker_account(address, accountname, repositories=[],
+ username=None, password=None, validate='true'):
+
+ if base.is_account_exist("dockerRegistry",accountname):
+ return "FAILED"
+
+ data = {
+ "name": accountname,
+ "requiredGroupMembership": [],
+ "providerVersion": None,
+ "permissions": {},
+ "address": address,
+ "username": username,
+ "password": password,
+ "email": "fake.email@spinnaker.io",
+ "cacheIntervalSeconds": 30,
+ "clientTimeoutMillis": 60000,
+ "cacheThreads": 1,
+ "paginateSize": 100,
+ "sortTagsByDate": False,
+ "trackDigests": False,
+ "insecureRegistry": False,
+ "repositories": repositories,
+ "passwordFile": None,
+ "dockerconfigFile": None
+ }
+ result = base.add_account("dockerRegistry",data)
+ if result == "SUCCEEDED":
+ print "Add account successfully"
+ else:
+ print "Add account failed"
+ return result
+
diff --git a/clover/spinnaker/halyard_sample.py b/clover/spinnaker/halyard_sample.py
new file mode 100644
index 0000000..b78be9b
--- /dev/null
+++ b/clover/spinnaker/halyard_sample.py
@@ -0,0 +1,41 @@
+# Copyright (c) Authors of Clover
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import halyard
+
+
+# please install the spinnaker useing the spinnaker/install/quick-install-spinnaker.yml first
+print "######## add docker provider ##########"
+address = "https://index.docker.io"
+repositories = ['wtwde/onap', 'wtwde/spinnaker', 'library/nginx']
+add_docker = halyard.add_docker_account(address, "docker-test", repositories)
+print "######## result ##########"
+print add_docker
+
+print "######## add kubernetes provider ##########"
+add_k8s = halyard.add_k8s_account('my-k8s-v1-t11561', "/root/config.115", "V1", ['dockerhub'])
+print "######## result ##########"
+print add_k8s
+
+print "######## k8s account list ##########"
+k8s_list = halyard.list_accounts('kubernetes')
+print "####### result ##########"
+print k8s_list
+
+print "######## docker account list ##########"
+docker_list = halyard.list_accounts('dockerRegistry')
+print "####### result ##########"
+print docker_list
+
+print "######## delete kubernetes provider ##########"
+del_k8s = halyard.delete_account('kubernetes','my-k8s-v1-t11561')
+print "######## result ##########"
+
+print "######## delete docker registry provider ##########"
+del_docker = halyard.delete_account('dockerRegistry','docker-test')
+print "######## result ##########"
+print del_docker
diff --git a/clover/spinnaker/install/quick-install-spinnaker.yml b/clover/spinnaker/install/quick-install-spinnaker.yml
new file mode 100644
index 0000000..c935453
--- /dev/null
+++ b/clover/spinnaker/install/quick-install-spinnaker.yml
@@ -0,0 +1,376 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: spinnaker
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: spinnaker-admin
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: cluster-admin
+subjects:
+- kind: ServiceAccount
+ name: default
+ namespace: spinnaker
+
+---
+
+apiVersion: v1
+kind: Pod
+metadata:
+ name: spin-halyard
+ namespace: spinnaker
+ labels:
+ app: spin
+ stack: halyard
+spec:
+ containers:
+ - name: halyard-daemon
+ # todo - make :stable or digest of :stable
+ image: gcr.io/spinnaker-marketplace/halyard:stable
+ imagePullPolicy: Always
+ command:
+ - /bin/sh
+ args:
+ - -c
+ # when the configmap is mounted directly at /home/spinnaker/.hal the halyard daemon
+ # isn't able to replace the contents of the mount with user modifications.
+ # so instead we mount the configmap elsewhere and copy the files into
+ # place when the container starts.
+ - "cp -R /home/spinnaker/staging/.hal /home/spinnaker/.hal && /opt/halyard/bin/halyard"
+ readinessProbe:
+ exec:
+ command:
+ - wget
+ - -q
+ - --spider
+ - http://localhost:8064/health
+ ports:
+ - containerPort: 8064
+ volumeMounts:
+ - name: halconfig
+ mountPath: /home/spinnaker/staging/.hal/config
+ subPath: config
+ - name: halconfig
+ mountPath: /home/spinnaker/staging/.hal/default/service-settings/deck.yml
+ subPath: deck.yml
+ - name: halconfig
+ mountPath: /home/spinnaker/staging/.hal/default/service-settings/gate.yml
+ subPath: gate.yml
+ - name: halconfig
+ mountPath: /home/spinnaker/staging/.hal/default/service-settings/igor.yml
+ subPath: igor.yml
+ - name: halconfig
+ mountPath: /home/spinnaker/staging/.hal/default/service-settings/fiat.yml
+ subPath: fiat.yml
+ - name: halconfig
+ mountPath: /home/spinnaker/staging/.hal/default/profiles/front50-local.yml
+ subPath: front50-local.yml
+ volumes:
+ - name: halconfig
+ configMap:
+ name: halconfig
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: spin-halyard
+ namespace: spinnaker
+spec:
+ ports:
+ - port: 8064
+ targetPort: 8064
+ protocol: TCP
+ selector:
+ app: spin
+ stack: halyard
+
+---
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: halconfig
+ namespace: spinnaker
+data:
+ igor.yml: |
+ enabled: true
+ fiat.yml: |
+ enabled: false
+ skipLifeCycleManagement: true
+ front50-local.yml: |
+ spinnaker.s3.versioning: false
+ gate.yml: |
+ host: 0.0.0.0
+ deck.yml: |
+ host: 0.0.0.0
+ env:
+ API_HOST: http://spin-gate.spinnaker:8084/
+ config: |
+ currentDeployment: default
+ deploymentConfigurations:
+ - name: default
+ version: 1.7.0
+ providers:
+ appengine:
+ enabled: false
+ accounts: []
+ aws:
+ enabled: false
+ accounts: []
+ defaultKeyPairTemplate: '{{name}}-keypair'
+ defaultRegions:
+ - name: us-west-2
+ defaults:
+ iamRole: BaseIAMRole
+ azure:
+ enabled: false
+ accounts: []
+ bakeryDefaults:
+ templateFile: azure-linux.json
+ baseImages: []
+ dcos:
+ enabled: false
+ accounts: []
+ clusters: []
+ dockerRegistry:
+ enabled: true
+ accounts:
+ - name: dockerhub
+ address: https://index.docker.io
+ repositories:
+ - opnfv/clover
+ google:
+ enabled: false
+ accounts: []
+ bakeryDefaults:
+ templateFile: gce.json
+ baseImages: []
+ zone: us-central1-f
+ network: default
+ useInternalIp: false
+ kubernetes:
+ enabled: true
+ accounts:
+ - name: my-kubernetes-account
+ requiredGroupMembership: []
+ providerVersion: V2
+ dockerRegistries: []
+ configureImagePullSecrets: true
+ serviceAccount: true
+ namespaces: []
+ omitNamespaces: []
+ kinds: []
+ omitKinds: []
+ customResources: []
+ oauthScopes: []
+ oAuthScopes: []
+ primaryAccount: my-kubernetes-account
+ openstack:
+ enabled: false
+ accounts: []
+ bakeryDefaults:
+ baseImages: []
+ oraclebmcs:
+ enabled: false
+ accounts: []
+ deploymentEnvironment:
+ size: SMALL
+ type: Distributed
+ accountName: my-kubernetes-account
+ updateVersions: true
+ consul:
+ enabled: false
+ vault:
+ enabled: false
+ customSizing: {}
+ gitConfig:
+ upstreamUser: spinnaker
+ persistentStorage:
+ persistentStoreType: s3
+ azs: {}
+ gcs:
+ rootFolder: front50
+ redis: {}
+ s3:
+ bucket: spinnaker-artifacts
+ rootFolder: front50
+ endpoint: http://minio-service.spinnaker:9000
+ accessKeyId: dont-use-this
+ secretAccessKey: for-production
+ oraclebmcs: {}
+ features:
+ auth: false
+ fiat: false
+ chaos: false
+ entityTags: false
+ jobs: false
+ metricStores:
+ datadog:
+ enabled: false
+ prometheus:
+ enabled: false
+ add_source_metalabels: true
+ stackdriver:
+ enabled: false
+ period: 30
+ enabled: false
+ notifications:
+ slack:
+ enabled: false
+ timezone: America/Los_Angeles
+ ci:
+ jenkins:
+ enabled: true
+ masters: []
+ travis:
+ enabled: false
+ masters: []
+ security:
+ apiSecurity:
+ ssl:
+ enabled: false
+ overrideBaseUrl: /gate
+ uiSecurity:
+ ssl:
+ enabled: false
+ authn:
+ oauth2:
+ enabled: false
+ client: {}
+ resource: {}
+ userInfoMapping: {}
+ saml:
+ enabled: false
+ ldap:
+ enabled: false
+ x509:
+ enabled: false
+ enabled: false
+ authz:
+ groupMembership:
+ service: EXTERNAL
+ google:
+ roleProviderType: GOOGLE
+ github:
+ roleProviderType: GITHUB
+ file:
+ roleProviderType: FILE
+ enabled: false
+ artifacts:
+ gcs:
+ enabled: false
+ accounts: []
+ github:
+ enabled: false
+ accounts: []
+ http:
+ enabled: false
+ accounts: []
+ pubsub:
+ google:
+ enabled: false
+ subscriptions: []
+
+---
+
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: minio-pv-claim
+ namespace: spinnaker
+ labels:
+ app: minio-storage-claim
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+ storageClassName: standard
+
+---
+
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ # This name uniquely identifies the Deployment
+ name: minio-deployment
+ namespace: spinnaker
+spec:
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ labels:
+ app: minio
+ spec:
+ volumes:
+ - name: storage
+ persistentVolumeClaim:
+ claimName: minio-pv-claim
+ containers:
+ - name: minio
+ image: minio/minio
+ args:
+ - server
+ - /storage
+ env:
+ - name: MINIO_ACCESS_KEY
+ value: "dont-use-this"
+ - name: MINIO_SECRET_KEY
+ value: "for-production"
+ ports:
+ - containerPort: 9000
+ volumeMounts:
+ - name: storage
+ mountPath: /storage
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: minio-service
+ namespace: spinnaker
+spec:
+ ports:
+ - port: 9000
+ targetPort: 9000
+ protocol: TCP
+ selector:
+ app: minio
+
+---
+
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: hal-deploy-apply
+ namespace: spinnaker
+ labels:
+ app: job
+ stack: hal-deploy
+spec:
+ template:
+ metadata:
+ labels:
+ app: job
+ stack: hal-deploy
+ spec:
+ restartPolicy: OnFailure
+ containers:
+ - name: hal-deploy-apply
+ # todo use a custom image
+ image: gcr.io/spinnaker-marketplace/halyard:stable
+ command:
+ - /bin/sh
+ args:
+ - -c
+ - "hal deploy apply --daemon-endpoint http://spin-halyard.spinnaker:8064"
diff --git a/clover/spinnaker/lib/__init__.py b/clover/spinnaker/lib/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clover/spinnaker/lib/__init__.py
diff --git a/clover/spinnaker/lib/halyard_base.py b/clover/spinnaker/lib/halyard_base.py
new file mode 100755
index 0000000..7245d6a
--- /dev/null
+++ b/clover/spinnaker/lib/halyard_base.py
@@ -0,0 +1,157 @@
+#!/bin/python
+
+
+import requests
+import json
+import time
+
+base_url="http://spin-halyard.spinnaker:8064/v1"
+namespace= 'spinnaker'
+headers = {'content-type': 'application/json; charset=UTF-8'}
+debug = False
+
+def get(url):
+ result = requests.get(url)
+ return result.json()
+
+def post(url, data = None, headers = None):
+ result = requests.post(url, data=data, headers=headers)
+ return result.json()
+
+def put(url, data = None, headers = None):
+ result = requests.put(url, data=data, headers=headers)
+ return result.json()
+
+def delete(url):
+ result = requests.delete(url)
+ return result.json()
+
+def print_dict_info(dict_info, debug = False):
+ if dict_info == None:
+ return None
+
+ if debug == True:
+ for v,k in dict_info.items():
+ print('{v}:{k}'.format(v = v, k = k))
+ else:
+ print dict_info.get('name')
+ print dict_info.get('state')
+
+def is_account_exist(provider, accountname):
+ exist_accounts = list_accounts(provider)
+ if accountname in exist_accounts:
+ print "account exists"
+ return True
+ print "account doesn't exist"
+ return False
+
+def get_task_info(uuid):
+ if uuid == None:
+ return None
+ url = base_url + "/tasks/" + uuid + "/"
+ result = get(url)
+ return result
+
+def wait_task_successful(uuid):
+ flag = ""
+ while True:
+ resp = get_task_info(uuid)
+ state = resp.get('state')
+ if flag != state:
+ print_dict_info(resp, debug)
+ flag = state
+ if state == "SUCCEEDED":
+ return "SUCCEEDED", resp
+ if state == "FAILED":
+ return "FAILED", resp
+ if resp.get('timedOut'):
+ return "TimeOut", resp
+
+def get_current_deployment():
+ '''get the current deployment and check the state'''
+
+ url = base_url + "/config/currentDeployment"
+ result = get(url)
+ uuid = result.get('uuid')
+ task_info = get_task_info(uuid)
+ print_dict_info(task_info, debug)
+
+ return task_info
+
+def apply_deploy():
+ """
+ after using api to config halyard, it need ruan apply deploy.
+ """
+ prep_url = base_url + "/config/deployments/default/prep/?validate=true"
+ deploy_url = base_url + "/config/deployments/default/deploy/?validate=false"
+ data='""'
+ result = post(prep_url, data=data, headers=headers)
+ uuid = result.get('uuid')
+ result, task_info = wait_task_successful(uuid)
+ if result != "SUCCEEDED":
+ return result
+ result = post(deploy_url, data=data, headers=headers)
+ uuid = result.get('uuid')
+ result, task_info = wait_task_successful(uuid)
+ return result
+
+def list_accounts(provider):
+ """
+ According to the provider, list all accounts
+ """
+ url = base_url + "/config/deployments/default/providers/" + \
+ provider + "/?validate=true"
+ resp = get(url)
+ uuid = resp.get('uuid')
+ result, task_info = wait_task_successful(uuid)
+ if result != "SUCCEEDED":
+ print "Get account failed"
+ return None
+ accounts = task_info.get('response').get('responseBody').get('accounts')
+ account_list = []
+ for account in accounts:
+ account_name = account.get('name')
+ account_list.append(account_name)
+ return account_list
+
+def enable_provider(provider, data='true'):
+ """
+ if needs to add a provider, it is necessary to enable the provider
+ """
+ url = base_url + "/config/deployments/default/providers/" + \
+ provider + "/enabled/?validate=true"
+ resp = put(url,data=data,headers=headers)
+ uuid = resp.get('uuid')
+ result, task_info = wait_task_successful(uuid)
+ return result
+
+def add_account(provider, data):
+ url = base_url + "/config/deployments/default/providers/" + \
+ provider + "/accounts/?validate=true"
+
+ enable_provider(provider)
+
+ resp = post(url, data=json.dumps(data), headers=headers)
+ uuid = resp.get('uuid')
+ result, task_info = wait_task_successful(uuid)
+ if result != "SUCCEEDED":
+ print "Add account failed"
+ return result
+ apply_result = apply_deploy()
+ if apply_result == "SUCCEEDED":
+ print "Deployment successful"
+ else:
+ print "Deployment failed"
+ return apply_result
+
+def delete_account(provider, accountname):
+ if not is_account_exist(provider, accountname):
+ return "FAILED"
+ url = base_url + "/config/deployments/default/providers/" + \
+ provider + "/accounts/account/" + accountname + "/?validate=true"
+ resp = delete(url)
+ uuid = resp.get('uuid')
+ result, task_info = wait_task_successful(uuid)
+
+ return result
+