allow passing public SSH keys from the command line (#13)

* allow passing public SSH keys from the command line
* update docs
This commit is contained in:
dmitsh 2018-10-31 21:53:33 -07:00 коммит произвёл GitHub
Родитель 7a13050aea
Коммит fc30368d38
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 105 добавлений и 18 удалений

Просмотреть файл

@ -3,7 +3,9 @@ package cmd
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/Microsoft/oe-engine/pkg/api"
"github.com/Microsoft/oe-engine/pkg/engine"
@ -15,13 +17,13 @@ import (
const (
generateName = "generate"
generateShortDescription = "Generate an Azure Resource Manager template"
generateLongDescription = "Generates an Azure Resource Manager template, parameters file and other assets for a cluster"
generateLongDescription = "Generates an Azure Resource Manager template and parameters file"
)
type generateCmd struct {
apimodelPath string
outputDirectory string // can be auto-determined from clusterDefinition
classicMode bool
outputDirectory string
sshPubKeys []string
noPrettyPrint bool
parametersOnly bool
@ -51,8 +53,8 @@ func newGenerateCmd() *cobra.Command {
f := generateCmd.Flags()
f.StringVar(&gc.apimodelPath, "api-model", "", "")
f.StringVar(&gc.outputDirectory, "output-directory", "", "output directory (derived from FQDN if absent)")
f.BoolVar(&gc.classicMode, "classic-mode", false, "enable classic parameters and outputs")
f.StringVar(&gc.outputDirectory, "output-directory", "", "output directory (_output if absent)")
f.StringArrayVar(&gc.sshPubKeys, "ssh-public-key", nil, "SSH public key file path")
f.BoolVar(&gc.noPrettyPrint, "no-pretty-print", false, "skip pretty printing the output")
f.BoolVar(&gc.parametersOnly, "parameters-only", false, "only output parameters files")
@ -77,6 +79,17 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) error {
return fmt.Errorf(fmt.Sprintf("specified api model does not exist (%s)", gc.apimodelPath))
}
for i, keyPath := range gc.sshPubKeys {
if _, err := os.Stat(keyPath); os.IsNotExist(err) {
return fmt.Errorf(fmt.Sprintf("ssh public key file %s does not exist", keyPath))
}
b, err := ioutil.ReadFile(keyPath)
if err != nil {
return err
}
gc.sshPubKeys[i] = strings.TrimSpace(string(b))
}
return nil
}
@ -84,7 +97,7 @@ func (gc *generateCmd) loadAPIModel(cmd *cobra.Command, args []string) error {
var err error
apiloader := &api.Apiloader{}
gc.oe, err = apiloader.LoadOpenEnclaveFromFile(gc.apimodelPath, true, false)
gc.oe, err = apiloader.LoadOpenEnclaveFromFile(gc.apimodelPath, true, false, gc.sshPubKeys)
if err != nil {
return fmt.Errorf(fmt.Sprintf("error parsing the api model: %s", err.Error()))
}

Просмотреть файл

@ -12,6 +12,9 @@ Alternatively, you can download latest release from [here](https://github.com/Mi
### Create VM definition file
The VM definition file is a JSON-formatted description of the properties of the VMs, such as: compute power, OS image, credentials, etc.
For details, refer to the [Setting properties in the VM definition file](properties.md)
The examples below illustrate how to set the various properties.
* [Multi-VM deployment](examples/oe-multi-vm.json) - Deploying multiple VMs
@ -21,13 +24,6 @@ The examples below illustrate how to set the various properties.
* [Linux user password](examples/oe-lnx-passwd.json) - Using password authentication instead of SSH on Linux
* [Windows OpenSSH](examples/oe-win-ssh.json) - Installing and configuring OpenSSH on Windows
The table below summarizes enumerated properties:
| Property | Key | Values |
| ------ | ------ |------ |
| OS | `osImageName` | `UbuntuServer_16.04` `WindowsServer_2016` |
| Compute| `vmSize` | `Standard_DC2s` `Standard_DC4s` |
## Generate deployment template
`oe-engine` generates 3 files:

72
docs/properties.md Normal file
Просмотреть файл

@ -0,0 +1,72 @@
# Setting properties in the VM definition file
This document describes VM properties, configurable in the VM definition file
### VM name
Specifies VM name.
* Path: `properties/vmProfiles[]/name`
* Value: string (follows the rules of underlying OS)
### OS image
Specifies the type and the version of the operating system.
* Path: `properties/vmProfiles[]/osImageName`
* Values:
* `UbuntuServer_16.04`
* `WindowsServer_2016`
### OS disk type
Specifies OS disk characteristics.
* Path: `properties/vmProfiles[]/osImageName`
* Values:
* `Premium_LRS` - Premium SSD
* `StandardSSD_LRS` - Standard SSD
* `Standard_LRS` - Standard HDD
### VM compute power
Specifies VM compute characteristics
* Path: `properties/vmProfiles[]/vmSize`
* Values:
* `Standard_DC2s`
* `Standard_DC4s`
Refer to the [VM sizes in Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes) for more details.
### VM Software
Indicates whether Open Enclave SDK and its dependencies should be installed or not.
* Path: `properties/vmProfiles[]/isVanilla`
* Values: boolean
* `true` - a vanilla VM. Open Enclave SDK will not be installed
* `false` - not a vanilla VM. Open Enclave SDK will be installed and verified
### Linux credentials
If at least one of the VMs runs Linux, `linuxProfile` must be present and contain admin user name and password or public SSH key.
Multiple public keys are **supported**.
Setting both the password and the public key(s) is **not allowed**.
* Path: `properties/linuxProfile/adminUsername`
* Value: string
* Path: `properties/linuxProfile/adminPassword`
* Value: string
* Path: `properties/linuxProfile/sshPublicKeys[]/keyData`
* Value: public SSH key
The public SSH key(s) could also be set from the command line using `--ssh-public-key` argument.
```sh
oe-engine generate oe-vm.json --ssh-public-key .ssh/id_rsa1.pub --ssh-public-key .ssh/id_rsa2.pub
```
### Windows credentials
If at least one of the VMs runs Windows, `windowsProfile` must be present and contain admin user name and password.
* Path: `properties/windowsProfile/adminUsername`
* Value: string
* Path: `properties/windowsProfile/adminPassword`
* Value: string

Просмотреть файл

@ -15,17 +15,17 @@ type Apiloader struct {
}
// LoadOpenEnclaveFromFile loads an OE API Model from a JSON file
func (a *Apiloader) LoadOpenEnclaveFromFile(jsonFile string, validate, isUpdate bool) (*OpenEnclave, error) {
func (a *Apiloader) LoadOpenEnclaveFromFile(jsonFile string, validate, isUpdate bool, sshPubKeys []string) (*OpenEnclave, error) {
contents, e := ioutil.ReadFile(jsonFile)
if e != nil {
return nil, fmt.Errorf("error reading file %s: %s", jsonFile, e.Error())
}
return a.DeserializeOpenEnclave(contents, validate, isUpdate)
return a.DeserializeOpenEnclave(contents, validate, isUpdate, sshPubKeys)
}
// DeserializeOpenEnclave loads an ACS Cluster API Model, validates it, and returns the unversioned representation
func (a *Apiloader) DeserializeOpenEnclave(contents []byte, validate, isUpdate bool) (*OpenEnclave, error) {
oe, err := a.LoadOpenEnclave(contents, validate, isUpdate)
func (a *Apiloader) DeserializeOpenEnclave(contents []byte, validate, isUpdate bool, sshPubKeys []string) (*OpenEnclave, error) {
oe, err := a.LoadOpenEnclave(contents, validate, isUpdate, sshPubKeys)
if oe == nil || err != nil {
log.Infof("Error returned by LoadOpenEnclave: %+v", err)
}
@ -33,7 +33,7 @@ func (a *Apiloader) DeserializeOpenEnclave(contents []byte, validate, isUpdate b
}
// LoadOpenEnclave loads and validates an OE API Model
func (a *Apiloader) LoadOpenEnclave(contents []byte, validate, isUpdate bool) (*OpenEnclave, error) {
func (a *Apiloader) LoadOpenEnclave(contents []byte, validate, isUpdate bool, sshPubKeys []string) (*OpenEnclave, error) {
oe := &OpenEnclave{}
if e := json.Unmarshal(contents, oe); e != nil {
return nil, e
@ -41,6 +41,12 @@ func (a *Apiloader) LoadOpenEnclave(contents []byte, validate, isUpdate bool) (*
if e := checkJSONKeys(contents, reflect.TypeOf(*oe)); e != nil {
return nil, e
}
// add SSH public keys from command line arguments
if oe.Properties.LinuxProfile != nil {
for _, key := range sshPubKeys {
oe.Properties.LinuxProfile.SSHPubKeys = append(oe.Properties.LinuxProfile.SSHPubKeys, &PublicKey{KeyData: key})
}
}
if e := oe.Properties.Validate(isUpdate); validate && e != nil {
return nil, e
}