/
hive.go
120 lines (98 loc) · 3.5 KB
/
hive.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
package liveconfig
// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.
import (
"context"
"fmt"
"os"
"strings"
mgmtcontainerservice "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2021-10-01/containerservice"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/containerservice"
)
func getAksClusterByNameAndLocation(ctx context.Context, aksClusters mgmtcontainerservice.ManagedClusterListResultPage, aksClusterName, location string) (*mgmtcontainerservice.ManagedCluster, error) {
for aksClusters.NotDone() {
for _, cluster := range aksClusters.Values() {
if strings.EqualFold(*cluster.Name, aksClusterName) && strings.EqualFold(*cluster.Location, location) {
return &cluster, nil
}
}
err := aksClusters.NextWithContext(ctx)
if err != nil {
return nil, err
}
}
return nil, nil
}
func getAksShardKubeconfig(ctx context.Context, managedClustersClient containerservice.ManagedClustersClient, location string, shard int) (*rest.Config, error) {
aksClusterName := fmt.Sprintf("aro-aks-cluster-%03d", shard)
aksClusters, err := managedClustersClient.List(ctx)
if err != nil {
return nil, err
}
aksCluster, err := getAksClusterByNameAndLocation(ctx, aksClusters, aksClusterName, location)
if err != nil {
return nil, err
}
if aksCluster == nil {
return nil, fmt.Errorf("failed to find the AKS cluster %s in %s", aksClusterName, location)
}
aksResourceGroup := strings.Replace(*aksCluster.NodeResourceGroup, fmt.Sprintf("-aks%d", shard), "", 1)
res, err := managedClustersClient.ListClusterAdminCredentials(ctx, aksResourceGroup, aksClusterName, "public")
if err != nil {
return nil, err
}
return parseKubeconfig(*res.Kubeconfigs)
}
func parseKubeconfig(credentials []mgmtcontainerservice.CredentialResult) (*rest.Config, error) {
clientconfig, err := clientcmd.NewClientConfigFromBytes(*credentials[0].Value)
if err != nil {
return nil, err
}
restConfig, err := clientconfig.ClientConfig()
if err != nil {
return nil, err
}
return restConfig, nil
}
func (p *prod) HiveRestConfig(ctx context.Context, shard int) (*rest.Config, error) {
// Hive shards are planned but not implemented yet
p.hiveCredentialsMutex.RLock()
cached, exists := p.cachedCredentials[shard]
p.hiveCredentialsMutex.RUnlock()
if exists {
return rest.CopyConfig(cached), nil
}
// Lock the RWMutex as we're starting to fetch so that new readers will wait
// for the existing Azure API call to be done.
p.hiveCredentialsMutex.Lock()
defer p.hiveCredentialsMutex.Unlock()
kubeConfig, err := getAksShardKubeconfig(ctx, p.managedClustersClient, p.location, shard)
if err != nil {
return nil, err
}
p.cachedCredentials[shard] = kubeConfig
return rest.CopyConfig(kubeConfig), nil
}
func (p *prod) InstallViaHive(ctx context.Context) (bool, error) {
// TODO: Replace with RP Live Service Config (KeyVault)
installViaHive := os.Getenv(hiveInstallerEnableEnvVar)
if installViaHive != "" {
return true, nil
}
return false, nil
}
func (p *prod) DefaultInstallerPullSpecOverride(ctx context.Context) string {
// TODO: we should probably not have an override in prod, but it may have unintended
// consequences in an int-like development RP
return os.Getenv(hiveDefaultPullSpecEnvVar)
}
func (p *prod) AdoptByHive(ctx context.Context) (bool, error) {
// TODO: Replace with RP Live Service Config (KeyVault)
adopt := os.Getenv(hiveAdoptEnableEnvVar)
if adopt != "" {
return true, nil
}
return false, nil
}