tentez

package module
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2024 License: MIT Imports: 20 Imported by: 0

README

Tentez

Tentez helps you switching traffic.

Installation

If you don't want to build from source go grab a binary release.

or use go install

$ go install github.com/FeLvi-zzz/tentez/cmd/tentez@latest

Usage

# show plan
$ tentez -f ./examples/example.yaml plan
Plan
1. pause
2. switch old:new = 70:30
  - tentez-web
  - tentez-api
  - tentez-foo
3. sleep 600s
4. pause
5. switch old:new = 30:70
  - tentez-web
  - tentez-api
  - tentez-foo
6. sleep 600s
7. pause
8. switch old:new = 0:100
  - tentez-web
  - tentez-api
  - tentez-foo
9. sleep 600s
# show plan and apply
$ tentez -f ./examples/example.yaml apply
Plan
1. pause
2. switch old:new = 70:30
  1. tentez-web
  2. tentez-api
  3. tentez-foo
3. sleep 600s
4. pause
5. switch old:new = 30:70
  1. tentez-web
  2. tentez-api
  3. tentez-foo
6. sleep 600s
7. pause
8. switch old:new = 0:100
  1. tentez-web
  2. tentez-api
  3. tentez-foo
9. sleep 600s

1 / 9 steps
Pause
enter "yes", continue steps.
If you'd like to interrupt steps, enter "quit".
> yes

2 / 9 steps
Switch old:new = 70:30
1. tentez-web switched!
2. tentez-api switched!
3. tentez-foo switched!

3 / 9 steps
Sleep 600s
Resume at 2022-02-05 15:10:03
Remain: 600s
...
Remain: 1s
Resume

(...snip)

Apply complete!
# get target resources' current states.
$ tentez -f ./examples/example.yaml get
aws_listeners:
- target: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:listener/app/my-lb/0123456789abcdef/0123456789abcdef
  weights:
  - arn: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets1/0123456789abcdef
    weight: 0
  - arn: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets2/fedcba9876543210
    weight: 100
aws_listener_rules:
- target: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:listener/app/my-lb/0123456789abcdef/0123456789abcdef/0123456789abcdef
  weights:
  - arn: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets1/0123456789abcdef
    weight: 0
  - arn: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets2/fedcba9876543210
    weight: 100
- target: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:listener/app/my-lb/0123456789abcdef/0123456789abcdef/0123456789abcdef
  weights:
  - arn: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets1/0123456789abcdef
    weight: 0
  - arn: arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-targets2/fedcba9876543210
    weight: 100
# rollback
# if you want to skip the pause step, add `--no-pause` flag.
$ tentez -f ./examples/example.yaml rollback
1. pause
2. switch old:new = 100:0
  1. tentez-web
  2. tentez-api
  3. tentez-foo

1 / 2 steps
Pause
enter "yes", continue steps.
If you'd like to interrupt steps, enter "quit".
> yes
continue step

2 / 2 steps
Switch old:new = 100:0
1. tentez-web switched!
2. tentez-api switched!
3. tentez-foo switched!
Switched at 2022-03-12 12:05:30

Apply complete!
# switch weights
# this command overrides steps of the config file.
# if you want to skip the pause step, add `--no-pause` flag.
$ tentez -f ./examples/example.yaml switch --weights 70,30
1. pause
2. switch old:new = 70:30
  1. tentez-web
  2. tentez-api
  3. tentez-foo

1 / 2 steps
Pause
enter "yes", continue steps.
If you'd like to interrupt steps, enter "quit".
> yes
continue step

2 / 2 steps
Switch old:new = 70:30
1. tentez-web switched!
2. tentez-api switched!
3. tentez-foo switched!
Switched at 2023-05-25 13:18:25

Apply complete!
# show version
$ tentez version
tentez version: x.x.x (rev: xxxxxxx)
# generate config from terraform plan json
$ terraform plan -out tfplan && terraform show -json tfplan > tfplan.json
$ tentez generate-config tfplanjson -f ./tfplan.json -o tentez.yaml

