Skip to content

Commit

Permalink
Merge pull request #1 from rodneyosodo/PR-PROP-31
Browse files Browse the repository at this point in the history
NOISSUE - Enhance Provision
  • Loading branch information
nyagamunene authored Jan 17, 2025
2 parents 7cd082e + 7f1dfd5 commit 4901399
Show file tree
Hide file tree
Showing 12 changed files with 466 additions and 327 deletions.
290 changes: 182 additions & 108 deletions cli/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package cli
import (
"fmt"
"os"
"strings"

"github.com/0x6flab/namegenerator"
smqSDK "github.com/absmach/magistrala/pkg/sdk/go"
"github.com/absmach/supermq/pkg/errors"
"github.com/charmbracelet/huh"
"github.com/spf13/cobra"
)

Expand All @@ -16,126 +19,190 @@ var (
errFailedClientCreation = errors.New("failed to create client")
errFailedConnectionCreation = errors.New("failed to create connection")

smqSDKInstance smqSDK.SDK
smqsdk smqSDK.SDK
namegen = namegenerator.NewGenerator()
fileName = "config.toml"
)

const filePermission = 0o644

// SetSuperMQSDK sets supermq SDK instance.
func SetSuperMQSDK(s smqSDK.SDK) {
smqSDKInstance = s
}

type Result struct {
ManagerThing smqSDK.Thing `json:"manager_thing,omitempty"`
ManagerChannel smqSDK.Channel `json:"manager_channel,omitempty"`
PropletThing smqSDK.Thing `json:"proplet_thing,omitempty"`
PropletChannel smqSDK.Channel `json:"proplet_channel,omitempty"`
func SetSuperMQSDK(sdk smqSDK.SDK) {
smqsdk = sdk
}

var provisionCmd = &cobra.Command{
Use: "provision",
Short: "Provision resources",
Long: `Provision necessary resources for Propeller operation.`,
Run: func(cmd *cobra.Command, args []string) {
u := smqSDK.Login{
Identity: "admin@example.com",
Secret: "12345678",
}

tkn, err := smqSDKInstance.CreateToken(u)
if err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedToCreateToken, err))

return
}
logSuccessCmd(*cmd, "Successfully created access token")

domain := smqSDK.Domain{
Name: "demo",
Alias: "demo",
Permission: "admin",
}

domain, err = smqSDKInstance.CreateDomain(domain, tkn.AccessToken)
if err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedToCreateDomain, err))

return
}
logSuccessCmd(*cmd, "Successfully created domain")

managerThing := smqSDK.Thing{
Name: "Propeller Manager",
Tags: []string{"manager", "propeller"},
Status: "enabled",
}

managerThing, err = smqSDKInstance.CreateThing(managerThing, domain.ID, tkn.AccessToken)
if err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedClientCreation, err))

return
}
logSuccessCmd(*cmd, "Successfully created manager client")

propletThing := smqSDK.Thing{
Name: "Propeller Proplet",
Tags: []string{"proplet", "propeller"},
Status: "enabled",
}

propletThing, err = smqSDKInstance.CreateThing(propletThing, domain.ID, tkn.AccessToken)
if err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedClientCreation, err))

return
}
logSuccessCmd(*cmd, "Successfully created proplet client")

managerChannel := smqSDK.Channel{
Name: "Propeller Manager",
Status: "enabled",
}
managerChannel, err = smqSDKInstance.CreateChannel(managerChannel, domain.ID, tkn.AccessToken)
if err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedChannelCreation, err))

return
}
logSuccessCmd(*cmd, "Successfully created manager channel")

managerConns := smqSDK.Connection{
ThingID: managerThing.ID,
ChannelID: managerChannel.ID,
}
err = smqSDKInstance.Connect(managerConns, domain.ID, tkn.AccessToken)
if err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedConnectionCreation, err))

return
}
logSuccessCmd(*cmd, "Successfully created manager connections")

