Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add preview to providers and custom tea lifecycle #543

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions cloud/aws/deploy/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,26 @@ func (d *DeployServer) Down(request *deploy.DeployDownRequest, stream deploy.Dep
optdestroy.ProgressStreams(noninteractive.NewNonInterativeOutput(outputStream)),
}

var interactiveProgram *interactive.Program
if request.Interactive {
pulumiEventChan := make(chan events.EngineEvent)
deployModel, err := interactive.NewOutputModel(make(chan tea.Msg), pulumiEventChan)
if err != nil {
return err
}

teaProgram := tea.NewProgram(deployModel, tea.WithOutput(outputStream))
pulumiDestroyOpts = []optdestroy.Option{
optdestroy.ProgressStreams(deployModel),
optdestroy.EventStreams(pulumiEventChan),
}

//nolint:errcheck
go teaProgram.Run()
// Close the program when we're done
defer teaProgram.Quit()
interactiveProgram = interactive.NewProgram(deployModel, &interactive.ProgramArgs{
Writer: outputStream,
})

go interactiveProgram.Run()

defer interactiveProgram.Stop()
}

s, err := auto.UpsertStackInlineSource(context.TODO(), details.FullStackName, details.Project, nil)
Expand All @@ -73,9 +76,6 @@ func (d *DeployServer) Down(request *deploy.DeployDownRequest, stream deploy.Dep

// destroy the stack
_, err = s.Destroy(context.TODO(), pulumiDestroyOpts...)
if err != nil {
return err
}

return nil
return err
}
115 changes: 115 additions & 0 deletions cloud/aws/deploy/preview.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright Nitric Pty Ltd.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package deploy

import (
"context"
"fmt"
"runtime/debug"

tea "github.com/charmbracelet/bubbletea"
"github.com/nitrictech/nitric/cloud/aws/deploy/config"
commonDeploy "github.com/nitrictech/nitric/cloud/common/deploy"
"github.com/nitrictech/nitric/cloud/common/deploy/output/interactive"
"github.com/nitrictech/nitric/cloud/common/deploy/output/noninteractive"
pulumiutils "github.com/nitrictech/nitric/cloud/common/deploy/pulumi"
deploy "github.com/nitrictech/nitric/core/pkg/api/nitric/deploy/v1"
"github.com/pulumi/pulumi/sdk/v3/go/auto"
"github.com/pulumi/pulumi/sdk/v3/go/auto/events"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// Preview - Dry run deployment for requested infrastructure for a stack
func (d *DeployServer) Preview(request *deploy.DeployPreviewRequest, stream deploy.DeployService_PreviewServer) (err error) {
defer func() {
if r := recover(); r != nil {
stack := string(debug.Stack())
err = fmt.Errorf("recovered panic: %+v\n Stack: %s", r, stack)
}
}()

details, err := commonDeploy.CommonStackDetailsFromAttributes(request.Attributes.AsMap())
if err != nil {
return status.Errorf(codes.InvalidArgument, err.Error())
}

config, err := config.ConfigFromAttributes(request.Attributes.AsMap())
if err != nil {
return status.Errorf(codes.InvalidArgument, "Bad stack configuration: %s", err)
}

// If we're interactive then we want to provide
outputStream := &pulumiutils.PreviewStreamMessageWriter{
Stream: stream,
}

// Default to the non-interactive writer
pulumiPreviewOpts := []optpreview.Option{
optpreview.ProgressStreams(noninteractive.NewNonInterativeOutput(outputStream)),
}

var interactiveProgram *interactive.Program
if request.Interactive {
pulumiEventChan := make(chan events.EngineEvent)
deployModel, err := interactive.NewOutputModel(make(chan tea.Msg), pulumiEventChan)
if err != nil {
return err
}

pulumiPreviewOpts = []optpreview.Option{
optpreview.ProgressStreams(deployModel),
optpreview.EventStreams(pulumiEventChan),
}

interactiveProgram = interactive.NewProgram(deployModel, &interactive.ProgramArgs{
Writer: outputStream,
})

go interactiveProgram.Run()

defer interactiveProgram.Stop()
}

pulumiStack, err := NewUpProgram(context.TODO(), details, config, request.Spec)
if err != nil {
return err
}

err = pulumiStack.SetAllConfig(context.TODO(), auto.ConfigMap{
"aws:region": auto.ConfigValue{Value: details.Region},
"aws:version": auto.ConfigValue{Value: pulumiAwsVersion},
"docker:version": auto.ConfigValue{Value: commonDeploy.PulumiDockerVersion},
})
if err != nil {
return err
}

if config.Refresh {
// TODO: Handle refresh logging
_, err := pulumiStack.Refresh(context.TODO())
if err != nil {
return err
}
}

// Run the program
_, err = pulumiStack.Preview(context.TODO(), pulumiPreviewOpts...)

return err
}
17 changes: 11 additions & 6 deletions cloud/aws/deploy/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,18 @@ func NewUpProgram(ctx context.Context, details *commonDeploy.CommonStackDetails,
return err
}

stackIdChan := make(chan string)
pulumi.Sprintf("%s-%s", ctx.Stack(), stackRandId.Result).ApplyT(func(id string) string {
stackIdChan <- id
return id
})
stackID := "stack-id"

if !ctx.DryRun() {
stackIdChan := make(chan string)
pulumi.Sprintf("%s-%s", ctx.Stack(), stackRandId.Result).ApplyT(func(id string) string {
stackIdChan <- id
return id
})

stackID = <-stackIdChan
}

stackID := <-stackIdChan
_, err = stack.NewAwsResourceGroup(ctx, details.FullStackName, &stack.AwsResourceGroupArgs{
StackID: stackID,
})
Expand Down
24 changes: 9 additions & 15 deletions cloud/aws/deploy/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,26 @@ func (d *DeployServer) Up(request *deploy.DeployUpRequest, stream deploy.DeployS
optup.ProgressStreams(noninteractive.NewNonInterativeOutput(outputStream)),
}

var interactiveProgram *interactive.Program
if request.Interactive {
pulumiEventChan := make(chan events.EngineEvent)
deployModel, err := interactive.NewOutputModel(make(chan tea.Msg), pulumiEventChan)
if err != nil {
return err
}

teaProgram := tea.NewProgram(deployModel, tea.WithOutput(&pulumiutils.UpStreamMessageWriter{
Stream: stream,
}))

pulumiUpOpts = []optup.Option{
optup.ProgressStreams(deployModel),
optup.EventStreams(pulumiEventChan),
}

//nolint:errcheck
go teaProgram.Run()
// Close the program when we're done
defer teaProgram.Quit()
interactiveProgram = interactive.NewProgram(deployModel, &interactive.ProgramArgs{
Writer: outputStream,
})

go interactiveProgram.Run()

defer interactiveProgram.Stop()
}

pulumiStack, err := NewUpProgram(context.TODO(), details, config, request.Spec)
Expand All @@ -109,13 +109,7 @@ func (d *DeployServer) Up(request *deploy.DeployUpRequest, stream deploy.DeployS
}

// Run the program
res, err := pulumiStack.Up(context.TODO(), pulumiUpOpts...)
if err != nil {
return err
}

// Send terminal message
err = stream.Send(pulumiutils.PulumiOutputsToResult(res.Outputs))
_, err = pulumiStack.Up(context.TODO(), pulumiUpOpts...)

return err
}
Loading
Loading