Skip to content

Commit

Permalink
feat: manage infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
Ric Featherstone authored and 06kellyjac committed Dec 21, 2023
1 parent 6c7c860 commit 2ba0555
Show file tree
Hide file tree
Showing 62 changed files with 2,751 additions and 1 deletion.
19 changes: 19 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.idea/
.git/
.simulator/
bin/
config/
docs/
internal/
simulation-scripts/
terraform/workspaces/simulator/.terraform/
.dockerignore
.editorconfig
.gitignore
aws-environment
dev.Dockerfile
Dockerfile
LICENSE
Makefile
README.md
SECURITY.md
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea/
.simulator/
config/*
!config/.gitkeep
bin/
terraform/workspaces/simulator/.terraform/
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM controlplane/simulator:dev

COPY --chown=ubuntu:ubuntu packer packer
COPY --chown=ubuntu:ubuntu terraform terraform
COPY --chown=ubuntu:ubuntu scenarios scenarios

RUN cd terraform/workspaces/simulator && terraform init -backend=false
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
SIMULATOR_IMAGE ?= controlplane/simulator

simulator-dev-image:
docker build -t $(SIMULATOR_IMAGE):dev -f dev.Dockerfile .

simulator-dev-image-run:
docker run -it --rm \
-v ~/.aws:/home/ubuntu/.aws \
-v $(shell pwd)/ansible:/simulator/ansible \
-v $(shell pwd)/config:/simulator/config:rw \
-v $(shell pwd)/packer:/simulator/packer \
-v $(shell pwd)/terraform:/simulator/terraform \
--env-file aws-environment \
--entrypoint bash \
$(SIMULATOR_IMAGE):dev \

simulator-image: simulator-dev-image
docker build -t $(SIMULATOR_IMAGE) .

simulator-image-run:
docker run -it --rm \
-v ~/.aws:/home/ubuntu/.aws \
-v $(shell pwd)/config:/simulator/config:rw \
--env-file aws-environment \
--entrypoint bash \
$(SIMULATOR_IMAGE):latest \

simulator-cli:
go build -v -o bin/simulator internal/cmd/main.go


61 changes: 61 additions & 0 deletions ansible/init-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---

- name: Initialise the kubernetes cluster
hosts: all
gather_facts: no
become: yes
tasks:
- name: Run kubeadm init
ansible.builtin.shell:
cmd: kubeadm init
creates: /etc/kubernetes/admin.conf
when: inventory_hostname in groups['masters'][0]

- name: Create join command
ansible.builtin.shell: kubeadm token create --print-join-command
become: yes
register: join_command
when: inventory_hostname in groups['masters'][0]

- name: Join nodes
ansible.builtin.shell: "{{ hostvars[groups['masters'][0]].join_command.stdout }}"
when: inventory_hostname in groups['nodes']

- name: Create .kube directories on bastion
ansible.builtin.file:
path: "/home/{{ item }}/.kube"
state: directory
owner: "{{ item }}"
group: "{{ item }}"
mode: '0755'
loop:
- ubuntu
- player
when: "'bastion' in inventory_hostname"

- name: Retrieve kubeconfig from master
ansible.builtin.fetch:
src: /etc/kubernetes/admin.conf
dest: kubeconfig
flat: yes
when: "'master-1' in inventory_hostname"

- name: Copy kubeconfig to bastion
ansible.builtin.copy:
src: kubeconfig
dest: "/home/{{ item }}/.kube/config"
owner: "{{ item }}"
group: "{{ item }}"
mode: 0440
loop:
- ubuntu
- player
when: "'bastion' in inventory_hostname"

- name: Remove pulled kubeconfig
ansible.builtin.file:
path: kubeconfig
state: absent
become: no
run_once: yes
delegate_to: localhost
8 changes: 8 additions & 0 deletions ansible/update-known-hosts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

- hosts: all
gather_facts: no
become: no
tasks:
- ansible.builtin.wait_for_connection:
- ansible.builtin.ping:
5 changes: 5 additions & 0 deletions aws-environment
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
AWS_PROFILE
AWS_REGION
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
Empty file added config/.gitkeep
Empty file.
55 changes: 55 additions & 0 deletions controlplane/aws/aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package aws

import (
"context"
"fmt"
"log/slog"
"os"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
)

var (
Env []string
)

func CreateBucket(ctx context.Context, name string) error {
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
slog.Error("failed to create aws config", "error", err)
}

client := s3.NewFromConfig(cfg)
_, err = client.CreateBucket(ctx, &s3.CreateBucketInput{
Bucket: aws.String(name),
CreateBucketConfiguration: &types.CreateBucketConfiguration{
LocationConstraint: types.BucketLocationConstraintEuWest2, // TODO: lookup AWS_REGION
},
})
if err != nil { // TODO: ignore bucket already exists, and you own it
slog.Error("failed to create s3 bucket", "error", err)
return err
}

return nil
}

func init() {
envKeys := []string{
"AWS_PROFILE",
"AWS_REGION",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"AWS_SESSION_TOKEN",
}

for _, key := range envKeys {
value, ok := os.LookupEnv(key)
if ok && len(value) > 0 {
Env = append(Env, fmt.Sprintf("%s=%s", key, value))
}
}
}
37 changes: 37 additions & 0 deletions controlplane/cli/image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cli

import (
"context"
"os"
"os/signal"

"github.com/spf13/cobra"

"github.com/controlplaneio/simulator/controlplane"
)

var (
template string
)

var imageCmd = &cobra.Command{
Use: "image",
}

var buildCmd = &cobra.Command{
Use: "build",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

cp := controlplane.New()
return cp.BuildImage(ctx, controlplane.PackerTemplate(template))
},
}

func init() {
buildCmd.Flags().StringVar(&template, "template", "", "the packer template to build")

imageCmd.AddCommand(buildCmd)
simulatorCmd.AddCommand(imageCmd)
}
47 changes: 47 additions & 0 deletions controlplane/cli/infra.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cli

import (
"context"
"os"
"os/signal"

"github.com/spf13/cobra"

"github.com/controlplaneio/simulator/controlplane"
)

var infraCmd = &cobra.Command{
Use: "infra",
}

var createCmd = &cobra.Command{
Use: "create",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

cp := controlplane.New()
return cp.CreateInfrastructure(ctx, bucket, key, name)
},
}

var destroyCmd = &cobra.Command{
Use: "destroy",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

cp := controlplane.New()
return cp.DestroyInfrastructure(ctx, bucket, key, name)
},
}

func init() {
infraCmd.PersistentFlags().StringVar(&bucket, "bucket", "", "the s3 bucket to use")
infraCmd.PersistentFlags().StringVar(&key, "key", "state/terraform.tfstate", "the key to store state in the s3 bucket")
infraCmd.PersistentFlags().StringVar(&name, "name", "", "the name for the infrastructure")

infraCmd.AddCommand(createCmd)
infraCmd.AddCommand(destroyCmd)
simulatorCmd.AddCommand(infraCmd)
}
46 changes: 46 additions & 0 deletions controlplane/cli/scenario.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cli

import (
"context"
"os"
"os/signal"

"github.com/spf13/cobra"

"github.com/controlplaneio/simulator/controlplane"
)

var scenarioCmd = &cobra.Command{
Use: "scenario",
}

var installCmd = &cobra.Command{
Use: "install",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

cp := controlplane.New()
return cp.InstallScenario(ctx, name)
},
}

var uninstallCmd = &cobra.Command{
Use: "uninstall",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

cp := controlplane.New()
return cp.UninstallScenario(ctx, name)
},
}

func init() {
scenarioCmd.PersistentFlags().StringVar(&name, "name", "", "the name of the scenario to deploy")

scenarioCmd.AddCommand(installCmd)
scenarioCmd.AddCommand(uninstallCmd)
simulatorCmd.AddCommand(scenarioCmd)

}
18 changes: 18 additions & 0 deletions controlplane/cli/simulator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cli

import (
"github.com/spf13/cobra"
)

var (
bucket, key, name string
)

var simulatorCmd = &cobra.Command{
Use: "simulator",
}

func Execute() {
err := simulatorCmd.Execute()
cobra.CheckErr(err)
}
33 changes: 33 additions & 0 deletions controlplane/cli/storage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cli

import (
"context"
"os"
"os/signal"

"github.com/spf13/cobra"

"github.com/controlplaneio/simulator/controlplane"
)

var bucketCmd = &cobra.Command{
Use: "bucket",
}

var createBucketCmd = &cobra.Command{
Use: "create",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

cp := controlplane.New()
return cp.CreateBucket(ctx, bucket)
},
}

func init() {
createBucketCmd.Flags().StringVar(&bucket, "name", "", "the name of the bucket to create")

bucketCmd.AddCommand(createBucketCmd)
simulatorCmd.AddCommand(bucketCmd)
}
Loading

0 comments on commit 2ba0555

Please sign in to comment.