Skip to content
Merged
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
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ ENV PATH "$PATH:/draft/az-cli-env/bin"
RUN apk add github-cli

COPY . ./
RUN make go-generate

RUN go mod download
ENTRYPOINT ["go"]
13 changes: 3 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
.PHONY: all
all: go-generate build generate-integrations
all: build generate-integrations


.PHONY: go-generate
go-generate:
rm -r ./pkg/deployments/deployTypes; \
rm -r ./pkg/workflows/workflows; \
rm -r ./pkg/addons/addons; \
GO111MODULE=on go generate ./pkg/workflows/...; \

.PHONY: test
test: run-unit-tests run-e2e-tests-local

Expand All @@ -18,7 +11,7 @@ run-unit-tests:

#TODO: add more e2e tests to the local testing
.PHONY: run-e2e-tests-local
run-e2e-tests-local: go-generate build
run-e2e-tests-local: build
test/check_info_schema.sh;

.PHONY: generate-integrations
Expand All @@ -32,7 +25,7 @@ build:
GO111MODULE=on go build -v -o .

.PHONY: build-all
build-all: go-generate build-windows-amd64 build-linux-amd64 build-linux-arm64 build-darwin-amd64 build-darwin-arm64
build-all: build-windows-amd64 build-linux-amd64 build-linux-arm64 build-darwin-amd64 build-darwin-arm64

.PHONY: build-windows-amd64
build-windows-amd64:
Expand Down
20 changes: 11 additions & 9 deletions cmd/generate-workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/Azure/draft/pkg/handlers"
"github.com/Azure/draft/pkg/prompts"
"github.com/Azure/draft/pkg/templatewriter"
"github.com/Azure/draft/pkg/cmdhelpers"
"github.com/Azure/draft/pkg/templatewriter/writers"
"github.com/Azure/draft/pkg/workflows"
"github.com/Azure/draft/template"
)

type generateWorkflowCmd struct {
Expand Down Expand Up @@ -73,23 +73,25 @@ func (gwc *generateWorkflowCmd) generateWorkflows() error {
}
}

workflow := workflows.CreateWorkflowsFromEmbedFS(template.Workflows, gwc.dest)
draftConfig, err := workflow.GetConfig(gwc.deployType)
t, err := handlers.GetTemplate(fmt.Sprintf("github-workflow-%s", gwc.deployType), "", gwc.dest, gwc.templateWriter)
if err != nil {
return fmt.Errorf("get config: %w", err)
return fmt.Errorf("failed to get template: %e", err)
}
if t == nil {
return fmt.Errorf("template is nil")
}

draftConfig.VariableMapToDraftConfig(flagVariablesMap)
t.Config.VariableMapToDraftConfig(flagVariablesMap)

