forked from Altinity/clickhouse-operator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
macro.go
242 lines (217 loc) · 10.3 KB
/
macro.go
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// Copyright 2019 Altinity Ltd and/or its affiliates. All rights reserved.
//
// 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 model
import (
"strconv"
"strings"
chop "github.com/squids-io/clickhouse-operator/pkg/apis/clickhouse.altinity.com/v1"
"github.com/squids-io/clickhouse-operator/pkg/util"
)
const (
// macrosNamespace is a sanitized namespace name where ClickHouseInstallation runs
macrosNamespace = "{namespace}"
// macrosChiName is a sanitized ClickHouseInstallation name
macrosChiName = "{chi}"
// macrosChiID is a sanitized ID made of original ClickHouseInstallation name
macrosChiID = "{chiID}"
// macrosClusterName is a sanitized cluster name
macrosClusterName = "{cluster}"
// macrosClusterID is a sanitized ID made of original cluster name
macrosClusterID = "{clusterID}"
// macrosClusterIndex is an index of the cluster in the CHI - integer number, converted into string
macrosClusterIndex = "{clusterIndex}"
// macrosShardName is a sanitized shard name
macrosShardName = "{shard}"
// macrosShardID is a sanitized ID made of original shard name
macrosShardID = "{shardID}"
// macrosShardIndex is an index of the shard in the cluster - integer number, converted into string
macrosShardIndex = "{shardIndex}"
// macrosReplicaName is a sanitized replica name
macrosReplicaName = "{replica}"
// macrosReplicaID is a sanitized ID made of original replica name
macrosReplicaID = "{replicaID}"
// macrosReplicaIndex is an index of the replica in the cluster - integer number, converted into string
macrosReplicaIndex = "{replicaIndex}"
// macrosHostName is a sanitized host name
macrosHostName = "{host}"
// macrosHostID is a sanitized ID made of original host name
macrosHostID = "{hostID}"
// macrosChiScopeIndex is an index of the host on the CHI-scope
macrosChiScopeIndex = "{chiScopeIndex}"
// macrosChiScopeCycleIndex is an index of the host in the CHI-scope cycle - integer number, converted into string
macrosChiScopeCycleIndex = "{chiScopeCycleIndex}"
// macrosChiScopeCycleOffset is an offset of the host in the CHI-scope cycle - integer number, converted into string
macrosChiScopeCycleOffset = "{chiScopeCycleOffset}"
// macrosClusterScopeIndex is an index of the host on the cluster-scope
macrosClusterScopeIndex = "{clusterScopeIndex}"
// macrosClusterScopeCycleIndex is an index of the host in the Cluster-scope cycle - integer number, converted into string
macrosClusterScopeCycleIndex = "{clusterScopeCycleIndex}"
// macrosClusterScopeCycleOffset is an offset of the host in the Cluster-scope cycle - integer number, converted into string
macrosClusterScopeCycleOffset = "{clusterScopeCycleOffset}"
// macrosShardScopeIndex is an index of the host on the shard-scope
macrosShardScopeIndex = "{shardScopeIndex}"
// macrosReplicaScopeIndex is an index of the host on the replica-scope
macrosReplicaScopeIndex = "{replicaScopeIndex}"
// macrosClusterScopeCycleHeadPointsToPreviousCycleTail is {clusterScopeIndex} of previous Cycle Tail
macrosClusterScopeCycleHeadPointsToPreviousCycleTail = "{clusterScopeCycleHeadPointsToPreviousCycleTail}"
)
// macrosEngine
type macrosEngine struct {
names *namer
chi *chop.ClickHouseInstallation
cluster *chop.ChiCluster
shard *chop.ChiShard
host *chop.ChiHost
}
// macro
func macro(scope interface{}) *macrosEngine {
m := new(macrosEngine)
m.names = newNamer(namerContextNames)
switch t := scope.(type) {
case *chop.ClickHouseInstallation:
m.chi = t
case *chop.ChiCluster:
m.cluster = t
case *chop.ChiShard:
m.shard = t
case *chop.ChiHost:
m.host = t
}
return m
}
// Line expands line with macros(es)
func (m *macrosEngine) Line(line string) string {
switch {
case m.chi != nil:
return m.newLineMacroReplacerChi().Replace(line)
case m.cluster != nil:
return m.newLineMacroReplacerCluster().Replace(line)
case m.shard != nil:
return m.newLineMacroReplacerShard().Replace(line)
case m.host != nil:
return m.newLineMacroReplacerHost().Replace(line)
}
return "unknown scope"
}
// Map expands map with macros(es)
func (m *macrosEngine) Map(_map map[string]string) map[string]string {
switch {
case m.chi != nil:
return m.newMapMacroReplacerChi().Replace(_map)
case m.cluster != nil:
return m.newMapMacroReplacerCluster().Replace(_map)
case m.shard != nil:
return m.newMapMacroReplacerShard().Replace(_map)
case m.host != nil:
return m.newMapMacroReplacerHost().Replace(_map)
}
return map[string]string{
"unknown scope": "unknown scope",
}
}
// newLineMacroReplacerChi
func (m *macrosEngine) newLineMacroReplacerChi() *strings.Replacer {
return strings.NewReplacer(
macrosNamespace, m.names.namePartNamespace(m.chi.Namespace),
macrosChiName, m.names.namePartChiName(m.chi.Name),
macrosChiID, m.names.namePartChiNameID(m.chi.Name),
)
}
// newMapMacroReplacerChi
func (m *macrosEngine) newMapMacroReplacerChi() *util.MapReplacer {
return util.NewMapReplacer(m.newLineMacroReplacerChi())
}
// newLineMacroReplacerCluster
func (m *macrosEngine) newLineMacroReplacerCluster() *strings.Replacer {
return strings.NewReplacer(
macrosNamespace, m.names.namePartNamespace(m.cluster.Address.Namespace),
macrosChiName, m.names.namePartChiName(m.cluster.Address.CHIName),
macrosChiID, m.names.namePartChiNameID(m.cluster.Address.CHIName),
macrosClusterName, m.names.namePartClusterName(m.cluster.Address.ClusterName),
macrosClusterID, m.names.namePartClusterNameID(m.cluster.Address.ClusterName),
macrosClusterIndex, strconv.Itoa(m.cluster.Address.ClusterIndex),
)
}
// newMapMacroReplacerCluster
func (m *macrosEngine) newMapMacroReplacerCluster() *util.MapReplacer {
return util.NewMapReplacer(m.newLineMacroReplacerCluster())
}
// newLineMacroReplacerShard
func (m *macrosEngine) newLineMacroReplacerShard() *strings.Replacer {
return strings.NewReplacer(
macrosNamespace, m.names.namePartNamespace(m.shard.Address.Namespace),
macrosChiName, m.names.namePartChiName(m.shard.Address.CHIName),
macrosChiID, m.names.namePartChiNameID(m.shard.Address.CHIName),
macrosClusterName, m.names.namePartClusterName(m.shard.Address.ClusterName),
macrosClusterID, m.names.namePartClusterNameID(m.shard.Address.ClusterName),
macrosClusterIndex, strconv.Itoa(m.shard.Address.ClusterIndex),
macrosShardName, m.names.namePartShardName(m.shard.Address.ShardName),
macrosShardID, m.names.namePartShardNameID(m.shard.Address.ShardName),
macrosShardIndex, strconv.Itoa(m.shard.Address.ShardIndex),
)
}
// newMapMacroReplacerShard
func (m *macrosEngine) newMapMacroReplacerShard() *util.MapReplacer {
return util.NewMapReplacer(m.newLineMacroReplacerShard())
}
// clusterScopeIndexOfPreviousCycleTail gets cluster-scope index of previous cycle tail
func clusterScopeIndexOfPreviousCycleTail(host *chop.ChiHost) int {
if host.Address.ClusterScopeCycleOffset == 0 {
// This is the cycle head - the first host of the cycle
// We need to point to previous host in this cluster - which would be previous cycle tail
if host.Address.ClusterScopeIndex == 0 {
// This is the very first host in the cluster - head of the first cycle
// No previous host available, so just point to the same host, mainly because label must be an empty string
// or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character
// So we can't set it to "-1"
return host.Address.ClusterScopeIndex
}
// This is head of non-first cycle, point to previous host in the cluster - which would be previous cycle tail
return host.Address.ClusterScopeIndex - 1
}
// This is not cycle head - just point to the same host
return host.Address.ClusterScopeIndex
}
// newLineMacroReplacerHost
func (m *macrosEngine) newLineMacroReplacerHost() *strings.Replacer {
return strings.NewReplacer(
macrosNamespace, m.names.namePartNamespace(m.host.Address.Namespace),
macrosChiName, m.names.namePartChiName(m.host.Address.CHIName),
macrosChiID, m.names.namePartChiNameID(m.host.Address.CHIName),
macrosClusterName, m.names.namePartClusterName(m.host.Address.ClusterName),
macrosClusterID, m.names.namePartClusterNameID(m.host.Address.ClusterName),
macrosClusterIndex, strconv.Itoa(m.host.Address.ClusterIndex),
macrosShardName, m.names.namePartShardName(m.host.Address.ShardName),
macrosShardID, m.names.namePartShardNameID(m.host.Address.ShardName),
macrosShardIndex, strconv.Itoa(m.host.Address.ShardIndex),
macrosShardScopeIndex, strconv.Itoa(m.host.Address.ShardScopeIndex), // TODO use appropriate namePart function
macrosReplicaName, m.names.namePartReplicaName(m.host.Address.ReplicaName),
macrosReplicaID, m.names.namePartReplicaNameID(m.host.Address.ReplicaName),
macrosReplicaIndex, strconv.Itoa(m.host.Address.ReplicaIndex),
macrosReplicaScopeIndex, strconv.Itoa(m.host.Address.ReplicaScopeIndex), // TODO use appropriate namePart function
macrosHostName, m.names.namePartHostName(m.host.Address.HostName),
macrosHostID, m.names.namePartHostNameID(m.host.Address.HostName),
macrosChiScopeIndex, strconv.Itoa(m.host.Address.CHIScopeIndex), // TODO use appropriate namePart function
macrosChiScopeCycleIndex, strconv.Itoa(m.host.Address.CHIScopeCycleIndex), // TODO use appropriate namePart function
macrosChiScopeCycleOffset, strconv.Itoa(m.host.Address.CHIScopeCycleOffset), // TODO use appropriate namePart function
macrosClusterScopeIndex, strconv.Itoa(m.host.Address.ClusterScopeIndex), // TODO use appropriate namePart function
macrosClusterScopeCycleIndex, strconv.Itoa(m.host.Address.ClusterScopeCycleIndex), // TODO use appropriate namePart function
macrosClusterScopeCycleOffset, strconv.Itoa(m.host.Address.ClusterScopeCycleOffset), // TODO use appropriate namePart function
macrosClusterScopeCycleHeadPointsToPreviousCycleTail, strconv.Itoa(clusterScopeIndexOfPreviousCycleTail(m.host)),
)
}
// newMapMacroReplacerHost
func (m *macrosEngine) newMapMacroReplacerHost() *util.MapReplacer {
return util.NewMapReplacer(m.newLineMacroReplacerHost())
}