deprecate ClusterName field of Postgresql type and remove team from REST endpoints (#2015)
* deprecate ClusterName field of Postgresql type * remove for teamId from operator API endpints /status /logs /history * update dns_format_string and yaml template in UI
This commit is contained in:
parent
89375186b3
commit
4c07494ac7
|
|
@ -36,6 +36,9 @@ type PostgresSpec struct {
|
|||
TeamID string `json:"teamId"`
|
||||
DockerImage string `json:"dockerImage,omitempty"`
|
||||
|
||||
// deprecated field storing cluster name without teamId prefix
|
||||
ClusterName string `json:"-"`
|
||||
|
||||
SpiloRunAsUser *int64 `json:"spiloRunAsUser,omitempty"`
|
||||
SpiloRunAsGroup *int64 `json:"spiloRunAsGroup,omitempty"`
|
||||
SpiloFSGroup *int64 `json:"spiloFSGroup,omitempty"`
|
||||
|
|
@ -62,7 +65,6 @@ type PostgresSpec struct {
|
|||
NumberOfInstances int32 `json:"numberOfInstances"`
|
||||
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
||||
Clone *CloneDescription `json:"clone,omitempty"`
|
||||
ClusterName string `json:"-"`
|
||||
Databases map[string]string `json:"databases,omitempty"`
|
||||
PreparedDatabases map[string]PreparedDatabase `json:"preparedDatabases,omitempty"`
|
||||
SchedulerName *string `json:"schedulerName,omitempty"`
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ type controllerInformer interface {
|
|||
GetOperatorConfig() *config.Config
|
||||
GetStatus() *spec.ControllerStatus
|
||||
TeamClusterList() map[string][]spec.NamespacedName
|
||||
ClusterStatus(team, namespace, cluster string) (*cluster.ClusterStatus, error)
|
||||
ClusterLogs(team, namespace, cluster string) ([]*spec.LogEntry, error)
|
||||
ClusterHistory(team, namespace, cluster string) ([]*spec.Diff, error)
|
||||
ClusterStatus(namespace, cluster string) (*cluster.ClusterStatus, error)
|
||||
ClusterLogs(namespace, cluster string) ([]*spec.LogEntry, error)
|
||||
ClusterHistory(namespace, cluster string) ([]*spec.Diff, error)
|
||||
ClusterDatabasesMap() map[string][]string
|
||||
WorkerLogs(workerID uint32) ([]*spec.LogEntry, error)
|
||||
ListQueue(workerID uint32) (*spec.QueueDump, error)
|
||||
|
|
@ -55,9 +55,9 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
clusterStatusRe = fmt.Sprintf(`^/clusters/%s/%s/%s/?$`, teamRe, namespaceRe, clusterRe)
|
||||
clusterLogsRe = fmt.Sprintf(`^/clusters/%s/%s/%s/logs/?$`, teamRe, namespaceRe, clusterRe)
|
||||
clusterHistoryRe = fmt.Sprintf(`^/clusters/%s/%s/%s/history/?$`, teamRe, namespaceRe, clusterRe)
|
||||
clusterStatusRe = fmt.Sprintf(`^/clusters/%s/%s/?$`, namespaceRe, clusterRe)
|
||||
clusterLogsRe = fmt.Sprintf(`^/clusters/%s/%s/logs/?$`, namespaceRe, clusterRe)
|
||||
clusterHistoryRe = fmt.Sprintf(`^/clusters/%s/%s/history/?$`, namespaceRe, clusterRe)
|
||||
teamURLRe = fmt.Sprintf(`^/clusters/%s/?$`, teamRe)
|
||||
|
||||
clusterStatusURL = regexp.MustCompile(clusterStatusRe)
|
||||
|
|
@ -170,7 +170,7 @@ func (s *Server) clusters(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
if matches := util.FindNamedStringSubmatch(clusterStatusURL, req.URL.Path); matches != nil {
|
||||
namespace := matches["namespace"]
|
||||
resp, err = s.controller.ClusterStatus(matches["team"], namespace, matches["cluster"])
|
||||
resp, err = s.controller.ClusterStatus(namespace, matches["cluster"])
|
||||
} else if matches := util.FindNamedStringSubmatch(teamURL, req.URL.Path); matches != nil {
|
||||
teamClusters := s.controller.TeamClusterList()
|
||||
clusters, found := teamClusters[matches["team"]]
|
||||
|
|
@ -181,21 +181,21 @@ func (s *Server) clusters(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
clusterNames := make([]string, 0)
|
||||
for _, cluster := range clusters {
|
||||
clusterNames = append(clusterNames, cluster.Name[len(matches["team"])+1:])
|
||||
clusterNames = append(clusterNames, cluster.Name)
|
||||
}
|
||||
|
||||
resp, err = clusterNames, nil
|
||||
} else if matches := util.FindNamedStringSubmatch(clusterLogsURL, req.URL.Path); matches != nil {
|
||||
namespace := matches["namespace"]
|
||||
resp, err = s.controller.ClusterLogs(matches["team"], namespace, matches["cluster"])
|
||||
resp, err = s.controller.ClusterLogs(namespace, matches["cluster"])
|
||||
} else if matches := util.FindNamedStringSubmatch(clusterHistoryURL, req.URL.Path); matches != nil {
|
||||
namespace := matches["namespace"]
|
||||
resp, err = s.controller.ClusterHistory(matches["team"], namespace, matches["cluster"])
|
||||
resp, err = s.controller.ClusterHistory(namespace, matches["cluster"])
|
||||
} else if req.URL.Path == clustersURL {
|
||||
clusterNamesPerTeam := make(map[string][]string)
|
||||
for team, clusters := range s.controller.TeamClusterList() {
|
||||
for _, cluster := range clusters {
|
||||
clusterNamesPerTeam[team] = append(clusterNamesPerTeam[team], cluster.Name[len(team)+1:])
|
||||
clusterNamesPerTeam[team] = append(clusterNamesPerTeam[team], cluster.Name)
|
||||
}
|
||||
}
|
||||
resp, err = clusterNamesPerTeam, nil
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
clusterStatusTest = "/clusters/test-id/test_namespace/testcluster/"
|
||||
clusterStatusNumericTest = "/clusters/test-id-1/test_namespace/testcluster/"
|
||||
clusterLogsTest = "/clusters/test-id/test_namespace/testcluster/logs/"
|
||||
clusterStatusTest = "/clusters/test-namespace/testcluster/"
|
||||
clusterStatusNumericTest = "/clusters/test-namespace-1/testcluster/"
|
||||
clusterLogsTest = "/clusters/test-namespace/testcluster/logs/"
|
||||
teamTest = "/clusters/test-id/"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1478,7 +1478,8 @@ func (c *Cluster) GetCurrentProcess() Process {
|
|||
// GetStatus provides status of the cluster
|
||||
func (c *Cluster) GetStatus() *ClusterStatus {
|
||||
status := &ClusterStatus{
|
||||
Cluster: c.Spec.ClusterName,
|
||||
Cluster: c.Name,
|
||||
Namespace: c.Namespace,
|
||||
Team: c.Spec.TeamID,
|
||||
Status: c.Status,
|
||||
Spec: c.Spec,
|
||||
|
|
|
|||
|
|
@ -587,7 +587,7 @@ func TestServiceAnnotations(t *testing.T) {
|
|||
clusterAnnotations: make(map[string]string),
|
||||
operatorAnnotations: make(map[string]string),
|
||||
expect: map[string]string{
|
||||
"external-dns.alpha.kubernetes.io/hostname": "test.test.db.example.com",
|
||||
"external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com",
|
||||
"service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600",
|
||||
},
|
||||
},
|
||||
|
|
@ -723,7 +723,7 @@ func TestServiceAnnotations(t *testing.T) {
|
|||
clusterAnnotations: make(map[string]string),
|
||||
operatorAnnotations: make(map[string]string),
|
||||
expect: map[string]string{
|
||||
"external-dns.alpha.kubernetes.io/hostname": "test-repl.test.db.example.com",
|
||||
"external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com",
|
||||
"service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600",
|
||||
},
|
||||
},
|
||||
|
|
@ -751,11 +751,6 @@ func TestServiceAnnotations(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.about, func(t *testing.T) {
|
||||
cl.OpConfig.EnableTeamIdClusternamePrefix = tt.enableTeamIdClusterPrefix
|
||||
if tt.enableTeamIdClusterPrefix {
|
||||
cl.Postgresql.Spec.ClusterName = "test"
|
||||
} else {
|
||||
cl.Postgresql.Spec.ClusterName = "acid-test"
|
||||
}
|
||||
|
||||
cl.OpConfig.CustomServiceAnnotations = tt.operatorAnnotations
|
||||
cl.OpConfig.EnableMasterLoadBalancer = tt.enableMasterLoadBalancerOC
|
||||
|
|
@ -764,6 +759,7 @@ func TestServiceAnnotations(t *testing.T) {
|
|||
cl.OpConfig.ReplicaDNSNameFormat = "{cluster}-repl.{namespace}.{hostedzone}"
|
||||
cl.OpConfig.DbHostedZone = "db.example.com"
|
||||
|
||||
cl.Postgresql.Spec.ClusterName = ""
|
||||
cl.Postgresql.Spec.TeamID = "acid"
|
||||
cl.Postgresql.Spec.ServiceAnnotations = tt.clusterAnnotations
|
||||
cl.Postgresql.Spec.EnableMasterLoadBalancer = tt.enableMasterLoadBalancerSpec
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ type WorkerStatus struct {
|
|||
type ClusterStatus struct {
|
||||
Team string
|
||||
Cluster string
|
||||
Namespace string
|
||||
MasterService *v1.Service
|
||||
ReplicaService *v1.Service
|
||||
MasterEndpoint *v1.Endpoints
|
||||
|
|
|
|||
|
|
@ -507,22 +507,20 @@ func (c *Cluster) roleLabelsSet(shouldAddExtraLabels bool, role PostgresRole) la
|
|||
|
||||
func (c *Cluster) dnsName(role PostgresRole) string {
|
||||
var dnsString string
|
||||
|
||||
if role == Master {
|
||||
dnsString = c.masterDNSName()
|
||||
} else {
|
||||
dnsString = c.replicaDNSName()
|
||||
}
|
||||
|
||||
// when cluster name starts with teamId prefix create an extra DNS entry
|
||||
// to support the old format when prefix contraint was enabled (but is disabled now)
|
||||
if !c.OpConfig.EnableTeamIdClusternamePrefix {
|
||||
clusterNameWithoutTeamPrefix, _ := acidv1.ExtractClusterName(c.Name, c.Spec.TeamID)
|
||||
if clusterNameWithoutTeamPrefix != "" {
|
||||
if role == Replica {
|
||||
clusterNameWithoutTeamPrefix = fmt.Sprintf("%s-repl", clusterNameWithoutTeamPrefix)
|
||||
}
|
||||
dnsString = fmt.Sprintf("%s,%s", dnsString, c.oldDNSFormat(clusterNameWithoutTeamPrefix))
|
||||
// if cluster name starts with teamID we might need to provide backwards compatibility
|
||||
clusterNameWithoutTeamPrefix, _ := acidv1.ExtractClusterName(c.Name, c.Spec.TeamID)
|
||||
if clusterNameWithoutTeamPrefix != "" {
|
||||
if role == Replica {
|
||||
clusterNameWithoutTeamPrefix = fmt.Sprintf("%s-repl", clusterNameWithoutTeamPrefix)
|
||||
}
|
||||
dnsString = fmt.Sprintf("%s,%s", dnsString, c.oldDNSFormat(clusterNameWithoutTeamPrefix))
|
||||
}
|
||||
|
||||
return dnsString
|
||||
|
|
@ -530,15 +528,17 @@ func (c *Cluster) dnsName(role PostgresRole) string {
|
|||
|
||||
func (c *Cluster) masterDNSName() string {
|
||||
return strings.ToLower(c.OpConfig.MasterDNSNameFormat.Format(
|
||||
"cluster", c.Spec.ClusterName,
|
||||
"cluster", c.Name,
|
||||
"namespace", c.Namespace,
|
||||
"team", c.teamName(),
|
||||
"hostedzone", c.OpConfig.DbHostedZone))
|
||||
}
|
||||
|
||||
func (c *Cluster) replicaDNSName() string {
|
||||
return strings.ToLower(c.OpConfig.ReplicaDNSNameFormat.Format(
|
||||
"cluster", c.Spec.ClusterName,
|
||||
"cluster", c.Name,
|
||||
"namespace", c.Namespace,
|
||||
"team", c.teamName(),
|
||||
"hostedzone", c.OpConfig.DbHostedZone))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ import (
|
|||
)
|
||||
|
||||
// ClusterStatus provides status of the cluster
|
||||
func (c *Controller) ClusterStatus(team, namespace, cluster string) (*cluster.ClusterStatus, error) {
|
||||
func (c *Controller) ClusterStatus(namespace, cluster string) (*cluster.ClusterStatus, error) {
|
||||
|
||||
clusterName := spec.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: team + "-" + cluster,
|
||||
Name: cluster,
|
||||
}
|
||||
|
||||
c.clustersMu.RLock()
|
||||
|
|
@ -92,11 +92,11 @@ func (c *Controller) GetStatus() *spec.ControllerStatus {
|
|||
}
|
||||
|
||||
// ClusterLogs dumps cluster ring logs
|
||||
func (c *Controller) ClusterLogs(team, namespace, name string) ([]*spec.LogEntry, error) {
|
||||
func (c *Controller) ClusterLogs(namespace, name string) ([]*spec.LogEntry, error) {
|
||||
|
||||
clusterName := spec.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: team + "-" + name,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
c.clustersMu.RLock()
|
||||
|
|
@ -215,11 +215,11 @@ func (c *Controller) WorkerStatus(workerID uint32) (*cluster.WorkerStatus, error
|
|||
}
|
||||
|
||||
// ClusterHistory dumps history of cluster changes
|
||||
func (c *Controller) ClusterHistory(team, namespace, name string) ([]*spec.Diff, error) {
|
||||
func (c *Controller) ClusterHistory(namespace, name string) ([]*spec.Diff, error) {
|
||||
|
||||
clusterName := spec.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: team + "-" + name,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
c.clustersMu.RLock()
|
||||
|
|
|
|||
|
|
@ -159,24 +159,16 @@ func (c *Controller) acquireInitialListOfClusters() error {
|
|||
}
|
||||
|
||||
func (c *Controller) addCluster(lg *logrus.Entry, clusterName spec.NamespacedName, pgSpec *acidv1.Postgresql) (*cluster.Cluster, error) {
|
||||
var (
|
||||
extractedClusterName string
|
||||
err error
|
||||
)
|
||||
|
||||
if c.opConfig.EnableTeamIdClusternamePrefix {
|
||||
if extractedClusterName, err = acidv1.ExtractClusterName(clusterName.Name, pgSpec.Spec.TeamID); err != nil {
|
||||
if _, err := acidv1.ExtractClusterName(clusterName.Name, pgSpec.Spec.TeamID); err != nil {
|
||||
c.KubeClient.SetPostgresCRDStatus(clusterName, acidv1.ClusterStatusInvalid)
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
extractedClusterName = clusterName.Name
|
||||
}
|
||||
|
||||
cl := cluster.New(c.makeClusterConfig(), c.KubeClient, *pgSpec, lg, c.eventRecorder)
|
||||
cl.Run(c.stopCh)
|
||||
teamName := strings.ToLower(cl.Spec.TeamID)
|
||||
cl.ClusterName = extractedClusterName
|
||||
|
||||
defer c.clustersMu.Unlock()
|
||||
c.clustersMu.Lock()
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ new
|
|||
|
||||
a.btn.btn-small.btn-warning(
|
||||
if='{ clusterExists }'
|
||||
href='/#/status/{ namespace.state }/{ team }-{ name }'
|
||||
href='/#/status/{ namespace.state }/{ name }'
|
||||
)
|
||||
| Cluster exists (show status)
|
||||
|
||||
|
|
@ -137,10 +137,10 @@ new
|
|||
input.form-control(
|
||||
ref='name'
|
||||
type='text'
|
||||
placeholder='new-cluster (can be { 53 - team.length - 1 } characters long)'
|
||||
placeholder='new-cluster (can be 53 characters long)'
|
||||
title='Database cluster name, must be a valid hostname component'
|
||||
pattern='[a-z0-9]+[a-z0-9\-]+[a-z0-9]+'
|
||||
maxlength='{ 53 - team.length - 1 }'
|
||||
maxlength=53
|
||||
required
|
||||
value='{ name }'
|
||||
onchange='{ nameChange }'
|
||||
|
|
@ -520,7 +520,7 @@ new
|
|||
apiVersion: "acid.zalan.do/v1"
|
||||
|
||||
metadata:
|
||||
name: "{{ team }}-{{ name }}"
|
||||
name: "{{ name }}"
|
||||
namespace: "{{ namespace.state }}"
|
||||
labels:
|
||||
team: {{ team }}
|
||||
|
|
@ -670,13 +670,12 @@ new
|
|||
this.updateDNSName = () => {
|
||||
this.dnsName = this.config.dns_format_string.format(
|
||||
this.name,
|
||||
this.team,
|
||||
this.namespace.state,
|
||||
)
|
||||
}
|
||||
|
||||
this.updateClusterName = () => {
|
||||
this.clusterName = (this.team + '-' + this.name).toLowerCase()
|
||||
this.clusterName = (this.name).toLowerCase()
|
||||
this.checkClusterExists()
|
||||
this.updateDNSName()
|
||||
}
|
||||
|
|
@ -950,7 +949,7 @@ new
|
|||
this.team = ''
|
||||
}
|
||||
|
||||
this.clusterName = (this.name + '-' + this.team).toLowerCase()
|
||||
this.clusterName = (this.name + '-').toLowerCase()
|
||||
this.volumeSize = 10
|
||||
this.instanceCount = 1
|
||||
this.ranges = {}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ spec:
|
|||
value: |-
|
||||
{
|
||||
"docs_link":"https://postgres-operator.readthedocs.io/en/latest/",
|
||||
"dns_format_string": "{1}-{0}.{2}",
|
||||
"dns_format_string": "{0}.{1}",
|
||||
"databases_visible": true,
|
||||
"master_load_balancer_visible": true,
|
||||
"nat_gateways_visible": false,
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ DEFAULT_UI_CONFIG = {
|
|||
'databases_visible': True,
|
||||
'resources_visible': RESOURCES_VISIBLE,
|
||||
'postgresql_versions': ['11','12','13','14'],
|
||||
'dns_format_string': '{0}.{1}.{2}',
|
||||
'dns_format_string': '{0}.{1}',
|
||||
'pgui_link': '',
|
||||
'static_network_whitelist': {},
|
||||
'read_only_mode': READ_ONLY_MODE,
|
||||
|
|
@ -981,15 +981,7 @@ def get_operator_get_logs(worker: int):
|
|||
@app.route('/operator/clusters/<namespace>/<cluster>/logs')
|
||||
@authorize
|
||||
def get_operator_get_logs_per_cluster(namespace: str, cluster: str):
|
||||
team, cluster_name = cluster.split('-', 1)
|
||||
# team id might contain hyphens, try to find correct team name
|
||||
user_teams = get_teams_for_user(session.get('user_name', ''))
|
||||
for user_team in user_teams:
|
||||
if cluster.find(user_team + '-') == 0:
|
||||
team = cluster[:len(user_team)]
|
||||
cluster_name = cluster[len(user_team + '-'):]
|
||||
break
|
||||
return proxy_operator(f'/clusters/{team}/{namespace}/{cluster_name}/logs/')
|
||||
return proxy_operator(f'/clusters/{namespace}/{cluster}/logs/')
|
||||
|
||||
|
||||
@app.route('/login')
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export TARGET_NAMESPACE="${TARGET_NAMESPACE-*}"
|
|||
|
||||
default_operator_ui_config='{
|
||||
"docs_link":"https://postgres-operator.readthedocs.io/en/latest/",
|
||||
"dns_format_string": "{1}-{0}.{2}",
|
||||
"dns_format_string": "{0}.{1}",
|
||||
"databases_visible": true,
|
||||
"nat_gateways_visible": false,
|
||||
"resources_visible": true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue