Skip to content

Commit 385220d

Browse files
committed
added ClusterInfo asset
1 parent fa469cc commit 385220d

File tree

4 files changed

+237
-3
lines changed

4 files changed

+237
-3
lines changed

cmd/node-joiner/main.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
)
1111

1212
func main() {
13+
1314
wd, err := os.Getwd()
1415
if err != nil {
1516
logrus.Fatal(err)
@@ -19,7 +20,11 @@ func main() {
1920
Use: "add-nodes",
2021
Short: "Generates an ISO that could be used to boot the configured nodes to let them join an existing cluster",
2122
RunE: func(cmd *cobra.Command, args []string) error {
22-
return nodejoiner.NewAddNodesCommand(wd)
23+
kubeConfig, err := cmd.Flags().GetString("kubeconfig")
24+
if err != nil {
25+
return err
26+
}
27+
return nodejoiner.NewAddNodesCommand(wd, kubeConfig)
2328
},
2429
}
2530

@@ -34,6 +39,7 @@ func main() {
3439
rootCmd := &cobra.Command{
3540
Use: "node-joiner",
3641
}
42+
rootCmd.PersistentFlags().String("kubeconfig", "", "Path to the kubeconfig file.")
3743

3844
rootCmd.AddCommand(nodesAddCmd)
3945
rootCmd.AddCommand(nodesMonitorCmd)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package joiner
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/openshift/installer/pkg/asset"
10+
"github.com/pkg/errors"
11+
)
12+
13+
const (
14+
addNodesParamsFile = ".addnodesparams"
15+
)
16+
17+
type AddNodesConfig struct {
18+
File *asset.File
19+
Params Params
20+
}
21+
22+
// Params is used to store the command line parameters
23+
type Params struct {
24+
Kubeconfig string `json:"kubeconfig,omitempty"`
25+
}
26+
27+
// Save stores the current parameters on disk
28+
func (p *Params) Save(assetsDir string) error {
29+
data, err := json.Marshal(p)
30+
if err != nil {
31+
return err
32+
}
33+
34+
fileName := filepath.Join(assetsDir, addNodesParamsFile)
35+
return os.WriteFile(fileName, data, 0o644)
36+
}
37+
38+
// Name returns the human-friendly name of the asset.
39+
func (*AddNodesConfig) Name() string {
40+
return "AddNodes Config"
41+
}
42+
43+
// Dependencies returns all of the dependencies directly needed to generate
44+
// the asset.
45+
func (*AddNodesConfig) Dependencies() []asset.Asset {
46+
return []asset.Asset{}
47+
}
48+
49+
// Generate it's empty for this asset, always loaded from disk.
50+
func (*AddNodesConfig) Generate(dependencies asset.Parents) error {
51+
return nil
52+
}
53+
54+
// Files returns the files generated by the asset.
55+
func (a *AddNodesConfig) Files() []*asset.File {
56+
if a.File != nil {
57+
return []*asset.File{a.File}
58+
}
59+
return []*asset.File{}
60+
}
61+
62+
// Load returns agent config asset from the disk.
63+
func (a *AddNodesConfig) Load(f asset.FileFetcher) (bool, error) {
64+
file, err := f.FetchByName(addNodesParamsFile)
65+
if err != nil {
66+
if os.IsNotExist(err) {
67+
return false, nil
68+
}
69+
return false, fmt.Errorf("failed to load %s file: %w", addNodesParamsFile, err)
70+
}
71+
72+
params := &Params{}
73+
if err := json.Unmarshal(file.Data, params); err != nil {
74+
return false, fmt.Errorf("failed to unmarshal %s: %w", addNodesParamsFile, err)
75+
}
76+
77+
a.Params = *params
78+
return true, nil
79+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package joiner
2+
3+
import (
4+
"context"
5+
"net/url"
6+
7+
configclient "github.com/openshift/client-go/config/clientset/versioned"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/client-go/kubernetes"
10+
"k8s.io/client-go/rest"
11+
"k8s.io/client-go/tools/clientcmd"
12+
13+
"github.com/openshift/installer/pkg/asset"
14+
"github.com/openshift/installer/pkg/asset/agent/workflow"
15+
)
16+
17+
// ClusterInfo it's an asset used to retrieve config info
18+
// from an already existing cluster.
19+
type ClusterInfo struct {
20+
ClusterID string
21+
ApiDnsName string
22+
PullSecret string
23+
}
24+
25+
var _ asset.WritableAsset = (*ClusterInfo)(nil)
26+
27+
// Name returns the human-friendly name of the asset.
28+
func (ci *ClusterInfo) Name() string {
29+
return "Agent Installer ClusterInfo"
30+
}
31+
32+
// Dependencies returns all of the dependencies directly needed to generate
33+
// the asset.
34+
func (*ClusterInfo) Dependencies() []asset.Asset {
35+
return []asset.Asset{
36+
&workflow.AgentWorkflow{},
37+
&AddNodesConfig{},
38+
}
39+
}
40+
41+
// Generate generates the ClusterInfo.
42+
func (ci *ClusterInfo) Generate(dependencies asset.Parents) error {
43+
agentWorkflow := &workflow.AgentWorkflow{}
44+
addNodesConfig := &AddNodesConfig{}
45+
dependencies.Get(agentWorkflow, addNodesConfig)
46+
47+
if agentWorkflow.Workflow != workflow.AgentWorkflowTypeAddNodes {
48+
return nil
49+
}
50+
51+
config, err := ci.getRestConfig(addNodesConfig.Params.Kubeconfig)
52+
if err != nil {
53+
return err
54+
}
55+
56+
err = ci.retrieveClusterID(config)
57+
if err != nil {
58+
return err
59+
}
60+
61+
err = ci.retrieveApiDnsName(config)
62+
if err != nil {
63+
return err
64+
}
65+
66+
err = ci.retrievePullSecret(config)
67+
if err != nil {
68+
return err
69+
}
70+
71+
return nil
72+
}
73+
74+
func (ci *ClusterInfo) getRestConfig(kubeconfig string) (*rest.Config, error) {
75+
var err error
76+
var config *rest.Config
77+
78+
if kubeconfig != "" {
79+
config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
80+
} else {
81+
config, err = rest.InClusterConfig()
82+
}
83+
84+
return config, err
85+
}
86+
87+
func (ci *ClusterInfo) retrieveClusterID(config *rest.Config) error {
88+
clientset, err := configclient.NewForConfig(config)
89+
if err != nil {
90+
return err
91+
}
92+
93+
cv, err := clientset.ConfigV1().ClusterVersions().Get(context.Background(), "version", metav1.GetOptions{})
94+
if err != nil {
95+
return err
96+
}
97+
ci.ClusterID = string(cv.Spec.ClusterID)
98+
99+
return nil
100+
}
101+
102+
func (ci *ClusterInfo) retrieveApiDnsName(config *rest.Config) error {
103+
104+
parsedUrl, err := url.Parse(config.Host)
105+
if err != nil {
106+
return err
107+
}
108+
109+
ci.ApiDnsName = parsedUrl.Hostname()
110+
return nil
111+
}
112+
113+
func (ci *ClusterInfo) retrievePullSecret(config *rest.Config) error {
114+
clientset, err := kubernetes.NewForConfig(config)
115+
if err != nil {
116+
return err
117+
}
118+
119+
pullSecret, err := clientset.CoreV1().Secrets("openshift-config").Get(context.Background(), "pull-secret", metav1.GetOptions{})
120+
if err != nil {
121+
return err
122+
}
123+
ci.PullSecret = string(pullSecret.Data[".dockerconfigjson"])
124+
125+
return nil
126+
}
127+
128+
// Files returns the files generated by the asset.
129+
func (*ClusterInfo) Files() []*asset.File {
130+
return []*asset.File{}
131+
}
132+
133+
// Load returns agent config asset from the disk.
134+
func (*ClusterInfo) Load(f asset.FileFetcher) (bool, error) {
135+
return false, nil
136+
}

pkg/nodejoiner/addnodes.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,24 @@ package nodejoiner
22

33
import (
44
"github.com/openshift/installer/pkg/asset"
5+
"github.com/openshift/installer/pkg/asset/agent/joiner"
6+
"github.com/openshift/installer/pkg/asset/agent/workflow"
57
"github.com/openshift/installer/pkg/asset/store"
68
)
79

810
// NewAddNodesCommand creates a new command for add nodes.
9-
func NewAddNodesCommand(directory string) error {
11+
func NewAddNodesCommand(directory string, kubeConfig string) error {
12+
13+
// Store the current parameters into the assets folder, so
14+
// that they could be retrieved later by the assets
15+
params := joiner.Params{
16+
Kubeconfig: kubeConfig,
17+
}
18+
params.Save(directory)
19+
1020
fetcher := store.NewAssetsFetcher(directory)
11-
return fetcher.FetchAndPersist([]asset.WritableAsset{})
21+
return fetcher.FetchAndPersist([]asset.WritableAsset{
22+
&workflow.AgentWorkflowAddNodes{},
23+
// To be completed
24+
})
1225
}

0 commit comments

Comments
 (0)