For instance, you can generate a config from the below terraform diff.

 resource "aws_lb_listener" "example" {
   ...

   default_action {
     type             = "forward"
-    target_group_arn = aws_lb_target_group.old.arn
+    target_group_arn = aws_lb_target_group.new.arn
   }
 }
# generate config from tagged AWS resouces
$ tentez generate-config resource-tag -f examples/tentez.ResourceTag.v1beta1.yaml

Refer examples/tentez.ResourceTag.v1beta1.yaml.

Assume other IAM Role
# set `AWS_ASSUME_ROLE_ARN` environment variable
$ AWS_ASSUME_ROLE_ARN=[IAM_ROLE_ARN] tentez -f ./examples/example.yaml get

Available resources

  • AWS
    • Listener
      • forward target group. for default LB listener rule.
    • Listener Rule
      • forward target group. for except default LB listner rule.

Why is named "Tentez"?

A tentetsuki is railroad switch in Japanese. It is a mechanical device used to guide trains from one track to another. This tool switches traffic, like a "tentetsuki".

"Tentez" pronounces "ten-tets".

Documentation

Overview

Example
t, err := tentez.New(
	context.TODO(),
	map[tentez.TargetType]tentez.Targets{
		tentez.TargetTypeAwsListenerRule: tentez.AwsListenerRules([]tentez.AwsListenerRule{}),
		tentez.TargetTypeAwsListener:     tentez.AwsListeners([]tentez.AwsListener{}),
	},
	[]tentez.Step{
		{
			Type: tentez.StepTypeSleep,
		},
	},
)
if err != nil {
	return
}

targetsData, err := t.Get(context.TODO())
if err != nil {
	return
}

output, err := yaml.Marshal(&targetsData)
if err != nil {
	return
}
fmt.Print(string(output))

data, ok := targetsData[tentez.TargetTypeAwsListener].([]tentez.AwsListenerData)
if ok && len(data) > 0 {
	name := data[0].Name
	fmt.Println(name)
}
Output:

Index

Examples

Constants

View Source
const Version = "0.11.0"

Variables

View Source
var Revision = "Devel"

Functions

func New added in v0.4.1

func New(ctx context.Context, targets map[TargetType]Targets, steps []Step) (tentez, error)

func NewFailedFetchTargetGroupsError added in v0.10.3

func NewFailedFetchTargetGroupsError(tgs []string) error

Types

type AwsListener

type AwsListener struct {
	Name   string `yaml:"name"`
	Target string `yaml:"target"`
	Switch Switch `yaml:"switch"`
}

type AwsListenerData

type AwsListenerData struct {
	Name              string                      `yaml:"name"`
	ListnerArn        string                      `yaml:"target"`
	Weights           []AwsTargetGroupTuple       `yaml:"weights"`
	AdditionalActions []elbv2Types.ActionTypeEnum `yaml:"additional_actions,omitempty"`
}

type AwsListenerRule

type AwsListenerRule struct {
	Name   string `yaml:"name"`
	Target string `yaml:"target"`
	Switch Switch `yaml:"switch"`
}

type AwsListenerRuleData

type AwsListenerRuleData struct {
	Name              string                      `yaml:"name"`
	ListenerRuleArn   string                      `yaml:"target"`
	Weights           []AwsTargetGroupTuple       `yaml:"weights"`
	AdditionalActions []elbv2Types.ActionTypeEnum `yaml:"additional_actions,omitempty"`
}

type AwsListenerRules

type AwsListenerRules []AwsListenerRule

type AwsListeners

type AwsListeners []AwsListener

type AwsTargetGroupTuple

type AwsTargetGroupTuple struct {
	TargetGroupArn string `yaml:"arn"`
	Weight         int32  `yaml:"weight"`
	Type           string `yaml:"type"`
}

type Change added in v0.7.0

type Change struct {
	Actions ChangeActions   `json:"actions"`
	Before  json.RawMessage `json:"before"`
	After   json.RawMessage `json:"after"`
}

