-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate.py
155 lines (125 loc) · 5.39 KB
/
state.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!multiconf
from multiconf.envs import EnvFactory
from multiconf import ConfigRoot, ConfigItem, ConfigBuilder
from multiconf.decorators import nested_repeatables, repeat, required, named_as
@nested_repeatables('cloud_servers, jenkins, apache')
@required('git')
class Project(ConfigRoot):
def __init__(self, selected_env, name, valid_envs, **attr):
super(Project, self).__init__(selected_env=selected_env, name=name,
valid_envs=valid_envs, **attr)
def render(self):
# for all items within config:
# collect result of their own render() function
pass
@named_as('cloud_servers')
@repeat()
class CloudServer(ConfigItem):
def __init__(self, host_name, server_num):
print 'DEBUG: in CloudServer.__init__ host_name=', host_name
super(CloudServer, self).__init__(host_name=host_name,
server_num=server_num)
print 'DEBUG: in CloudServer.__init__ self.host_name=', self.host_name
class CloudServers(ConfigBuilder):
'''
This is builder - it will insert into config multiple objects
if type CloudServer and will calculate hostname for each
'''
def __init__(self, base_host_name, num_servers):
super(CloudServers, self).__init__(host_name=base_host_name,
num_servers=num_servers)
def build(self):
for server_num in xrange(1, self.num_servers+1):
cs = CloudServer(host_name='%s%s' % (self.host_name, server_num),
server_num=server_num)
print 'DEBUG: cs.host_name=%s' % cs.host_name
@named_as('git')
class GitRepo(ConfigItem):
def __init__(self, origin, branch, branches_mask):
super(GitRepo, self).__init__(origin=origin, branch=branch,
branches_mask=branches_mask)
@named_as('jenkins')
@required('nodes, view')
@repeat()
class Jenkins(ConfigItem):
def __init__(self, num_nodes, base_port=0):
super(Jenkins, self).__init__(num_nodes=num_nodes, base_port=base_port)
@named_as('nodes')
class Nodes(ConfigItem):
def __init__(self, hosts):
super(Nodes, self).__init__(hosts=hosts)
@named_as('view')
@nested_repeatables('sub_view')
class NestedView(ConfigItem):
def __init__(self, name):
super(NestedView, self).__init__(name=name)
@named_as('sub_view')
@repeat()
class JobsView(ConfigItem):
def __init__(self, name):
super(JobsView, self).__init__(name=name)
class Jobs(ConfigItem):
def __init__(self, slaves=None):
super(Jobs, self).__init__(slaves=slaves)
class ProjectJobs(Jobs):
pass
class RepositoryJobs(Jobs):
pass
@named_as('apache')
@repeat()
class Apache(ConfigItem):
def __init__(self, base_port, nodes):
super(Apache, self).__init__(base_port=base_port, nodes=nodes)
class Database(ConfigItem):
def __init__(self, name):
super(Database, self).__init__(name=name)
# Define environments
# Use EnvFactory() to create environment or group of environments
ef = EnvFactory()
# We have five environments and we define them here
devlocal = ef.Env('devlocal') # Local dev box
dev = ef.Env('dev') # Dev build box
cloud = ef.Env('cloud') # Cloud
prod = ef.Env('prod')
# Grouping environments per their roles
g_dev = ef.EnvGroup('g_dev', devlocal, dev, cloud)
g_prod = ef.EnvGroup('g_prod', prod)
# This function is used to describe all environments and return an instantiated environment
# configuration for environment with name 'env_name', which is passed as parameter
def conf(env_name):
env = ef.env(env_name)
with Project(env, 'SampleProject', [g_dev, g_prod]) as project:
# CloudServers is a multiconf builder - it will not be present in
# configuration. Instead there will be CloudServer objects based on
# num_servers parameter
with CloudServers(base_host_name='something', num_servers=0) as cloud_servers:
cloud_servers.setattr('num_servers', devlocal=1, dev=2, cloud=4)
# GitRepo is set to be a required element of a project
# Try to comment out this declaration and see what happens
with GitRepo(origin='[email protected]:lechat/envsample.git',
branch='master', branches_mask='fb_[0-9]*$') as git:
git.setattr('branch', g_dev='develop')
with Jenkins(num_nodes=0) as jenkins:
jenkins.setattr('num_nodes', g_dev=2)
jenkins.setattr('base_port', g_dev=8080)
# Nodes is a builder too
jenkins_nodes = Nodes(hosts=cloud_servers)
with NestedView(project.name) as top_view:
with JobsView('%s_branches' % project.name) as jw1:
ProjectJobs(jenkins_nodes)
with JobsView('%s_common' % project.name) as jw1:
RepositoryJobs()
with Apache(base_port=80, nodes=cloud_servers) as apache:
apache.setattr('base_port', g_dev=18000)
with Database('%s_db' % project.name) as db:
db.setattr('name', g_dev='%s_dev_db' % project.name)
return project
config = conf('devlocal')
print config
assert(config.name=='SampleProject')
# Check that we only have one cloud server in devlocal
assert(len(config.cloud_servers)==1)
print config.cloud_servers
cloud_server = config.cloud_servers.values()[0]
assert(isinstance(cloud_server, CloudServer))
assert(cloud_server.host_name == 'something1')