forked from openshift/installer
/
cluster.go
129 lines (110 loc) · 3.76 KB
/
cluster.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
package cluster
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/password"
"github.com/openshift/installer/pkg/terraform"
)
var (
// kubeadminPasswordPath is the path where kubeadmin user password is stored.
kubeadminPasswordPath = filepath.Join("auth", "kubeadmin-password")
)
// Cluster uses the terraform executable to launch a cluster
// with the given terraform tfvar and generated templates.
type Cluster struct {
FileList []*asset.File
}
var _ asset.WritableAsset = (*Cluster)(nil)
// Name returns the human-friendly name of the asset.
func (c *Cluster) Name() string {
return "Cluster"
}
// Dependencies returns the direct dependency for launching
// the cluster.
func (c *Cluster) Dependencies() []asset.Asset {
return []asset.Asset{
&installconfig.ClusterID{},
&installconfig.InstallConfig{},
// PlatformCredsCheck just checks the creds (and asks, if needed)
// We do not actually use it in this asset directly, hence
// it is put in the dependencies but not fetched in Generate
&installconfig.PlatformCredsCheck{},
&TerraformVariables{},
&password.KubeadminPassword{},
}
}
// Generate launches the cluster and generates the terraform state file on disk.
func (c *Cluster) Generate(parents asset.Parents) (err error) {
clusterID := &installconfig.ClusterID{}
installConfig := &installconfig.InstallConfig{}
terraformVariables := &TerraformVariables{}
kubeadminPassword := &password.KubeadminPassword{}
parents.Get(clusterID, installConfig, terraformVariables, kubeadminPassword)
if installConfig.Config.Platform.None != nil {
return errors.New("cluster cannot be created with platform set to 'none'")
}
// Copy the terraform.tfvars to a temp directory where the terraform will be invoked within.
tmpDir, err := ioutil.TempDir("", "openshift-install-")
if err != nil {
return errors.Wrap(err, "failed to create temp dir for terraform execution")
}
defer os.RemoveAll(tmpDir)
extraArgs := []string{}
for _, file := range terraformVariables.Files() {
if err := ioutil.WriteFile(filepath.Join(tmpDir, file.Filename), file.Data, 0600); err != nil {
return err
}
extraArgs = append(extraArgs, fmt.Sprintf("-var-file=%s", filepath.Join(tmpDir, file.Filename)))
}
c.FileList = []*asset.File{
{
Filename: kubeadminPasswordPath,
Data: []byte(kubeadminPassword.Password),
},
}
logrus.Infof("Creating infrastructure resources...")
stateFile, err := terraform.Apply(tmpDir, installConfig.Config.Platform.Name(), extraArgs...)
if err != nil {
err = errors.Wrap(err, "failed to create cluster")
if stateFile == "" {
return err
}
// Store the error from the apply, but continue with the
// generation so that the Terraform state file is recovered from
// the temporary directory.
}
data, err2 := ioutil.ReadFile(stateFile)
if err2 == nil {
c.FileList = append(c.FileList, &asset.File{
Filename: terraform.StateFileName,
Data: data,
})
} else if err == nil {
err = err2
} else {
logrus.Errorf("Failed to read tfstate: %v", err2)
}
return err
}
// Files returns the FileList generated by the asset.
func (c *Cluster) Files() []*asset.File {
return c.FileList
}
// Load returns error if the tfstate file is already on-disk, because we want to
// prevent user from accidentally re-launching the cluster.
func (c *Cluster) Load(f asset.FileFetcher) (found bool, err error) {
_, err = f.FetchByName(terraform.StateFileName)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
return true, errors.Errorf("%q already exists. There may already be a running cluster", terraform.StateFileName)
}