Skip to content

Commit 7b9cadd

Browse files
committed
Various improvements
1 parent 1f4cfbf commit 7b9cadd

File tree

7 files changed

+221
-29
lines changed

7 files changed

+221
-29
lines changed

dashboard/src/deployment/MemberList.js

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,7 @@
11
import React, { Component } from 'react';
2-
import styled from 'react-emotion';
32
import { Accordion, Header, Icon, List, Segment } from 'semantic-ui-react';
43
import CommandInstruction from '../util/CommandInstruction.js';
5-
6-
const Field = styled('div')`
7-
padding-top: 0.3em;
8-
padding-bottom: 0.3em;
9-
`;
10-
11-
const FieldLabel = styled('span')`
12-
width: 9rem;
13-
display: inline-block;
14-
`;
15-
16-
const FieldIcons = styled('div')`
17-
float: right;
18-
`;
4+
import { Field, FieldLabel, FieldIcons } from '../style/style';
195

206
const MemberListView = ({group, activeMemberID, onClick, members, namespace}) => (
217
<Segment>

dashboard/src/replication/DeploymentReplicationDetails.js

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import React, { Component } from 'react';
33
import api, { IsUnauthorized } from '../api/api.js';
44
import Loading from '../util/Loading.js';
55
import styled from 'react-emotion';
6-
import { Loader } from 'semantic-ui-react';
6+
import { Header, Loader, Segment } from 'semantic-ui-react';
77
import { withAuth } from '../auth/Auth.js';
8+
import { Field, FieldContent as FC, FieldLabel as FL } from '../style/style';
89

910
const LoaderBox = styled('span')`
1011
float: right;
@@ -16,6 +17,61 @@ const LoaderBox = styled('span')`
1617
display: inline-block;
1718
`;
1819

20+
const EndpointView = ({title, deploymentName, masterEndpoint, authKeyfileSecretName, authUserSecretName, tlsCACert, tlsCACertSecretName}) => (
21+
<Segment>
22+
<Header>{title}</Header>
23+
<Field>
24+
<FL>Deployment</FL>
25+
<FC>{deploymentName || "-"}</FC>
26+
</Field>
27+
<Field>
28+
<FL>Master endpoint</FL>
29+
<FC>{masterEndpoint || "-"}</FC>
30+
</Field>
31+
<Field>
32+
<FL>TLS CA Certificate</FL>
33+
<FC><code>{tlsCACert}</code></FC>
34+
</Field>
35+
<Header sub>Secret names</Header>
36+
<Field>
37+
<FL>Authentication keyfile</FL>
38+
<FC><code>{authKeyfileSecretName || "-"}</code></FC>
39+
</Field>
40+
<Field>
41+
<FL>Authentication user</FL>
42+
<FC><code>{authUserSecretName || "-"}</code></FC>
43+
</Field>
44+
<Field>
45+
<FL>TLS CA Certificate</FL>
46+
<FC><code>{tlsCACertSecretName || "-"}</code></FC>
47+
</Field>
48+
</Segment>
49+
);
50+
51+
const DetailsView = ({replication, loading}) => (
52+
<div>
53+
<LoaderBox><Loader size="mini" active={loading} inline/></LoaderBox>
54+
<EndpointView
55+
title="Source"
56+
deploymentName={replication.source.deployment_name}
57+
masterEndpoint={replication.source.master_endpoint}
58+
authKeyfileSecretName={replication.source.auth_keyfile_secret_name}
59+
authUserSecretName={replication.source.auth_user_secret_name}
60+
tlsCACert={replication.source.tls_ca_cert}
61+
tlsCACertSecretName={replication.source.tls_ca_cert_secret_name}
62+
/>
63+
<EndpointView
64+
title="Destination"
65+
deploymentName={replication.destination.deployment_name}
66+
masterEndpoint={replication.destination.master_endpoint}
67+
authKeyfileSecretName={replication.destination.auth_keyfile_secret_name}
68+
authUserSecretName={replication.destination.auth_user_secret_name}
69+
tlsCACert={replication.destination.tls_ca_cert}
70+
tlsCACertSecretName={replication.destination.tls_ca_cert_secret_name}
71+
/>
72+
</div>
73+
);
74+
1975
class DeploymentReplicationDetails extends Component {
2076
state = {
2177
loading: true,
@@ -55,12 +111,7 @@ class DeploymentReplicationDetails extends Component {
55111
if (!dr) {
56112
return (<Loading/>);
57113
}
58-
return (
59-
<div>
60-
<LoaderBox><Loader size="mini" active={this.state.loading} inline/></LoaderBox>
61-
<div>TODO</div>
62-
</div>
63-
);
114+
return (<DetailsView replication={dr} loading={this.state.loading}/>);
64115
}
65116
}
66117

dashboard/src/replication/DeploymentReplicationList.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const HeaderView = ({loading}) => (
2121
<Table.Row>
2222
<Table.HeaderCell>State</Table.HeaderCell>
2323
<Table.HeaderCell>Name</Table.HeaderCell>
24+
<Table.HeaderCell>Source</Table.HeaderCell>
25+
<Table.HeaderCell>Destination</Table.HeaderCell>
2426
<Table.HeaderCell>
2527
Actions
2628
<LoaderBox><Loader size="mini" active={loading} inline/></LoaderBox>
@@ -29,7 +31,7 @@ const HeaderView = ({loading}) => (
2931
</Table.Header>
3032
);
3133

32-
const RowView = ({name, mode, stateColor, deleteCommand, describeCommand}) => (
34+
const RowView = ({name, mode, stateColor, source, destination, deleteCommand, describeCommand}) => (
3335
<Table.Row>
3436
<Table.Cell>
3537
<Popup trigger={<Icon name={(stateColor==="green") ? "check" : "bell"} color={stateColor}/>}>
@@ -41,6 +43,12 @@ const RowView = ({name, mode, stateColor, deleteCommand, describeCommand}) => (
4143
{name}
4244
</Link>
4345
</Table.Cell>
46+
<Table.Cell>
47+
{source}
48+
</Table.Cell>
49+
<Table.Cell>
50+
{destination}
51+
</Table.Cell>
4452
<Table.Cell>
4553
<CommandInstruction
4654
trigger={<Icon link name="zoom"/>}
@@ -71,6 +79,8 @@ const ListView = ({items, loading}) => (
7179
name={item.name}
7280
namespace={item.namespace}
7381
stateColor={item.state_color}
82+
source={item.source.deployment_name || item.source.master_endpoint}
83+
destination={item.destination.deployment_name || item.destination.master_endpoint}
7484
deleteCommand={createDeleteCommand(item.name, item.namespace)}
7585
describeCommand={createDescribeCommand(item.name, item.namespace)}
7686
/>) : <p>No items</p>

dashboard/src/style/style.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import styled from 'react-emotion';
2+
3+
export const Field = styled('div')`
4+
padding-top: 0.3em;
5+
padding-bottom: 0.3em;
6+
clear: both;
7+
`;
8+
9+
export const FieldLabel = styled('span')`
10+
width: 9rem;
11+
display: inline-block;
12+
float: left;
13+
`;
14+
15+
export const FieldContent = styled('div')`
16+
display: inline-block;
17+
`;
18+
19+
export const FieldIcons = styled('div')`
20+
float: right;
21+
`;

pkg/replication/server_api.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,19 @@ func (dr *DeploymentReplication) StateColor() server.StateColor {
4848
}
4949
return server.StateYellow
5050
}
51+
52+
// Source provides info on the source of the replication
53+
func (dr *DeploymentReplication) Source() server.Endpoint {
54+
return serverEndpoint{
55+
dr: dr,
56+
getSpec: func() api.EndpointSpec { return dr.apiObject.Spec.Source },
57+
}
58+
}
59+
60+
// Destination provides info on the destination of the replication
61+
func (dr *DeploymentReplication) Destination() server.Endpoint {
62+
return serverEndpoint{
63+
dr: dr,
64+
getSpec: func() api.EndpointSpec { return dr.apiObject.Spec.Destination },
65+
}
66+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package replication
24+
25+
import (
26+
api "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1alpha"
27+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
28+
)
29+
30+
type serverEndpoint struct {
31+
dr *DeploymentReplication
32+
getSpec func() api.EndpointSpec
33+
}
34+
35+
// DeploymentName returns the name of the ArangoDeployment of this endpoint
36+
func (ep serverEndpoint) DeploymentName() string {
37+
return ep.getSpec().GetDeploymentName()
38+
}
39+
40+
// MasterEndpoint returns the URLs of the custom master endpoint
41+
func (ep serverEndpoint) MasterEndpoint() []string {
42+
return ep.getSpec().MasterEndpoint
43+
}
44+
45+
// AuthKeyfileSecretName returns the name of a Secret containing the authentication keyfile
46+
// for accessing the syncmaster at this endpoint
47+
func (ep serverEndpoint) AuthKeyfileSecretName() string {
48+
return ep.getSpec().Authentication.GetKeyfileSecretName()
49+
}
50+
51+
// AuthUserSecretName returns the name of a Secret containing the authentication username+password
52+
// for accessing the syncmaster at this endpoint
53+
func (ep serverEndpoint) AuthUserSecretName() string {
54+
return ep.getSpec().Authentication.GetUserSecretName()
55+
}
56+
57+
// TLSCACert returns a PEM encoded TLS CA certificate of the syncmaster at this endpoint
58+
func (ep serverEndpoint) TLSCACert() string {
59+
tlsCASecretName := ep.getSpec().TLS.GetCASecretName()
60+
caCert, err := k8sutil.GetCACertficateSecret(ep.dr.deps.KubeCli.CoreV1(), tlsCASecretName, ep.dr.apiObject.GetNamespace())
61+
if err != nil {
62+
return ""
63+
}
64+
return caCert
65+
}
66+
67+
// TLSCACertSecretName returns the name of a Secret containing the TLS CA certificate of the syncmaster at this endpoint
68+
func (ep serverEndpoint) TLSCACertSecretName() string {
69+
return ep.getSpec().TLS.GetCASecretName()
70+
}

pkg/server/handlers_replication.go

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ type DeploymentReplication interface {
3333
Name() string
3434
Namespace() string
3535
StateColor() StateColor
36+
Source() Endpoint
37+
Destination() Endpoint
3638
}
3739

3840
// DeploymentReplicationOperator is the API implemented by the deployment operator.
@@ -45,17 +47,53 @@ type DeploymentReplicationOperator interface {
4547

4648
// DeploymentReplicationInfo is the information returned per deployment replication.
4749
type DeploymentReplicationInfo struct {
48-
Name string `json:"name"`
49-
Namespace string `json:"namespace"`
50-
StateColor StateColor `json:"state_color"`
50+
Name string `json:"name"`
51+
Namespace string `json:"namespace"`
52+
StateColor StateColor `json:"state_color"`
53+
Source EndpointInfo `json:"source"`
54+
Destination EndpointInfo `json:"destination"`
5155
}
5256

5357
// newDeploymentReplicationInfo initializes a DeploymentReplicationInfo for the given deployment replication.
5458
func newDeploymentReplicationInfo(dr DeploymentReplication) DeploymentReplicationInfo {
5559
return DeploymentReplicationInfo{
56-
Name: dr.Name(),
57-
Namespace: dr.Namespace(),
58-
StateColor: dr.StateColor(),
60+
Name: dr.Name(),
61+
Namespace: dr.Namespace(),
62+
StateColor: dr.StateColor(),
63+
Source: newEndpointInfo(dr.Source()),
64+
Destination: newEndpointInfo(dr.Destination()),
65+
}
66+
}
67+
68+
// Endpoint is the API implemented by source&destination of the replication
69+
type Endpoint interface {
70+
DeploymentName() string
71+
MasterEndpoint() []string
72+
AuthKeyfileSecretName() string
73+
AuthUserSecretName() string
74+
TLSCACert() string
75+
TLSCACertSecretName() string
76+
}
77+
78+
// EndpointInfo is the information returned per source/destination endpoint of the replication.
79+
type EndpointInfo struct {
80+
DeploymentName string `json:"deployment_name"`
81+
MasterEndpoint []string `json:"master_endpoint"`
82+
AuthKeyfileSecretName string `json:"auth_keyfile_secret_name"`
83+
AuthUserSecretName string `json:"auth_user_secret_name"`
84+
TLSCACert string `json:"tls_ca_cert"`
85+
TLSCACertSecretName string `json:"tls_ca_cert_secret_name"`
86+
}
87+
88+
// newEndpointInfo initializes an EndpointInfo for the given Endpoint.
89+
func newEndpointInfo(ep Endpoint) EndpointInfo {
90+
return EndpointInfo{
91+
DeploymentName: ep.DeploymentName(),
92+
MasterEndpoint: ep.MasterEndpoint(),
93+
AuthKeyfileSecretName: ep.AuthKeyfileSecretName(),
94+
AuthUserSecretName: ep.AuthUserSecretName(),
95+
TLSCACert: ep.TLSCACert(),
96+
TLSCACertSecretName: ep.TLSCACertSecretName(),
5997
}
6098
}
6199

0 commit comments

Comments
 (0)