зеркало из https://github.com/microsoft/oe-engine.git
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:
Родитель
7a13050aea
Коммит
fc30368d38
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче