Skip to content

Commit

Permalink
Merge pull request #1150 from abhinavdahiya/ssh_mc
Browse files Browse the repository at this point in the history
 machines: add the authorized keys for a pool using a machine config
  • Loading branch information
openshift-merge-robot authored Mar 27, 2019
2 parents fa08964 + 5623cbd commit 6a50329
Show file tree
Hide file tree
Showing 83 changed files with 6,243 additions and 63 deletions.
24 changes: 23 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions pkg/asset/machines/machineconfig/authorizedkeys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package machineconfig

import (
"fmt"

ignv2_2types "github.com/coreos/ignition/config/v2_2/types"
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ForAuthorizedKeys creates the MachineConfig to set the authorized key for `core` user.
func ForAuthorizedKeys(key string, role string) *mcfgv1.MachineConfig {
return &mcfgv1.MachineConfig{
TypeMeta: metav1.TypeMeta{
APIVersion: mcfgv1.SchemeGroupVersion.String(),
Kind: "MachineConfig",
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("99-%s-ssh", role),
Labels: map[string]string{
"machineconfiguration.openshift.io/role": role,
},
},
Spec: mcfgv1.MachineConfigSpec{
Config: ignv2_2types.Config{
Ignition: ignv2_2types.Ignition{
Version: ignv2_2types.MaxVersion.String(),
},
Passwd: ignv2_2types.Passwd{
Users: []ignv2_2types.PasswdUser{{
Name: "core", SSHAuthorizedKeys: []ignv2_2types.SSHAuthorizedKey{ignv2_2types.SSHAuthorizedKey(key)},
}},
},
},
},
}
}
63 changes: 63 additions & 0 deletions pkg/asset/machines/machineconfig/manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package machineconfig

import (
"fmt"
"os"
"path/filepath"

"github.com/ghodss/yaml"

mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"

"github.com/openshift/installer/pkg/asset"
)

const (
machineConfigFileName = "99_openshift-machineconfig_%s.yaml"
)

var (
machineConfigFileNamePattern = fmt.Sprintf(machineConfigFileName, "*")
)

// Manifests creates manifest files containing the MachineConfigs.
func Manifests(configs []*mcfgv1.MachineConfig, role, directory string) ([]*asset.File, error) {
data := []byte{}
for _, c := range configs {
if c == nil {
continue
}
configData, err := yaml.Marshal(c)
if err != nil {
return nil, err
}
data = append(data, []byte("---\n")...)
data = append(data, configData...)
}
if len(data) == 0 {
return nil, nil
}
return []*asset.File{
{
Filename: filepath.Join(directory, fmt.Sprintf(machineConfigFileName, role)),
Data: data,
},
}, nil
}

// IsManifest tests whether the specified filename is a MachineConfig manifest.
func IsManifest(role, filename string) bool {
return fmt.Sprintf(machineConfigFileName, role) == filename
}

// Load loads the MachineConfig manifests.
func Load(f asset.FileFetcher, role, directory string) ([]*asset.File, error) {
file, err := f.FetchByName(filepath.Join(directory, fmt.Sprintf(machineConfigFileName, role)))
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
return []*asset.File{file}, nil
}
106 changes: 73 additions & 33 deletions pkg/asset/machines/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/machines/aws"
"github.com/openshift/installer/pkg/asset/machines/libvirt"
"github.com/openshift/installer/pkg/asset/machines/machineconfig"
"github.com/openshift/installer/pkg/asset/machines/openstack"
"github.com/openshift/installer/pkg/asset/rhcos"
awstypes "github.com/openshift/installer/pkg/types/aws"
Expand All @@ -22,6 +23,7 @@ import (
nonetypes "github.com/openshift/installer/pkg/types/none"
openstacktypes "github.com/openshift/installer/pkg/types/openstack"
vspheretypes "github.com/openshift/installer/pkg/types/vsphere"
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
Expand All @@ -33,17 +35,23 @@ import (

// Master generates the machines for the `master` machine pool.
type Master struct {
FileList []*asset.File
UserDataFile *asset.File
MachineConfigFiles []*asset.File
MachineFiles []*asset.File
}

var (
const (
directory = "openshift"

// MasterMachineFileName is the format string for constucting the master Machine filenames.
MasterMachineFileName = "99_openshift-cluster-api_master-machines-%s.yaml"
// masterMachineFileName is the format string for constucting the master Machine filenames.
masterMachineFileName = "99_openshift-cluster-api_master-machines-%s.yaml"

// masterUserDataFileName is the filename used for the master user-data secret.
masterUserDataFileName = "99_openshift-cluster-api_master-user-data-secret.yaml"
)

// MasterUserDataFileName is the filename used for the master user-data secret.
MasterUserDataFileName = "99_openshift-cluster-api_master-user-data-secret.yaml"
var (
masterMachineFileNamePattern = fmt.Sprintf(masterMachineFileName, "*")

_ asset.WritableAsset = (*Master)(nil)
)
Expand Down Expand Up @@ -82,10 +90,10 @@ func (m *Master) Generate(dependencies asset.Parents) error {
mign := &machine.Master{}
dependencies.Get(clusterID, installconfig, rhcosImage, mign)

var err error
machines := []machineapi.Machine{}
ic := installconfig.Config
pool := ic.ControlPlane
var err error
machines := []machineapi.Machine{}
switch ic.Platform.Name() {
case awstypes.Name:
mpool := defaultAWSMachinePoolPlatform()
Expand Down Expand Up @@ -138,71 +146,83 @@ func (m *Master) Generate(dependencies asset.Parents) error {
return errors.Wrap(err, "failed to create user-data secret for master machines")
}

m.FileList = []*asset.File{{
Filename: filepath.Join(directory, MasterUserDataFileName),
m.UserDataFile = &asset.File{
Filename: filepath.Join(directory, masterUserDataFileName),
Data: data,
}}
}

count := len(machines)
if count == 0 {
return errors.New("at least one master machine must be configured")
machineConfigs := []*mcfgv1.MachineConfig{}
if ic.SSHKey != "" {
machineConfigs = append(machineConfigs, machineconfig.ForAuthorizedKeys(ic.SSHKey, "master"))
}
m.MachineConfigFiles, err = machineconfig.Manifests(machineConfigs, "master", directory)
if err != nil {
return errors.Wrap(err, "failed to create MachineConfig manifests for master machines")
}

padFormat := fmt.Sprintf("%%0%dd", len(fmt.Sprintf("%d", count)))
m.MachineFiles = make([]*asset.File, len(machines))
padFormat := fmt.Sprintf("%%0%dd", len(fmt.Sprintf("%d", len(machines))))
for i, machine := range machines {
data, err := yaml.Marshal(machine)
if err != nil {
return errors.Wrapf(err, "marshal master %d", i)
}

padded := fmt.Sprintf(padFormat, i)
m.FileList = append(m.FileList, &asset.File{
Filename: filepath.Join(directory, fmt.Sprintf(MasterMachineFileName, padded)),
m.MachineFiles[i] = &asset.File{
Filename: filepath.Join(directory, fmt.Sprintf(masterMachineFileName, padded)),
Data: data,
})
}
}

return nil
}

// Files returns the files generated by the asset.
func (m *Master) Files() []*asset.File {
return m.FileList
files := make([]*asset.File, 0, 1+len(m.MachineConfigFiles)+len(m.MachineFiles))
if m.UserDataFile != nil {
files = append(files, m.UserDataFile)
}
files = append(files, m.MachineConfigFiles...)
files = append(files, m.MachineFiles...)
return files
}

// Load reads the asset files from disk.
func (m *Master) Load(f asset.FileFetcher) (found bool, err error) {
file, err := f.FetchByName(filepath.Join(directory, MasterUserDataFileName))
file, err := f.FetchByName(filepath.Join(directory, masterUserDataFileName))
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
m.FileList = []*asset.File{file}
m.UserDataFile = file

m.MachineConfigFiles, err = machineconfig.Load(f, "master", directory)
if err != nil {
return true, err
}

fileList, err := f.FetchByPattern(filepath.Join(directory, fmt.Sprintf(MasterMachineFileName, "*")))
fileList, err := f.FetchByPattern(filepath.Join(directory, masterMachineFileNamePattern))
if err != nil {
return true, err
}

if len(fileList) == 0 {
return true, errors.Errorf("master machine manifests are required if you also provide %s", file.Filename)
return true, errors.Errorf("master machine manifests are required if you also provide %s", m.UserDataFile.Filename)
}

m.FileList = append(m.FileList, fileList...)
m.MachineFiles = fileList
return true, nil
}

// Machines returns master Machine manifest YAML.
func (m *Master) Machines() [][]byte {
machines := [][]byte{}
userData := filepath.Join(directory, MasterUserDataFileName)
for _, file := range m.FileList {
if file.Filename == userData {
continue
}
machines = append(machines, file.Data)
machines := make([][]byte, len(m.MachineFiles))
for i, file := range m.MachineFiles {
machines[i] = file.Data
}
return machines
}
Expand All @@ -220,9 +240,9 @@ func (m *Master) StructuredMachines() ([]machineapi.Machine, error) {
)

machines := []machineapi.Machine{}
for i, data := range m.Machines() {
for i, file := range m.MachineFiles {
machine := &machineapi.Machine{}
err := yaml.Unmarshal(data, &machine)
err := yaml.Unmarshal(file.Data, &machine)
if err != nil {
return machines, errors.Wrapf(err, "unmarshal master %d", i)
}
Expand All @@ -238,3 +258,23 @@ func (m *Master) StructuredMachines() ([]machineapi.Machine, error) {

return machines, nil
}

// IsMasterManifest tests whether a file is a manifest that belongs to the
// Master Machines asset.
func IsMasterManifest(file *asset.File) bool {
if filepath.Dir(file.Filename) != directory {
return false
}
filename := filepath.Base(file.Filename)
if filename == masterUserDataFileName {
return true
}
if machineconfig.IsManifest("master", filename) {
return true
}
if matched, err := filepath.Match(masterMachineFileNamePattern, filename); err != nil {
panic("bad format for master machine file name pattern")
} else {
return matched
}
}
Loading

0 comments on commit 6a50329

Please sign in to comment.