if err = prompts.RunPromptsFromConfigWithSkips(draftConfig); err != nil {
if err = prompts.RunPromptsFromConfigWithSkips(t.Config); err != nil {
return err
}

if err := workflows.UpdateProductionDeployments(gwc.deployType, gwc.dest, draftConfig, gwc.templateWriter); err != nil {
if err := cmdhelpers.UpdateProductionDeployments(gwc.deployType, gwc.dest, t.Config, gwc.templateWriter); err != nil {
return fmt.Errorf("update production deployments: %w", err)
}

return workflow.CreateWorkflowFiles(gwc.deployType, draftConfig, gwc.templateWriter)
return t.Generate()
}

func flagVariablesToMap(flagVariables []string) map[string]string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package workflows
package cmdhelpers

//GitHubWorkflow is a rough struct to allow for yaml editing including deletion of Job steps
// GitHubWorkflow is a rough struct to allow for yaml editing including deletion of Job steps
type GitHubWorkflow struct {
Name string
On on `yaml:"on"`
Expand Down
26 changes: 3 additions & 23 deletions pkg/workflows/workflows.go → pkg/cmdhelpers/workflow_helpers.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package workflows
package cmdhelpers

import (
"embed"
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path"

Expand All @@ -17,7 +15,6 @@ import (
log "github.com/sirupsen/logrus"

"github.com/Azure/draft/pkg/config"
"github.com/Azure/draft/pkg/embedutils"
"github.com/Azure/draft/pkg/osutil"
"github.com/Azure/draft/pkg/templatewriter"
)
Expand Down Expand Up @@ -61,7 +58,7 @@ func UpdateProductionDeployments(deployType, dest string, draftConfig *config.Dr
func setDeploymentContainerImage(filePath, productionImage string) error {

decode := scheme.Codecs.UniversalDeserializer().Decode
file, err := ioutil.ReadFile(filePath)
file, err := os.ReadFile(filePath)
if err != nil {
return err
}
Expand Down Expand Up @@ -97,7 +94,7 @@ func setDeploymentContainerImage(filePath, productionImage string) error {
}

func setHelmContainerImage(filePath, productionImage string, templateWriter templatewriter.TemplateWriter) error {
file, err := ioutil.ReadFile(filePath)
file, err := os.ReadFile(filePath)
if err != nil {
return err
}
Expand Down Expand Up @@ -146,23 +143,6 @@ func (w *Workflows) GetConfig(deployType string) (*config.DraftConfig, error) {
return val, nil
}

func CreateWorkflowsFromEmbedFS(workflowTemplates embed.FS, dest string) *Workflows {
deployMap, err := embedutils.EmbedFStoMap(workflowTemplates, parentDirName)
if err != nil {
log.Fatal(err)
}

w := &Workflows{
workflows: deployMap,
Dest: dest,
configs: make(map[string]*config.DraftConfig),
workflowTemplates: workflowTemplates,
}
w.populateConfigs()

return w
}

func (w *Workflows) populateConfigs() {
for deployType := range w.workflows {
draftConfig, err := w.loadConfig(deployType)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package workflows
package cmdhelpers

import (
"errors"
"io/ioutil"
"os"

"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -49,7 +48,7 @@ func (hpy *HelmProductionYaml) GetServiceName() string {
}

func (hpy *HelmProductionYaml) LoadFromFile(filePath string) error {
file, err := ioutil.ReadFile(filePath)
file, err := os.ReadFile(filePath)
if err != nil {
return err
}
Expand All @@ -63,7 +62,7 @@ func (hpy *HelmProductionYaml) WriteToFile(filePath string) error {
return err
}

return ioutil.WriteFile(filePath, currYaml, 0755)
return os.WriteFile(filePath, currYaml, 0755)
}

type ServiceYaml struct {
Expand All @@ -84,7 +83,10 @@ func (sy *ServiceYaml) GetServiceName() string {

func (sy *ServiceYaml) LoadFromFile(filePath string) error {
decode := scheme.Codecs.UniversalDeserializer().Decode
file, err := ioutil.ReadFile(filePath)
file, err := os.ReadFile(filePath)
if err != nil {
return err
}
k8sObj, _, err := decode(file, nil, nil)
if err != nil {
return err
Expand Down
15 changes: 14 additions & 1 deletion pkg/fixtures/validatetemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,20 @@ func ValidateContentAgainstFixture(generatedContent []byte, fixturePath string)
}

if normalizeWhitespace(fixtureContent) != normalizeWhitespace(generatedContent) {
return errors.New("generated content does not match fixture")
genWords := strings.Split(normalizeWhitespace(generatedContent), " ")
fixtureWords := strings.Split(normalizeWhitespace(fixtureContent), " ")
differingWords := []string{}
for i, word := range genWords {
if word != fixtureWords[i] {
differingWords = append(differingWords, fmt.Sprintf("'%s' != '%s'", word, fixtureWords[i]))
if len(differingWords) == 1 {
fmt.Println("Generated Word | Fixture Word")
}
fmt.Printf("'%s' != '%s'\n", word, fixtureWords[i])
}
}

return errors.New(fmt.Sprintf("generated content does not match fixture: %s", strings.Join(differingWords, ", ")))
}

return nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# This workflow will build and push an application to a Azure Kubernetes Service (AKS) cluster when you push your code
#
# This workflow assumes you have already created the target AKS cluster and have created an Azure Container Registry (ACR)
# The ACR should be attached to the AKS cluster
# For instructions see:
# - https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal
# - https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal
# - https://learn.microsoft.com/en-us/azure/aks/cluster-container-registry-integration?tabs=azure-cli#configure-acr-integration-for-existing-aks-clusters
# - https://github.com/Azure/aks-create-action
#
# To configure this workflow:
#
# 1. Set the following secrets in your repository (instructions for getting these
# https://docs.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-cli%2Clinux)):
# - AZURE_CLIENT_ID
# - AZURE_TENANT_ID
# - AZURE_SUBSCRIPTION_ID
#
# 2. Set the following environment variables (or replace the values below):
# - ACR_RESOURCE_GROUP (resource group of your ACR)
# - AZURE_CONTAINER_REGISTRY (name of your container registry / ACR)
# - CONTAINER_NAME (name of the container image you would like to push up to your ACR)
# - CLUSTER_RESOURCE_GROUP (where your cluster is deployed)
# - CLUSTER_NAME (name of your AKS cluster)
# - DOCKER_FILE (path to your Dockerfile)
# - BUILD_CONTEXT_PATH (path to the context of your Dockerfile)
# - CHART_PATH (path to your helm chart)
# - CHART_OVERRIDE_PATH (path to your helm chart with override values)
# - CHART_OVERRIDES (override values for your helm chart)
# - NAMESPACE (namespace to deploy your application)
#
# For more information on GitHub Actions for Azure, refer to https://github.com/Azure/Actions
# For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples
# For more options with the actions used below please refer to https://github.com/Azure/login

name: testWorkflow

on:
push:
branches: [testBranch]
workflow_dispatch:

env:
ACR_RESOURCE_GROUP: testAcrRG
AZURE_CONTAINER_REGISTRY: testAcr
CONTAINER_NAME: testContainer
CLUSTER_RESOURCE_GROUP: testClusterRG
CLUSTER_NAME: testCluster
DOCKER_FILE: ./Dockerfile
BUILD_CONTEXT_PATH: test
CHART_PATH: testPath
CHART_OVERRIDE_PATH: testOverridePath
CHART_OVERRIDES: replicas:2
NAMESPACE: default

jobs:
buildImage:
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
steps:
# Checks out the repository this file is in
- uses: actions/checkout@v3

# Logs in with your Azure credentials
- name: Azure login
uses: azure/login@v1.4.6
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

# Builds and pushes an image up to your Azure Container Registry
- name: Build and push image to ACR
run: |
az acr build --image ${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }}
deploy:
permissions:
actions: read
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [buildImage]
steps:
# Checks out the repository this file is in
- uses: actions/checkout@v3

# Logs in with your Azure credentials
- name: Azure login
uses: azure/login@v1.4.6
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

# Use kubelogin to configure your kubeconfig for Azure auth
- name: Set up kubelogin for non-interactive login
uses: azure/use-kubelogin@v1
with:
kubelogin-version: "v0.0.25"

# Retrieves your Azure Kubernetes Service cluster's kubeconfig file
- name: Get K8s context
uses: azure/aks-set-context@v3
with:
resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }}
cluster-name: ${{ env.CLUSTER_NAME }}
admin: "false"
use-kubelogin: "true"

# Checks if the AKS cluster is private
- name: Is private cluster
id: isPrivate
run: |
result=$(az aks show --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.CLUSTER_NAME }} --query "apiServerAccessProfile.enablePrivateCluster")
echo "PRIVATE_CLUSTER=$result" >> "$GITHUB_OUTPUT"

# Deploys application
- name: Deploy application on private cluster
if: steps.isPrivate.outputs.PRIVATE_CLUSTER == 'true'
run: |
command_id=$(az aks command invoke --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.CLUSTER_NAME }} --command "helm upgrade --wait -i -f ${{ env.CHART_OVERRIDE_PATH }} --set ${{ env.CHART_OVERRIDES }} --set image.tag=${{ github.sha }} automated-deployment ${{ env.CHART_PATH }} --namespace ${{ env.NAMESPACE }} --create-namespace --timeout 240s" --file . --query id -o tsv)
result=$(az aks command result --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.CLUSTER_NAME }} --command-id $command_id)
echo "Helm upgrade result: $result"
exitCode=$(az aks command result --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.CLUSTER_NAME }} --command-id $command_id --query exitCode -o tsv)

if [ $exitCode -ne 0 ]; then
exit $exitCode
fi

- name: Deploy application on public cluster
if: steps.isPrivate.outputs.PRIVATE_CLUSTER != 'true'
run: helm upgrade --wait -i -f ${{ env.CHART_OVERRIDE_PATH }} --set ${{ env.CHART_OVERRIDES }} --set image.tag=${{ github.sha }} automated-deployment ${{ env.CHART_PATH }} --namespace ${{ env.NAMESPACE }} --create-namespace
Loading