propletConns := smqSDK.Connection{
ThingID: propletThing.ID,
ChannelID: managerChannel.ID,
}
var (
identity string
secret string
err error
token smqSDK.Token
domainName string
domainAlias string
domainPermission string
domain smqSDK.Domain
managerThingName string
managerThing smqSDK.Thing
propletThingName string
propletThing smqSDK.Thing
managerChannelName string
managerChannel smqSDK.Channel
)
form := huh.NewForm(
huh.NewGroup(
huh.NewInput().
Title("Enter your identity (e-mail)?").
Value(&identity).
Validate(func(str string) error {
if str == "" {
return errors.New("identity is required")
}

return nil
}),
huh.NewInput().
Title("Enter your secret").
EchoMode(huh.EchoModePassword).
Value(&secret).
Validate(func(str string) error {
if str == "" {
return errors.New("secret is required")
}
u := smqSDK.Login{
Identity: identity,
Secret: secret,
}

token, err = smqsdk.CreateToken(u)
if err != nil {
return errors.Wrap(errFailedToCreateToken, err)
}

return nil
}),
),
huh.NewGroup(
huh.NewInput().
Title("Enter your domain name(leave empty to auto generate)").
Value(&domainName),
huh.NewInput().
Title("Enter your domain alias(leave empty to auto generate)").
Value(&domainAlias),
huh.NewSelect[string]().
Title("Select your domain permission").
Options(
huh.NewOption("admin", "admin"),
huh.NewOption("edit", "edit"),
huh.NewOption("view", "view"),
).
Value(&domainPermission).
Validate(func(str string) error {
if domainName == "" {
domainName = namegen.Generate()
}
if domainAlias == "" {
domainAlias = strings.ToLower(domainName)
}
domain = smqSDK.Domain{
Name: domainName,
Alias: domainAlias,
Permission: domainPermission,
}
domain, err = smqsdk.CreateDomain(domain, token.AccessToken)
if err != nil {
return errors.Wrap(errFailedToCreateDomain, err)
}

return nil
}),
),
huh.NewGroup(
huh.NewInput().
Title("Enter your manager thing name(leave empty to auto generate)").
Value(&managerThingName).
Validate(func(str string) error {
if str == "" {
managerThingName = namegen.Generate()
}
managerThing = smqSDK.Thing{
Name: managerThingName,
Tags: []string{"manager", "propeller"},
Status: "enabled",
}
managerThing, err = smqsdk.CreateThing(managerThing, domain.ID, token.AccessToken)
if err != nil {
return errors.Wrap(errFailedClientCreation, err)
}

return nil
}),
),
huh.NewGroup(
huh.NewInput().
Title("Enter your proplet thing name(leave empty to auto generate)").
Value(&propletThingName).
Validate(func(str string) error {
if str == "" {
propletThingName = namegen.Generate()
}
propletThing = smqSDK.Thing{
Name: propletThingName,
Tags: []string{"proplet", "propeller"},
Status: "enabled",
}
propletThing, err = smqsdk.CreateThing(propletThing, domain.ID, token.AccessToken)
if err != nil {
return errors.Wrap(errFailedClientCreation, err)
}

return nil
}),
), huh.NewGroup(
huh.NewInput().
Title("Enter your manager channel name(leave empty to auto generate)").
Value(&managerChannelName).
Validate(func(str string) error {
if str == "" {
managerChannelName = namegen.Generate()
}
managerChannel = smqSDK.Channel{
Name: managerChannelName,
Status: "enabled",
}
managerChannel, err = smqsdk.CreateChannel(managerChannel, domain.ID, token.AccessToken)
if err != nil {
return errors.Wrap(errFailedChannelCreation, err)
}

managerConns := smqSDK.Connection{
ThingID: managerThing.ID,
ChannelID: managerChannel.ID,
}
if err = smqsdk.Connect(managerConns, domain.ID, token.AccessToken); err != nil {
return errors.Wrap(errFailedConnectionCreation, err)
}

propletConns := smqSDK.Connection{
ThingID: propletThing.ID,
ChannelID: managerChannel.ID,
}
if err = smqsdk.Connect(propletConns, domain.ID, token.AccessToken); err != nil {
return errors.Wrap(errFailedConnectionCreation, err)
}

return nil
}),
),
)

err = smqSDKInstance.Connect(propletConns, domain.ID, tkn.AccessToken)
if err != nil {
if err := form.Run(); err != nil {
logErrorCmd(*cmd, errors.Wrap(errFailedConnectionCreation, err))

return
}
logSuccessCmd(*cmd, "Successfully created proplet connections")

res := Result{
ManagerThing: managerThing,
ManagerChannel: managerChannel,
PropletThing: propletThing,
PropletChannel: managerChannel,
}

configContent := fmt.Sprintf(`# SuperMQ Configuration
Expand Down Expand Up @@ -164,17 +231,24 @@ channel_id = "%s"`,
managerChannel.ID,
)

if err := os.WriteFile("config.toml", []byte(configContent), filePermission); err != nil {
logErrorCmd(*cmd, errors.New("failed to create config.toml file"))
if err := os.WriteFile(fileName, []byte(configContent), filePermission); err != nil {
logErrorCmd(*cmd, errors.New(fmt.Sprintf("failed to create %s file", fileName)))

return
}
logSuccessCmd(*cmd, "Successfully created config.toml file")

logJSONCmd(*cmd, res)
logSuccessCmd(*cmd, fmt.Sprintf("Successfully created %s file", fileName))
},
}

func NewProvisionCmd() *cobra.Command {
provisionCmd.PersistentFlags().StringVarP(
&fileName,
"file-name",
"f",
fileName,
"The name of the file to create",
)

return provisionCmd
}
24 changes: 3 additions & 21 deletions cli/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import (
)

var (
DefTLSVerification = false
DefManagerURL = "http://localhost:7070"
defOffset uint64 = 0
defLimit uint64 = 10
defOffset uint64 = 0
defLimit uint64 = 10
)

var psdk sdk.SDK

func SetSDK(s sdk.SDK) {
func SetPropellerSDK(s sdk.SDK) {
psdk = s
}

Expand Down Expand Up @@ -153,14 +151,6 @@ func NewTasksCmd() *cobra.Command {
cmd.AddCommand(&tasksCmd[i])
}

cmd.PersistentFlags().StringVarP(
&DefManagerURL,
"manager-url",
"m",
DefManagerURL,
"Manager URL",
)

cmd.PersistentFlags().Uint64VarP(
&defOffset,
"offset",
Expand All @@ -177,13 +167,5 @@ func NewTasksCmd() *cobra.Command {
"Limit",
)

cmd.PersistentFlags().BoolVarP(
&DefTLSVerification,
"tls-verification",
"v",
DefTLSVerification,
"TLS Verification",
)

return &cmd
}
Loading

0 comments on commit 4901399

Please sign in to comment.