type ChangeAction added in v0.7.0

type ChangeAction string
const (
	ChangeActionNoop   ChangeAction = "no-op"
	ChangeActionCreate ChangeAction = "create"
	ChangeActionRead   ChangeAction = "read"
	ChangeActionUpdate ChangeAction = "update"
	ChangeActionDelete ChangeAction = "delete"
)

type ChangeActions added in v0.7.0

type ChangeActions []ChangeAction

func (ChangeActions) IsUpdate added in v0.7.0

func (c ChangeActions) IsUpdate() bool

type ChangeValueAwsListener added in v0.7.0

type ChangeValueAwsListener struct {
	Arn            string                         `json:"arn"`
	DefaultActions []ChangeValueElbV2TargetAction `json:"default_action"`
}

func (ChangeValueAwsListener) GetSwitchTarget added in v0.7.0

func (c ChangeValueAwsListener) GetSwitchTarget() (string, error)

func (ChangeValueAwsListener) GetTarget added in v0.7.0

func (c ChangeValueAwsListener) GetTarget() (string, error)

type ChangeValueAwsListenerRule added in v0.7.0

type ChangeValueAwsListenerRule struct {
	Arn     string                         `json:"arn"`
	Actions []ChangeValueElbV2TargetAction `json:"action"`
}

func (ChangeValueAwsListenerRule) GetSwitchTarget added in v0.7.0

func (c ChangeValueAwsListenerRule) GetSwitchTarget() (string, error)

func (ChangeValueAwsListenerRule) GetTarget added in v0.7.0

func (c ChangeValueAwsListenerRule) GetTarget() (string, error)

type ChangeValueElbV2TargetAction added in v0.7.0

type ChangeValueElbV2TargetAction struct {
	TargetGroupArn string                                `json:"target_group_arn"`
	Forward        []ChangeValueElbV2TargetActionForward `json:"forward"`
}

type ChangeValueElbV2TargetActionForward added in v0.7.0

type ChangeValueElbV2TargetActionForward struct {
	TargetGroups []ChangeValueElbV2TargetActionForwardTargetGroups `json:"target_group"`
}

type ChangeValueElbV2TargetActionForwardTargetGroups added in v0.7.0

type ChangeValueElbV2TargetActionForwardTargetGroups struct {
	Arn    string `json:"arn"`
	Weight int    `json:"weight"`
}

type ChangeValueInterface added in v0.7.0

type ChangeValueInterface interface {
	GetTarget() (string, error)
	GetSwitchTarget() (string, error)
}

type Client added in v0.2.0

type Client struct {
	// contains filtered or unexported fields
}

type Clock added in v0.10.0

type Clock interface {
	Sleep(duration time.Duration)
}

type Config added in v0.2.0

type Config struct {
	// contains filtered or unexported fields
}

func NewConfig added in v0.10.0

func NewConfig(ctx context.Context) (Config, error)

type FailedFetchTargetGroupsError added in v0.10.3

type FailedFetchTargetGroupsError struct {
	// contains filtered or unexported fields
}

func (*FailedFetchTargetGroupsError) Error added in v0.10.3

func (*FailedFetchTargetGroupsError) Is added in v0.10.3

func (f *FailedFetchTargetGroupsError) Is(target error) bool

type GenerateConfigResourceTag added in v0.10.0

type GenerateConfigResourceTag struct {
	Version GenerateConfigResourceTagVersion `yaml:"version"`
}

type GenerateConfigResourceTagV1beta1 added in v0.10.0

type GenerateConfigResourceTagV1beta1 struct {
	Spec GenerateConfigResourceTagV1beta1Spec `yaml:"spec"`
}

type GenerateConfigResourceTagV1beta1Spec added in v0.10.0

