1
+ #!/usr/bin/env python
2
+
3
+ # Copyright 2015 The Kubernetes Authors.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ ###################
18
+
19
+ # local-overrides.py takes in input a list of provider and, for each of them, generates the components YAML from the
20
+ # local repositories (the GitHub repositories clone), and finally stores it in the clusterctl local override folder
21
+
22
+ # prerequisites:
23
+
24
+ # - the script should be executed from sigs.k8s.io/cluster-api/ by calling cmd/clusterctl/hack/local-overrides.py
25
+ # - there should be a sigs.k8s.io/cluster-api/clusterctl-settings.json file with the list of provider for which
26
+ # the local overrides should be generated and the list of provider repositories to be included (on top of cluster-api).
27
+ # {
28
+ # "providers": [ "cluster-api", "kubeadm", "aws"],
29
+ # "provider_repos": ["../cluster-api-provider-aws"]
30
+ # }
31
+ # - for each additional provider repository there should be a sigs.k8s.io/<provider_repo>/clusterctl-settings.json file e.g.
32
+ # {
33
+ # "name": "aws",
34
+ # "config": {
35
+ # "componentsFile": "infrastructure-components.yaml",
36
+ # "nextVersion": "v0.5.0",
37
+ # "type": "InfrastructureProvider"
38
+ # }
39
+
40
+ ###################
41
+
42
+ import json
43
+ import subprocess
44
+ import os
45
+ import errno
46
+
47
+ settings = {}
48
+
49
+ providers = {
50
+ 'cluster-api' : {
51
+ 'componentsFile' : 'core-components.yaml' ,
52
+ 'nextVersion' : 'v0.3.0' ,
53
+ 'type' : 'CoreProvider' ,
54
+ },
55
+ 'kubeadm' : {
56
+ 'componentsFile' : 'bootstrap-components.yaml' ,
57
+ 'nextVersion' : 'v0.3.0' ,
58
+ 'type' : 'BootstrapProvider' ,
59
+ },
60
+ }
61
+
62
+ def load_settings ():
63
+ global settings
64
+ try :
65
+ settings = json .load (open ('clusterctl-settings.json' ))
66
+ except Exception as e :
67
+ raise Exception ('failed to load clusterctl-settings.json: {}' .format (e ))
68
+
69
+ def load_provider ():
70
+ provider_repos = settings .get ('provider_repos' , [])
71
+ for repo in provider_repos :
72
+ file = repo + '/clusterctl-settings.json'
73
+ try :
74
+ provider_details = json .load (open (file ))
75
+ provider_name = provider_details ['name' ]
76
+ provider_config = provider_details ['config' ]
77
+ provider_config ['repo' ] = repo
78
+ providers [provider_name ] = provider_config
79
+ except Exception as e :
80
+ raise Exception ('failed to load clusterctl-settings.json from repo {}: {}' .format (repo , e ))
81
+
82
+ def kustomize (args ):
83
+ try :
84
+ out = subprocess .Popen (args ,
85
+ stdout = subprocess .PIPE ,
86
+ stderr = subprocess .STDOUT )
87
+
88
+ stdout , stderr = out .communicate ()
89
+ if stderr is not None :
90
+ raise Exception ('stderr contains: \n {}' .format (stderr ))
91
+
92
+ return stdout
93
+ except Exception as e :
94
+ raise Exception ('failed to run {}: {}' .format (args , e ))
95
+
96
+ def get_home ():
97
+ return os .path .expanduser ('~' )
98
+
99
+ def write_local_override (provider , version , components_file , components_yaml ):
100
+ try :
101
+ home = get_home ()
102
+ overrides_folder = os .path .join (home , 'cluster-api' , 'overrides' )
103
+ provider_overrides_folder = os .path .join (overrides_folder , provider , version )
104
+ try :
105
+ os .makedirs (provider_overrides_folder )
106
+ except OSError as e :
107
+ if e .errno != errno .EEXIST :
108
+ raise
109
+ f = open (os .path .join (provider_overrides_folder , components_file ), 'w' )
110
+ f .write (components_yaml )
111
+ f .close ()
112
+ except Exception as e :
113
+ raise Exception ('failed to write {} to {}: {}' .format (components_file , components_folder , e ))
114
+
115
+ def create_local_overrides ():
116
+ providerList = settings .get ('providers' , [])
117
+ assert providerList is not None , 'invalid configuration: please define the list of providers to overrides'
118
+ assert len (providerList )> 0 , 'invalid configuration: please define at least one provider to override'
119
+
120
+ for provider in providerList :
121
+ p = providers .get (provider )
122
+ assert p is not None , 'invalid configuration: please the configuration for the {} provider' .format (provider )
123
+
124
+ repo = '.'
125
+ if 'repo' in p :
126
+ repo = p .get ('repo' )
127
+
128
+ next_version = p .get ('nextVersion' )
129
+ assert next_version is not None , 'invalid configuration for provider {}: please provide nextVersion value' .format (provider )
130
+
131
+ type = p .get ('type' )
132
+ assert type is not None , 'invalid configuration for provider {}: please provide type value' .format (provider )
133
+ assert type in ['CoreProvider' ,'BootstrapProvider' ,'InfrastructureProvider' ], 'invalid configuration for provider {}: please provide type value' .format (provider )
134
+
135
+ components_file = p .get ('componentsFile' )
136
+ assert components_file is not None , 'invalid configuration for provider {}: please provide componentsFile value' .format (provider )
137
+
138
+ components_yaml = kustomize (['kustomize' , 'build' , repo + '/config/default' ])
139
+ write_local_override (provider , next_version , components_file , components_yaml )
140
+
141
+ yield provider , type , next_version
142
+
143
+
144
+ def CoreProviderFlag ():
145
+ return '--core'
146
+
147
+ def BootstrapProviderFlag ():
148
+ return '--bootstrap'
149
+
150
+ def InfrastructureProviderFlag ():
151
+ return '--infrastructure'
152
+
153
+ def type_to_flag (type ):
154
+ switcher = {
155
+ 'CoreProvider' : CoreProviderFlag ,
156
+ 'BootstrapProvider' : BootstrapProviderFlag ,
157
+ 'InfrastructureProvider' : InfrastructureProviderFlag
158
+ }
159
+ func = switcher .get (type , lambda : 'Invalid type' )
160
+ return func ()
161
+
162
+ def print_instructions (overrides ):
163
+ providerList = settings .get ('providers' , [])
164
+ print ('clusterctl local overrides generated from local repositories for the {} providers.' .format (', ' .join (providerList )))
165
+ print ('in order to use them, please run:' )
166
+ print
167
+ cmd = 'clusterctl init'
168
+ for provider , type , next_version in overrides :
169
+ cmd += ' {} {}:{}' .format (type_to_flag (type ), provider , next_version )
170
+ print (cmd )
171
+ print
172
+
173
+ load_settings ()
174
+
175
+ load_provider ()
176
+
177
+ overrides = create_local_overrides ()
178
+
179
+ print_instructions (overrides )
0 commit comments