Skip to content

Commit

Permalink
Migrate to managed identities (#116)
Browse files Browse the repository at this point in the history
* update schema and readme for new managed identities

* Use AzureDb driver for workload identity auth

* Added version log

* Added version log

* use correct image

* Add support for deployment annotations, pod labels and service account annotations
  • Loading branch information
Richard87 authored Mar 19, 2024
1 parent c59a5bd commit fe89b2a
Show file tree
Hide file tree
Showing 14 changed files with 66 additions and 45 deletions.
14 changes: 2 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
DOCKER_REGISTRY=radixdev.azurecr.io
VERSION=latest
IMAGE_NAME=$(DOCKER_REGISTRY)/radix-cost-allocation:$(VERSION)
DB_PASSWORD=a_password

# to deploy run: "make deploy DB_PASSWORD=<sql_db_password>"

# to deploy db: "make deploy-azure DB_PASSWORD=<sql_db_password>"
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
IMAGE_NAME=$(DOCKER_REGISTRY)/radix-cost-allocation:$(BRANCH)-$(VERSION)

build:
docker build -t $(IMAGE_NAME) .
Expand All @@ -14,12 +10,6 @@ push:
az acr login -n $(DOCKER_REGISTRY)
docker push $(IMAGE_NAME)

deploy:
helm upgrade --install radix-cost-allocation ./charts --set db.password=$(DB_PASSWORD)

deploy-azure:
az deployment group create --resource-group common --template-file ./azure-infrastructure/azuredeploy.json --parameters sqlAdministratorLoginPassword=$(DB_PASSWORD)

.PHONY: test
test:
go test -cover `go list ./...`
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ We use arm template and github action to create azure resources
The SQL Server database and objects are deployed on push to master and release branch.
All SQL scripts on azure-infrastructure must be idempotent.

Note: The Github Workflow is not allowed to create new external users, so you must run it locally. Se more here: https://github.com/equinor/radix-vulnerability-scanner/issues/54

## Deploy to cluster

Installation on cluster is handled by flux through [flux repo](https://github.com/equinor/radix-flux). Before being installed, it requires that there exist a namespace called `radix-cost-allocation`. In that namespace there must be a secret called `cost-db-secret` that contains the database password. This is handled through the setup script in [radix-platform](https://github.com/equinor/radix-platform)
Expand Down Expand Up @@ -67,4 +69,4 @@ Create a copy of .env.template and name it .env. Set variables to allow local de

---------

[Security notification](./SECURITY.md)
[Security notification](./SECURITY.md)
15 changes: 14 additions & 1 deletion azure-infrastructure/createSchema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,17 @@ BEGIN
CREATE ROLE datareader
END

GRANT SELECT ON SCHEMA::cost TO datareader
GRANT SELECT ON SCHEMA::cost TO datareader


IF NOT EXISTS(SELECT 1 FROM sys.database_principals WHERE name = 'radix-id-vulnerability-scan-writer-$(RADIX_ZONE)')
BEGIN
CREATE USER [radix-id-vulnerability-scan-writer-$(RADIX_ZONE)] FROM EXTERNAL PROVIDER;
END
ALTER ROLE datawriter ADD MEMBER [radix-id-vulnerability-scan-writer-$(RADIX_ZONE)]

IF NOT EXISTS(SELECT 1 FROM sys.database_principals WHERE name = 'radix-id-vulnerability-scan-reader-$(RADIX_ZONE)')
BEGIN
CREATE USER [radix-id-vulnerability-scan-reader-$(RADIX_ZONE)] FROM EXTERNAL PROVIDER;
END
ALTER ROLE datareader ADD MEMBER [radix-id-vulnerability-scan-reader-$(RADIX_ZONE)]
4 changes: 2 additions & 2 deletions charts/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: v1
appVersion: 0.3.4
version: 0.6.3
appVersion: 1.0.0
version: 1.0.0
description: Pull cost data from containers and push to sql server
name: radix-cost-allocation
12 changes: 7 additions & 5 deletions charts/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ metadata:
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "cost-allocation.labels" . | nindent 4 }}
{{- with .Values.deploymentAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
replicas: 1
selector:
Expand All @@ -14,6 +18,9 @@ spec:
metadata:
labels:
{{- include "cost-allocation.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
serviceAccount: {{ include "cost-allocation.serviceAccountName" . }}
securityContext:
Expand All @@ -34,8 +41,6 @@ spec:
value: {{ .Values.schedule.nodeSync | quote }}
- name: SCHEDULE_POD_SYNC
value: {{ .Values.schedule.podSync | quote }}
- name: SQL_USER
value: {{ .Values.db.user }}
- name: SQL_DATABASE
value: {{ .Values.db.database }}
- name: SQL_SERVER
Expand All @@ -46,9 +51,6 @@ spec:
value: {{ .Values.logLevel }}
- name: APP_NAME_EXCLUDE_LIST
value: {{ .Values.appNameExcludeList }}
envFrom:
- secretRef:
name: {{ .Values.secret.name }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
securityContext:
Expand Down
8 changes: 0 additions & 8 deletions charts/templates/secret.yaml

This file was deleted.

4 changes: 4 additions & 0 deletions charts/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ metadata:
namespace: {{ .Release.Namespace }}
labels:
{{- include "cost-allocation.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
9 changes: 7 additions & 2 deletions charts/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ image:
secret:
name: sql-credential

# Annotations to add to the Deployment
deploymentAnnotations: {}
# Extra pod labels
podLabels: {}

serviceAccount:
# The name of the service account to use.
# If not set, a name is generated using the fullname template
name: ""
# Annotations to add to the service account
annotations: {}

db:
user: radixwriter
database: sqldb-radix-cost-allocation
server: sql-radix-cost-allocation-dev.database.windows.net
password: password
port: "1433"
queryTimeout: "30"

Expand Down
6 changes: 2 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ type AppConfig struct {
type SQLConfig struct {
Server string
Database string `envconfig:"default=sqldb-radix-cost-allocation"`
User string
Password string
Port int `envconfig:"default=1433"`
QueryTimeout int `envconfig:"default=30"`
Port int `envconfig:"default=1433"`
QueryTimeout int `envconfig:"default=30"`
}

// CronSchedule defines cron schedules for jobs
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ require (

require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/equinor/radix-common v1.7.1 // indirect
Expand All @@ -29,6 +33,7 @@ require (
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand All @@ -39,12 +44,14 @@ require (
github.com/imdario/mergo v0.3.13 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY=
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand All @@ -11,6 +15,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
Expand All @@ -36,6 +41,7 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
Expand Down Expand Up @@ -86,6 +92,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
Expand All @@ -111,6 +118,7 @@ github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
5 changes: 4 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"os"
"os/signal"
"runtime/debug"
"syscall"
"time"

Expand Down Expand Up @@ -31,6 +32,9 @@ func main() {
log.Fatal().Err(err).Msg("Failed to initialize logger")
}

info, _ := debug.ReadBuildInfo()
log.Info().Str("version", info.Main.Version).Msg("Starting")

go func() {
if err := run.InitAndStartCollector(ctx, appConfig.SQL, appConfig.Schedule, appConfig.AppNameExcludeList); err != nil {
log.Fatal().Msg(err.Error())
Expand All @@ -39,7 +43,6 @@ func main() {

<-ctx.Done()
}

func setupLogger(ctx context.Context, logLevel string, prettyPrint bool) (context.Context, error) {
zerolog.DurationFieldUnit = time.Millisecond
level, err := zerolog.ParseLevel(logLevel)
Expand Down
13 changes: 5 additions & 8 deletions pkg/utils/mssql/mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import (
"database/sql"
"fmt"

mssql "github.com/microsoft/go-mssqldb"
"github.com/microsoft/go-mssqldb/azuread"
)

// OpenSQLServer opens a new connection to a SQL Server
func OpenSQLServer(server, database, userID, password string, port int) (*sql.DB, error) {
c, err := mssql.NewConnector(
GetSQLServerDsn(server, database, userID, password, port),
)
func OpenSQLServer(server, database string, port int) (*sql.DB, error) {
c, err := azuread.NewConnector(GetSQLServerDsn(server, database, port))
if err != nil {
return nil, err
}
Expand All @@ -20,9 +18,8 @@ func OpenSQLServer(server, database, userID, password string, port int) (*sql.DB
}

// GetSQLServerDsn builds a SQL Server specific DSN
func GetSQLServerDsn(server, database, userID, password string, port int) string {
dsn := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s",
server, userID, password, database)
func GetSQLServerDsn(server, database string, port int) string {
dsn := fmt.Sprintf("server=%s;database=%s;fedauth=ActiveDirectoryDefault", server, database)

if port > 0 {
dsn = fmt.Sprintf("%s;port=%d", dsn, port)
Expand Down
2 changes: 1 addition & 1 deletion run/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func InitAndStartCollector(ctx context.Context, sqlConfig config.SQLConfig, cron
return errors.WithMessage(err, "failed to get kubernetes clients")
}

db, err := mssqlUtils.OpenSQLServer(sqlConfig.Server, sqlConfig.Database, sqlConfig.User, sqlConfig.Password, sqlConfig.Port)
db, err := mssqlUtils.OpenSQLServer(sqlConfig.Server, sqlConfig.Database, sqlConfig.Port)
if err != nil {
return errors.WithMessage(err, "failed to init database driver")
}
Expand Down

0 comments on commit fe89b2a

Please sign in to comment.