type GenerateConfigResourceTagV1beta1Spec struct {
	FilterTags      map[string]string `yaml:"filterTags"`
	MatchingTagKeys []string          `yaml:"matchingTagKeys"`
	SwitchTag       struct {
		Key   string `yaml:"key"`
		Value struct {
			Old string `yaml:"old"`
			New string `yaml:"new"`
		} `yaml:"value"`
	} `yaml:"switchTag"`
}

type GenerateConfigResourceTagVersion added in v0.10.0

type GenerateConfigResourceTagVersion string
const (
	GenerateConfigResourceTagVersionV1beta1 GenerateConfigResourceTagVersion = "tentez.ResourceTag.v1beta1"
)

type RealClock added in v0.10.0

type RealClock struct{}

func (RealClock) Sleep added in v0.10.0

func (c RealClock) Sleep(duration time.Duration)

type ResourceChange added in v0.7.0

type ResourceChange struct {
	Address string `json:"address"`
	Type    string `json:"type"`
	Change  Change `json:"change"`
}

type SkipSwitchError added in v0.4.0

type SkipSwitchError struct {
	Message string
}

func (SkipSwitchError) Error added in v0.4.0

func (s SkipSwitchError) Error() string

type Step

type Step struct {
	Type         StepType `yaml:"type"`
	Weight       Weight   `yaml:"weight,omitempty"`
	SleepSeconds int      `yaml:"sleepSeconds,omitempty"`
}

type StepType added in v0.4.1

type StepType string
const (
	StepTypePause  StepType = "pause"
	StepTypeSleep  StepType = "sleep"
	StepTypeSwitch StepType = "switch"
)

type Switch

type Switch struct {
	Old string
	New string
}

type Target added in v0.2.0

type Target interface {
	// contains filtered or unexported methods
}

type TargetType added in v0.4.1

type TargetType string
const (
	TargetTypeAwsListener     TargetType = "aws_listeners"
	TargetTypeAwsListenerRule TargetType = "aws_listener_rules"
)

type Targets added in v0.2.0

type Targets interface {
	// contains filtered or unexported methods
}

type TargetsData added in v0.5.0

type TargetsData interface{}

type Tentez added in v0.2.0

type Tentez interface {
	Plan() error
	Apply(ctx context.Context, isForce bool) error
	Get(ctx context.Context) (map[TargetType]TargetsData, error)
	Rollback(ctx context.Context, hasPause bool) error
	Switch(wctx context.Context, eights []int, hasPause bool) error
}

func NewFromYaml added in v0.2.0

func NewFromYaml(ctx context.Context, filename string) (t Tentez, err error)

type TerraformPlanJson added in v0.7.0

type TerraformPlanJson struct {
	FormatVersion   string           `json:"format_version"`
	ResourceChanges []ResourceChange `json:"resource_changes"`
}

type Ui added in v0.10.3

type Ui interface {
	Ask(prompt string) string

	Outputln(s string)
	Outputf(format string, a ...interface{})

	OutputErrln(s string)
	OutputErrf(format string, a ...interface{})
}

type Weight

type Weight struct {
	Old int32
	New int32
}

func (Weight) CalcNewRatio added in v0.4.0

func (w Weight) CalcNewRatio() float64

func (Weight) CalcOldRatio added in v0.4.0

func (w Weight) CalcOldRatio() float64

type YamlStruct

type YamlStruct struct {
	Steps            []Step           `yaml:"steps"`
	AwsListeners     AwsListeners     `yaml:"aws_listeners"`
	AwsListenerRules AwsListenerRules `yaml:"aws_listener_rules"`
}

func GenerateConfigFromResourceTags added in v0.10.0

func GenerateConfigFromResourceTags(
	ctx context.Context,
	filterTags map[string]string,
	matchingTagKeys []string,
	switchKey string,
	oldValue string,
	newValue string,
	cfg Config,
) (YamlStruct, error)

func GenerateConfigFromTerraformPlanJsons added in v0.7.1

func GenerateConfigFromTerraformPlanJsons(jsons []TerraformPlanJson) (YamlStruct, error)

Directories

Path Synopsis
cmd
internal
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL