forked from gravitational/teleport
/
api_with_roles.go
101 lines (88 loc) · 2.81 KB
/
api_with_roles.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
/*
Copyright 2020 Gravitational, Inc.
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 reversetunnel
import (
"github.com/gravitational/trace"
"github.com/sirupsen/logrus"
"github.com/zmb3/teleport/api/types"
"github.com/zmb3/teleport/lib/services"
"github.com/zmb3/teleport/lib/utils"
)
// ClusterGetter is an interface that defines GetRemoteCluster method
type ClusterGetter interface {
// GetRemoteCluster returns a remote cluster by name
GetRemoteCluster(clusterName string) (types.RemoteCluster, error)
}
// NewTunnelWithRoles returns new authorizing tunnel
func NewTunnelWithRoles(tunnel Tunnel, accessChecker services.AccessChecker, access ClusterGetter) *TunnelWithRoles {
return &TunnelWithRoles{
tunnel: tunnel,
accessChecker: accessChecker,
access: access,
}
}
// TunnelWithRoles authorizes requests
type TunnelWithRoles struct {
tunnel Tunnel
// accessChecker is used to check RBAC permissions.
accessChecker services.AccessChecker
access ClusterGetter
}
// GetSites returns a list of connected remote sites
func (t *TunnelWithRoles) GetSites() ([]RemoteSite, error) {
clusters, err := t.tunnel.GetSites()
if err != nil {
return nil, trace.Wrap(err)
}
out := make([]RemoteSite, 0, len(clusters))
for _, cluster := range clusters {
if _, ok := cluster.(*localSite); ok {
out = append(out, cluster)
continue
}
rc, err := t.access.GetRemoteCluster(cluster.GetName())
if err != nil {
if !trace.IsNotFound(err) {
return nil, trace.Wrap(err)
}
logrus.Warningf("Skipping dangling cluster %q, no remote cluster resource found.", cluster.GetName())
continue
}
if err := t.accessChecker.CheckAccessToRemoteCluster(rc); err != nil {
if !trace.IsAccessDenied(err) {
return nil, trace.Wrap(err)
}
continue
}
out = append(out, cluster)
}
return out, nil
}
// GetSite returns remote site this node belongs to
func (t *TunnelWithRoles) GetSite(clusterName string) (RemoteSite, error) {
cluster, err := t.tunnel.GetSite(clusterName)
if err != nil {
return nil, trace.Wrap(err)
}
if _, ok := cluster.(*localSite); ok {
return cluster, nil
}
rc, err := t.access.GetRemoteCluster(clusterName)
if err != nil {
return nil, trace.Wrap(err)
}
if err := t.accessChecker.CheckAccessToRemoteCluster(rc); err != nil {
return nil, utils.OpaqueAccessDenied(err)
}
return cluster, nil
}