Skip to content

Commit 22ba056

Browse files
committed
Introduce organization optional parameter in credentials (#105)
Credentials can now also include an optional organization ID that specifies the organization to use.
1 parent 86b52b2 commit 22ba056

25 files changed

+142
-57
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Another example: let's say that the execution of the previous command results in
3131
## Set credentials
3232

3333
arduino-cloud-cli needs a credentials file containing an Arduino IoT Cloud client ID and its corresponding secret.
34+
Credentials can also include an optional organization ID that specifies the organization to use.
3435
You can retrieve these credentials from the [cloud](https://create.arduino.cc/iot/integrations) by creating a new API key.
3536

3637
Once you have the credentials, execute the following command and provide them:
@@ -53,7 +54,8 @@ The credentials file is supported in two different formats: json and yaml. Use t
5354

5455
`$ arduino-cloud-cli credentials init --file-format json`
5556

56-
It is also possible to specify credentials directly in `ARDUINO_CLOUD_CLIENT` and `ARDUINO_CLOUD_SECRET` environment variables. Credentials specified in environment variables have higher priority than the ones specified in credentials files.
57+
It is also possible to specify credentials directly in `ARDUINO_CLOUD_CLIENT`, `ARDUINO_CLOUD_SECRET` and optionally `ARDUINO_CLOUD_ORGANIZATION` environment variables. Credentials specified in environment variables have higher priority than the ones specified in credentials files.
58+
Please note that credentials are correctly extracted from environment variables only if all the mandatory credentials parameters (client and secret) are found in environment variables. (think of it as another config file but with higher priority)
5759

5860
#### Find credentials
5961

cli/credentials/init.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func runInitCommand(flags *initFlags) error {
100100

101101
// Take needed credentials starting an interactive mode
102102
feedback.Print("To obtain your API credentials visit https://create.arduino.cc/iot/integrations")
103-
id, key, err := paramsPrompt()
103+
id, key, org, err := paramsPrompt()
104104
if err != nil {
105105
return fmt.Errorf("cannot take credentials params: %w", err)
106106
}
@@ -110,6 +110,7 @@ func runInitCommand(flags *initFlags) error {
110110
newSettings.SetConfigPermissions(os.FileMode(0600))
111111
newSettings.Set("client", id)
112112
newSettings.Set("secret", key)
113+
newSettings.Set("organization", org)
113114
if err := newSettings.WriteConfigAs(credFile.String()); err != nil {
114115
return fmt.Errorf("cannot write credentials file: %w", err)
115116
}
@@ -118,7 +119,7 @@ func runInitCommand(flags *initFlags) error {
118119
return nil
119120
}
120121

121-
func paramsPrompt() (id, key string, err error) {
122+
func paramsPrompt() (id, key, org string, err error) {
122123
prompt := promptui.Prompt{
123124
Label: "Please enter the Client ID",
124125
Validate: func(s string) error {
@@ -130,7 +131,7 @@ func paramsPrompt() (id, key string, err error) {
130131
}
131132
id, err = prompt.Run()
132133
if err != nil {
133-
return "", "", fmt.Errorf("client prompt fail: %w", err)
134+
return "", "", "", fmt.Errorf("client prompt fail: %w", err)
134135
}
135136

136137
prompt = promptui.Prompt{
@@ -145,8 +146,23 @@ func paramsPrompt() (id, key string, err error) {
145146
}
146147
key, err = prompt.Run()
147148
if err != nil {
148-
return "", "", fmt.Errorf("client secret prompt fail: %w", err)
149+
return "", "", "", fmt.Errorf("client secret prompt fail: %w", err)
149150
}
150151

151-
return id, key, nil
152+
prompt = promptui.Prompt{
153+
Mask: '*',
154+
Label: "Please enter the Organization ID - if any - Leave empty otherwise",
155+
Validate: func(s string) error {
156+
if len(s) != 0 && len(s) != config.OrganizationLen {
157+
return errors.New("organization id not valid")
158+
}
159+
return nil
160+
},
161+
}
162+
org, err = prompt.Run()
163+
if err != nil {
164+
return "", "", "", fmt.Errorf("organization id prompt fail: %w", err)
165+
}
166+
167+
return id, key, org, nil
152168
}

command/dashboard/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type CreateParams struct {
3434

3535
// Create allows to create a new dashboard.
3636
func Create(params *CreateParams, cred *config.Credentials) (*DashboardInfo, error) {
37-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
37+
iotClient, err := iot.NewClient(cred)
3838
if err != nil {
3939
return nil, err
4040
}

command/dashboard/delete.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type DeleteParams struct {
3131
// Delete command is used to delete a dashboard
3232
// from Arduino IoT Cloud.
3333
func Delete(params *DeleteParams, cred *config.Credentials) error {
34-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
34+
iotClient, err := iot.NewClient(cred)
3535
if err != nil {
3636
return err
3737
}

command/dashboard/extract.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type ExtractParams struct {
3434
// Extract command is used to extract a dashboard template
3535
// from a dashboard on Arduino IoT Cloud.
3636
func Extract(params *ExtractParams, cred *config.Credentials) (map[string]interface{}, error) {
37-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
37+
iotClient, err := iot.NewClient(cred)
3838
if err != nil {
3939
return nil, err
4040
}

command/dashboard/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
// List command is used to list
2626
// the dashboards of Arduino IoT Cloud.
2727
func List(cred *config.Credentials) ([]DashboardInfo, error) {
28-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
28+
iotClient, err := iot.NewClient(cred)
2929
if err != nil {
3030
return nil, err
3131
}

command/device/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func Create(params *CreateParams, cred *config.Credentials) (*DeviceInfo, error)
6363
)
6464
}
6565

66-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
66+
iotClient, err := iot.NewClient(cred)
6767
if err != nil {
6868
return nil, err
6969
}

command/device/creategeneric.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type DeviceGenericInfo struct {
4444

4545
// CreateGeneric command is used to add a new generic device to Arduino IoT Cloud.
4646
func CreateGeneric(params *CreateGenericParams, cred *config.Credentials) (*DeviceGenericInfo, error) {
47-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
47+
iotClient, err := iot.NewClient(cred)
4848
if err != nil {
4949
return nil, err
5050
}

command/device/createlora.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func CreateLora(params *CreateLoraParams, cred *config.Credentials) (*DeviceLora
107107
return nil, err
108108
}
109109

110-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
110+
iotClient, err := iot.NewClient(cred)
111111
if err != nil {
112112
return nil, err
113113
}

command/device/delete.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func Delete(params *DeleteParams, cred *config.Credentials) error {
4343
return errors.New("cannot use both ID and Tags. only one of them should be not nil")
4444
}
4545

46-
iotClient, err := iot.NewClient(cred.Client, cred.Secret)
46+
iotClient, err := iot.NewClient(cred)
4747
if err != nil {
4848
return err
4949
}

0 commit comments

Comments
 (0)