forked from openshift/origin
/
router.go
158 lines (139 loc) · 5.01 KB
/
router.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
package router
import (
"fmt"
"time"
"github.com/golang/glog"
"github.com/spf13/pflag"
kclient "k8s.io/kubernetes/pkg/client"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util"
oclient "github.com/openshift/origin/pkg/client"
cmdutil "github.com/openshift/origin/pkg/cmd/util"
controllerfactory "github.com/openshift/origin/pkg/router/controller/factory"
)
// RouterSelection controls what routes and resources on the server are considered
// part of this router.
type RouterSelection struct {
ResyncInterval time.Duration
LabelSelector string
Labels labels.Selector
FieldSelector string
Fields fields.Selector
Namespace string
NamespaceLabelSelector string
NamespaceLabels labels.Selector
ProjectLabelSelector string
ProjectLabels labels.Selector
}
// Bind sets the appropriate labels
func (o *RouterSelection) Bind(flag *pflag.FlagSet) {
flag.DurationVar(&o.ResyncInterval, "resync-interval", 10*time.Minute, "The interval at which the route list should be fully refreshed")
flag.StringVar(&o.LabelSelector, "labels", cmdutil.Env("ROUTE_LABELS", ""), "A label selector to apply to the routes to watch")
flag.StringVar(&o.FieldSelector, "fields", cmdutil.Env("ROUTE_FIELDS", ""), "A field selector to apply to routes to watch")
flag.StringVar(&o.ProjectLabelSelector, "project-labels", cmdutil.Env("PROJECT_LABELS", ""), "A label selector to apply to projects to watch; if '*' watches all projects the client can access")
flag.StringVar(&o.NamespaceLabelSelector, "namespace-labels", cmdutil.Env("NAMESPACE_LABELS", ""), "A label selector to apply to namespaces to watch")
}
// Complete converts string representations of field and label selectors to their parsed equivalent, or
// returns an error.
func (o *RouterSelection) Complete() error {
if len(o.LabelSelector) > 0 {
s, err := labels.Parse(o.LabelSelector)
if err != nil {
return fmt.Errorf("label selector is not valid: %v", err)
}
o.Labels = s
} else {
o.Labels = labels.Everything()
}
if len(o.FieldSelector) > 0 {
s, err := fields.ParseSelector(o.FieldSelector)
if err != nil {
return fmt.Errorf("field selector is not valid: %v", err)
}
o.Fields = s
} else {
o.Fields = fields.Everything()
}
if len(o.ProjectLabelSelector) > 0 {
if len(o.Namespace) > 0 {
return fmt.Errorf("only one of --project-labels and --namespace may be used")
}
if len(o.NamespaceLabelSelector) > 0 {
return fmt.Errorf("only one of --namespace-labels and --project-labels may be used")
}
if o.ProjectLabelSelector == "*" {
o.ProjectLabels = labels.Everything()
} else {
s, err := labels.Parse(o.ProjectLabelSelector)
if err != nil {
return fmt.Errorf("--project-labels selector is not valid: %v", err)
}
o.ProjectLabels = s
}
}
if len(o.NamespaceLabelSelector) > 0 {
if len(o.Namespace) > 0 {
return fmt.Errorf("only one of --namespace-labels and --namespace may be used")
}
s, err := labels.Parse(o.NamespaceLabelSelector)
if err != nil {
return fmt.Errorf("--namespace-labels selector is not valid: %v", err)
}
o.NamespaceLabels = s
}
return nil
}
// NewFactory initializes a factory that will watch the requested routes
func (o *RouterSelection) NewFactory(oc oclient.Interface, kc kclient.Interface) *controllerfactory.RouterControllerFactory {
factory := controllerfactory.NewDefaultRouterControllerFactory(oc, kc)
factory.Labels = o.Labels
factory.Fields = o.Fields
factory.Namespace = o.Namespace
factory.ResyncInterval = o.ResyncInterval
switch {
case o.NamespaceLabels != nil:
glog.Infof("Router is only using routes in namespaces matching %s", o.NamespaceLabels)
factory.Namespaces = namespaceNames{kc.Namespaces(), o.NamespaceLabels}
case o.ProjectLabels != nil:
glog.Infof("Router is only using routes in projects matching %s", o.ProjectLabels)
factory.Namespaces = projectNames{oc.Projects(), o.ProjectLabels}
case len(factory.Namespace) > 0:
glog.Infof("Router is only using resources in namespace %s", factory.Namespace)
default:
glog.Infof("Router is including routes in all namespaces")
}
return factory
}
// projectNames returns the names of projects matching the label selector
type projectNames struct {
client oclient.ProjectInterface
selector labels.Selector
}
func (n projectNames) NamespaceNames() (util.StringSet, error) {
all, err := n.client.List(n.selector, fields.Everything())
if err != nil {
return nil, err
}
names := make(util.StringSet, len(all.Items))
for i := range all.Items {
names.Insert(all.Items[i].Name)
}
return names, nil
}
// namespaceNames returns the names of namespaces matching the label selector
type namespaceNames struct {
client kclient.NamespaceInterface
selector labels.Selector
}
func (n namespaceNames) NamespaceNames() (util.StringSet, error) {
all, err := n.client.List(n.selector, fields.Everything())
if err != nil {
return nil, err
}
names := make(util.StringSet, len(all.Items))
for i := range all.Items {
names.Insert(all.Items[i].Name)
}
return names, nil
}