Skip to content

Commit bdceddc

Browse files
authored
Merge pull request #136 from projectsyn/collect-ocp-and-additional-facts
Collect OCP OAuth route and additional facts
2 parents 9c10d17 + 506f6bf commit bdceddc

File tree

9 files changed

+165
-17
lines changed

9 files changed

+165
-17
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
k8s.io/apimachinery v0.28.3
1717
k8s.io/client-go v0.28.3
1818
k8s.io/klog v1.0.0
19+
sigs.k8s.io/controller-runtime v0.16.3
1920
)
2021

2122
require (
@@ -118,7 +119,6 @@ require (
118119
k8s.io/klog/v2 v2.110.1 // indirect
119120
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
120121
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
121-
sigs.k8s.io/controller-runtime v0.16.3 // indirect
122122
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
123123
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
124124
sigs.k8s.io/yaml v1.4.0 // indirect

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU
6464
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
6565
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
6666
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
67+
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
68+
github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
6769
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
6870
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
6971
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
@@ -273,6 +275,8 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
273275
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
274276
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
275277
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
278+
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
279+
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
276280
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
277281
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
278282
golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=

main.go

+18
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,24 @@ func main() {
4848
app.Flag("operator-namespace", "Namespace in which the ArgoCD operator will be running").Default("syn-argocd-operator").StringVar(&agent.OperatorNamespace)
4949
app.Flag("argo-image", "Image to be used for the Argo CD deployments").Default(images.DefaultArgoCDImage).StringVar(&agent.ArgoCDImage)
5050
app.Flag("redis-image", "Image to be used for the Argo CD Redis deployment").Default(images.DefaultRedisImage).StringVar(&agent.RedisImage)
51+
app.
52+
Flag(
53+
"additional-facts-config-map",
54+
"Additional facts added to the dynamic facts in the cluster object. Keys in the configmap's data field can't override existing keys.").
55+
Default("additional-facts").
56+
StringVar(&agent.AdditionalFactsConfigMap)
57+
app.
58+
Flag(
59+
"ocp-oauth-route-namespace",
60+
"Namespace for the OpenShift OAuth route").
61+
Default("openshift-authentication").
62+
StringVar(&agent.OCPOAuthRouteNamespace)
63+
app.
64+
Flag(
65+
"ocp-oauth-route-name",
66+
"Name of the OpenShift OAuth route").
67+
Default("oauth-openshift").
68+
StringVar(&agent.OCPOAuthRouteName)
5169

5270
kingpin.MustParse(app.Parse(os.Args[1:]))
5371
}

pkg/agent/agent.go

+19-5
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import (
1212

1313
"github.com/deepmap/oapi-codegen/v2/pkg/securityprovider"
1414
"github.com/projectsyn/lieutenant-api/pkg/api"
15-
"github.com/projectsyn/steward/pkg/argocd"
1615
"k8s.io/client-go/kubernetes"
1716
"k8s.io/client-go/rest"
1817
"k8s.io/client-go/tools/clientcmd"
1918
"k8s.io/klog"
19+
20+
"github.com/projectsyn/steward/pkg/agent/facts"
21+
"github.com/projectsyn/steward/pkg/argocd"
2022
)
2123

2224
// Agent configures the cluster agent
@@ -31,8 +33,14 @@ type Agent struct {
3133
OperatorNamespace string
3234
ArgoCDImage string
3335
RedisImage string
36+
// The configmap containing additional facts to be added to the dynamic facts
37+
AdditionalFactsConfigMap string
3438

35-
facts factCollector
39+
// Reference to the OpenShift OAuth route to be added to the dynamic facts
40+
OCPOAuthRouteNamespace string
41+
OCPOAuthRouteName string
42+
43+
facts facts.FactCollector
3644
}
3745

3846
// Run starts the cluster agent
@@ -58,8 +66,14 @@ func (a *Agent) Run(ctx context.Context) error {
5866
return err
5967
}
6068

61-
a.facts = factCollector{
62-
client: client,
69+
a.facts = facts.FactCollector{
70+
Client: client,
71+
72+
OAuthRouteNamespace: a.OCPOAuthRouteNamespace,
73+
OAuthRouteName: a.OCPOAuthRouteName,
74+
75+
AdditionalFactsConfigMapNamespace: a.Namespace,
76+
AdditionalFactsConfigMapName: a.AdditionalFactsConfigMap,
6377
}
6478

6579
ticker := time.NewTicker(1 * time.Minute)
@@ -91,7 +105,7 @@ func (a *Agent) registerCluster(ctx context.Context, config *rest.Config, apiCli
91105
DeployKey: &publicKey,
92106
},
93107
}
94-
patchCluster.DynamicFacts, err = a.facts.fetchDynamicFacts(ctx)
108+
patchCluster.DynamicFacts, err = a.facts.FetchDynamicFacts(ctx)
95109
if err != nil {
96110
klog.Errorf("Error fetching dynamic facts: %v", err)
97111
}

pkg/agent/facts.go pkg/agent/facts/facts.go

+41-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package agent
1+
package facts
22

33
import (
44
"context"
@@ -7,17 +7,33 @@ import (
77
"unicode"
88

99
"github.com/projectsyn/lieutenant-api/pkg/api"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
"k8s.io/apimachinery/pkg/version"
1112
"k8s.io/client-go/kubernetes"
1213
"k8s.io/klog"
1314
)
1415

15-
type factCollector struct {
16-
client *kubernetes.Clientset
16+
type FactCollector struct {
17+
Client *kubernetes.Clientset
18+
19+
OAuthRouteNamespace string
20+
OAuthRouteName string
21+
22+
AdditionalFactsConfigMapNamespace string
23+
AdditionalFactsConfigMapName string
1724
}
1825

19-
func (col factCollector) fetchDynamicFacts(ctx context.Context) (*api.DynamicClusterFacts, error) {
26+
func (col FactCollector) FetchDynamicFacts(ctx context.Context) (*api.DynamicClusterFacts, error) {
2027
facts := api.DynamicClusterFacts{}
28+
29+
additionalFacts, err := col.fetchAdditionalFacts(ctx)
30+
if err != nil {
31+
klog.Errorf("Error fetching additional facts: %v", err)
32+
}
33+
for k, v := range additionalFacts {
34+
facts[k] = v
35+
}
36+
2137
kubeVersion, err := col.fetchKubernetesVersion(ctx)
2238
if err != nil {
2339
klog.Errorf("Error fetching kubernetes version: %v", err)
@@ -34,12 +50,20 @@ func (col factCollector) fetchDynamicFacts(ctx context.Context) (*api.DynamicClu
3450
facts["openshiftVersion"] = ocpVersion
3551
}
3652

53+
ocpOAuthRoute, err := col.fetchOpenshiftOAuthRoute(ctx)
54+
if err != nil {
55+
klog.Errorf("Error fetching openshift oauth route: %v", err)
56+
}
57+
if ocpOAuthRoute != "" {
58+
facts["openshiftOAuthRoute"] = ocpOAuthRoute
59+
}
60+
3761
return &facts, nil
3862
}
3963

40-
func (col factCollector) fetchKubernetesVersion(ctx context.Context) (*version.Info, error) {
64+
func (col FactCollector) fetchKubernetesVersion(ctx context.Context) (*version.Info, error) {
4165
// We are not using `col.client.ServerVersion()` to get context support
42-
body, err := col.client.RESTClient().Get().AbsPath("/version").Do(ctx).Raw()
66+
body, err := col.Client.RESTClient().Get().AbsPath("/version").Do(ctx).Raw()
4367
if err != nil {
4468
return nil, err
4569
}
@@ -70,6 +94,17 @@ func processKubernetesVersion(v version.Info) (version.Info, error) {
7094
return v, nil
7195
}
7296

97+
func (col FactCollector) fetchAdditionalFacts(ctx context.Context) (map[string]string, error) {
98+
if col.AdditionalFactsConfigMapName == "" {
99+
return nil, nil
100+
}
101+
cm, err := col.Client.CoreV1().ConfigMaps(col.AdditionalFactsConfigMapNamespace).Get(ctx, col.AdditionalFactsConfigMapName, metav1.GetOptions{})
102+
if err != nil {
103+
return nil, fmt.Errorf("unable to fetch the additional facts config map: %w", err)
104+
}
105+
return cm.Data, nil
106+
}
107+
73108
func trimVersion(v string) string {
74109
res := []rune{}
75110
for _, r := range v {

pkg/agent/facts_test.go pkg/agent/facts/facts_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package agent
1+
package facts
22

33
import (
44
"testing"

pkg/agent/factsopenshift.go pkg/agent/facts/factsopenshift.go

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
package agent
1+
package facts
22

33
import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"path"
78
"strings"
89
"time"
910

@@ -30,8 +31,14 @@ type OpenshiftVersion struct {
3031
Status OpenshiftVersionStatus
3132
}
3233

33-
func (col factCollector) fetchOpenshiftVersion(ctx context.Context) (*SemanticVersion, error) {
34-
body, err := col.client.RESTClient().Get().AbsPath("/apis/config.openshift.io/v1/clusterversions/version").Do(ctx).Raw()
34+
type OpenshiftRoute struct {
35+
Spec struct {
36+
Host string
37+
}
38+
}
39+
40+
func (col FactCollector) fetchOpenshiftVersion(ctx context.Context) (*SemanticVersion, error) {
41+
body, err := col.Client.RESTClient().Get().AbsPath("/apis/config.openshift.io/v1/clusterversions/version").Do(ctx).Raw()
3542
if err != nil {
3643
if errors.IsNotFound(err) {
3744
// API server doesn't know `clusterversions` or there is no resource, so we are not running on openshift.
@@ -48,6 +55,27 @@ func (col factCollector) fetchOpenshiftVersion(ctx context.Context) (*SemanticVe
4855
return processOpenshiftVersion(version)
4956
}
5057

58+
func (col FactCollector) fetchOpenshiftOAuthRoute(ctx context.Context) (string, error) {
59+
body, err := col.Client.RESTClient().Get().
60+
AbsPath(
61+
path.Join("/apis/route.openshift.io/v1/namespaces", col.OAuthRouteNamespace, "routes", col.OAuthRouteName),
62+
).Do(ctx).Raw()
63+
if err != nil {
64+
if errors.IsNotFound(err) {
65+
// API server doesn't know `routes` or there is no resource, so we are not running on openshift.
66+
return "", nil
67+
}
68+
return "", fmt.Errorf("unable to fetch the openshift route: %w", err)
69+
}
70+
var route OpenshiftRoute
71+
err = json.Unmarshal(body, &route)
72+
if err != nil {
73+
return "", fmt.Errorf("unable to parse the openshift route: %w", err)
74+
}
75+
76+
return route.Spec.Host, nil
77+
}
78+
5179
type SemanticVersion struct {
5280
Major string
5381
Minor string

pkg/agent/factsopenshift_test.go pkg/agent/facts/factsopenshift_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package agent
1+
package facts
22

33
import (
44
"testing"

tools/dynamic_fact_collector/main.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"flag"
7+
"fmt"
8+
9+
"k8s.io/client-go/kubernetes"
10+
"sigs.k8s.io/controller-runtime/pkg/client/config"
11+
12+
"github.com/projectsyn/steward/pkg/agent/facts"
13+
)
14+
15+
func main() {
16+
ns := flag.String("namespace", "syn", "namespace in which steward is running")
17+
additionalFactsConfigMap := flag.String("additional-facts-config-map", "additional-facts", "configmap containing additional facts to be added to the dynamic facts")
18+
ocpOAuthRouteNamespace := flag.String("ocp-oauth-route-namespace", "openshift-authentication", "Namespace for the OpenShift OAuth route")
19+
ocpOAuthRouteName := flag.String("ocp-oauth-route-name", "oauth-openshift", "Name of the OpenShift OAuth route")
20+
21+
flag.Parse()
22+
23+
cfg := config.GetConfigOrDie()
24+
25+
client, err := kubernetes.NewForConfig(cfg)
26+
if err != nil {
27+
panic(err)
28+
}
29+
30+
c := facts.FactCollector{
31+
Client: client,
32+
33+
OAuthRouteNamespace: *ocpOAuthRouteNamespace,
34+
OAuthRouteName: *ocpOAuthRouteName,
35+
36+
AdditionalFactsConfigMapNamespace: *ns,
37+
AdditionalFactsConfigMapName: *additionalFactsConfigMap,
38+
}
39+
40+
fcts, err := c.FetchDynamicFacts(context.Background())
41+
if err != nil {
42+
panic(err)
43+
}
44+
out, err := json.MarshalIndent(fcts, "", "\t")
45+
if err != nil {
46+
panic(err)
47+
}
48+
fmt.Println(string(out))
49+
}

0 commit comments

Comments
 (0)