Skip to content

Commit

Permalink
Merge pull request #161 from utkarsh-pro/utkarsh-pro/feature/addons-s…
Browse files Browse the repository at this point in the history
…upport

Add "Check Configuration" and addons support to istio adapter
  • Loading branch information
leecalcote authored Dec 7, 2020
2 parents 1c6d48d + 836fa23 commit a7ec6c7
Show file tree
Hide file tree
Showing 9 changed files with 412 additions and 69 deletions.
47 changes: 25 additions & 22 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
FROM golang:1.13.1 as bd
RUN adduser --disabled-login --gecos "" appuser
WORKDIR /github.com/layer5io/meshery-istio
ADD . .
RUN GOPROXY=direct GOSUMDB=off go build -ldflags="-w -s" -a -o /meshery-istio .
RUN find . -name "*.go" -type f -delete; mv istio /
RUN wget -O /istio.tar.gz https://github.com/istio/istio/releases/download/1.5.1/istio-1.5.1-linux.tar.gz
FROM golang:1.13 as builder

FROM alpine
RUN apk --update add ca-certificates curl
RUN mkdir /lib64 && \
ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 && \
mkdir -p /root/.kube && \
mkdir -p /tmp/istio
COPY --from=bd /meshery-istio /app/
COPY --from=bd /istio /app/istio
COPY --from=bd /istio.tar.gz /app/
COPY --from=bd //github.com/layer5io/meshery-istio/scripts /app/scripts/.
COPY --from=bd /etc/passwd /etc/passwd
ENV ISTIO_VERSION=1.7.3
# USER appuser
WORKDIR /app
CMD ./meshery-istio
ARG ENVIRONMENT="development"
ARG CONFIG_PROVIDER="viper"
WORKDIR /build
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download
# Copy the go source
COPY main.go main.go
COPY internal/ internal/
COPY istio/ istio/
# Build
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -ldflags="-w -s -X main.environment=$ENVIRONMENT -X main.provider=$CONFIG_PROVIDER" -a -o meshery-istio main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/base
WORKDIR /
ENV DISTRO="debian"
ENV GOARCH="amd64"
COPY --from=builder /build/meshery-istio .
ENTRYPOINT ["/meshery-istio"]
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ go 1.13
replace github.com/kudobuilder/kuttl => github.com/layer5io/kuttl v0.4.1-0.20200723152044-916f10574334

require (
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/aspenmesh/istio-vet v0.0.0-20200806222806-9c8e9a962b9f
github.com/layer5io/meshery-adapter-library v0.1.7
github.com/layer5io/meshkit v0.1.28
github.com/onsi/ginkgo v1.13.0 // indirect
golang.org/x/net v0.0.0-20200927032502-5d4f70055728 // indirect
google.golang.org/grpc v1.32.0 // indirect
k8s.io/apimachinery v0.19.4
istio.io/client-go v1.8.0
k8s.io/apimachinery v0.18.12
k8s.io/client-go v0.18.12
)
52 changes: 33 additions & 19 deletions go.sum

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ const (
// Constants to use in log statements
IstioOperation = "istio"
LabelNamespace = "label-namespace"

// Istio vet operation
IstioVetOpertation = "istio-vet"

// Addons that the adapter supports
PrometheusAddon = "prometheus-addon"
GrafanaAddon = "grafana-addon"
KialiAddon = "kiali-addon"
JaegerAddon = "jaeger-addon"
ZipkinAddon = "zipkin-addon"
)

var (
Expand Down
30 changes: 30 additions & 0 deletions internal/config/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,35 @@ func getOperations(dev adapter.Operations) adapter.Operations {
Description: "Label Namespace for Automatic Sidecar Injection",
}

dev[PrometheusAddon] = &adapter.Operation{
Type: int32(meshes.OpCategory_CONFIGURE),
Description: "Prometheus Monitoring",
}

dev[GrafanaAddon] = &adapter.Operation{
Type: int32(meshes.OpCategory_CONFIGURE),
Description: "Grafana Dashboard",
}

dev[KialiAddon] = &adapter.Operation{
Type: int32(meshes.OpCategory_CONFIGURE),
Description: "Kiali Dashboard",
}

dev[JaegerAddon] = &adapter.Operation{
Type: int32(meshes.OpCategory_CONFIGURE),
Description: "Jaeger Dashboard",
}

dev[ZipkinAddon] = &adapter.Operation{
Type: int32(meshes.OpCategory_CONFIGURE),
Description: "Zipkin Dashboard",
}

dev[IstioVetOpertation] = &adapter.Operation{
Type: int32(meshes.OpCategory_VALIDATE),
Description: "Analyze Running Configuration",
}

return dev
}
58 changes: 58 additions & 0 deletions istio/addons.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package istio

import (
"fmt"
"strings"

"github.com/layer5io/meshery-adapter-library/adapter"
"github.com/layer5io/meshery-adapter-library/status"
"github.com/layer5io/meshery-istio/internal/config"
)

// AddonTemplate is as a container for addon templates
var AddonTemplate = map[string]adapter.Template{
config.PrometheusAddon: "https://raw.githubusercontent.com/istio/istio/master/samples/addons/prometheus.yaml",
config.GrafanaAddon: "https://raw.githubusercontent.com/istio/istio/master/samples/addons/grafana.yaml",
config.KialiAddon: "https://raw.githubusercontent.com/istio/istio/master/samples/addons/kiali.yaml",
config.JaegerAddon: "https://raw.githubusercontent.com/istio/istio/master/samples/addons/jaeger.yaml",
config.ZipkinAddon: "https://raw.githubusercontent.com/istio/istio/master/samples/addons/extras/zipkin.yaml",
}

// InstallAddon installs the specified addon in the given namespace
func (istio *Istio) InstallAddon(namespace string, del bool, addon string) (string, error) {
// Some of addons will have a different install process
// than these template based addons
switch addon {
case config.PrometheusAddon, config.GrafanaAddon, config.KialiAddon, config.JaegerAddon, config.ZipkinAddon:
return istio.installAddonFromTemplate(namespace, del, AddonTemplate[addon])
}

return "", ErrAddonInvalidConfig(fmt.Errorf("%s is invalid addon", addon))
}

// installAddonFromTemplate installs/uninstalls an addon in the given namespace
//
// the template defines the manifest's link/location which needs to be used to
// install the addon
func (istio *Istio) installAddonFromTemplate(namespace string, del bool, template adapter.Template) (string, error) {
istio.Log.Info(fmt.Sprintf("Requested action is delete: %v", del))
st := status.Installing

if del {
st = status.Removing
}

contents, err := readFileSource(string(template))
if err != nil {
return st, ErrAddonFromTemplate(err)
}

err = istio.applyManifest([]byte(contents), del, namespace)
// Specifically choosing to ignore kiali dashboard's error.
// Referring to: https://github.com/kiali/kiali/issues/3112
if err != nil && !strings.Contains(err.Error(), "no matches for kind \"MonitoringDashboard\" in version \"monitoring.kiali.io/v1alpha1\"") {
return st, ErrAddonFromTemplate(err)
}

return status.Installed, nil
}
99 changes: 73 additions & 26 deletions istio/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,62 @@ import (
)

var (
// Errror code for failed service mesh installation
ErrInstallIstioCode = "istio_test_code"
ErrUnzipFileCode = "istio_test_code"
ErrTarXZFCode = "istio_test_code"
ErrMeshConfigCode = "istio_test_code"
ErrFetchManifestCode = "istio_test_code"
ErrDownloadBinaryCode = "istio_test_code"
ErrInstallBinaryCode = "istio_test_code"
ErrClientConfigCode = "istio_test_code"
ErrClientSetCode = "istio_test_code"
ErrStreamEventCode = "istio_test_code"
ErrSampleAppCode = "istio_test_code"
// Error code for failed service mesh installation

// ErrInstallIstioCode represents the errors which are generated
// during istio service mesh install process
ErrInstallIstioCode = "istio_test_code"

// ErrUnzipFileCode represents the errors which are generated
// during unzip process
ErrUnzipFileCode = "istio_test_code"

// ErrTarXZFCode represents the errors which are generated
// during decompressing and extracting tar.gz file
ErrTarXZFCode = "istio_test_code"

// ErrMeshConfigCode represents the errors which are generated
// when an invalid mesh config is found
ErrMeshConfigCode = "istio_test_code"

// ErrFetchManifestCode represents the errors which are generated
// during fetch manifest process
ErrFetchManifestCode = "istio_test_code"

// ErrDownloadBinaryCode represents the errors which are generated
// during binary download process
ErrDownloadBinaryCode = "istio_test_code"

// ErrInstallBinaryCode represents the errors which are generated
// during binary installation process
ErrInstallBinaryCode = "istio_test_code"

// ErrSampleAppCode represents the errors which are generated
// duing sample app installation
ErrSampleAppCode = "istio_test_code"

// ErrCustomOperationCode represents the errors which are generated
// when an invalid addon operation is requested
ErrCustomOperationCode = "istio_test_code"

// ErrAddonFromTemplateCode represents the errors which are generated
// during addon deployment process
ErrAddonFromTemplateCode = "istio_test_code"

// ErrAddonInvalidConfigCode represents the errors which are generated
// when an invalid addon operation is requested
ErrAddonInvalidConfigCode = "istio_test_code"

// ErrCreatingIstioClientCode represents the errors which are generated
// during creating istio client process
ErrCreatingIstioClientCode = "istio_test_code"

// ErrIstioVetSyncCode represents the errors which are generated
// during istio-vet sync process
ErrIstioVetSyncCode = "istio_test_code"

// ErrOpInvalid represents the errors which are generated
// when an invalid operation is requested
ErrOpInvalid = errors.NewDefault(errors.ErrOpInvalid, "Invalid operation")
)

Expand Down Expand Up @@ -60,27 +102,32 @@ func ErrInstallBinary(err error) error {
return errors.NewDefault(ErrInstallBinaryCode, fmt.Sprintf("Error installing istio binary: %s", err.Error()))
}

// ErrClientConfig is the error for setting client config
func ErrClientConfig(err error) error {
return errors.NewDefault(ErrClientConfigCode, fmt.Sprintf("Error setting client config: %s", err.Error()))
}

// ErrClientSet is the error for setting clientset
func ErrClientSet(err error) error {
return errors.NewDefault(ErrClientSetCode, fmt.Sprintf("Error setting clientset: %s", err.Error()))
// ErrSampleApp is the error for streaming event
func ErrSampleApp(err error) error {
return errors.NewDefault(ErrSampleAppCode, fmt.Sprintf("Error with sample app operation: %s", err.Error()))
}

// ErrStreamEvent is the error for streaming event
func ErrStreamEvent(err error) error {
return errors.NewDefault(ErrStreamEventCode, fmt.Sprintf("Error streaming event: %s", err.Error()))
// ErrAddonFromTemplate is the error for streaming event
func ErrAddonFromTemplate(err error) error {
return errors.NewDefault(ErrAddonFromTemplateCode, fmt.Sprintf("Error with addon install operation: %s", err.Error()))
}

// ErrSampleApp is the error for streaming event
func ErrSampleApp(err error) error {
return errors.NewDefault(ErrSampleAppCode, fmt.Sprintf("Error with sample app operation: %s", err.Error()))
// ErrAddonInvalidConfig is the error for streaming event
func ErrAddonInvalidConfig(err error) error {
return errors.NewDefault(ErrAddonInvalidConfigCode, fmt.Sprintf("Invalid addon: %s", err.Error()))
}

// ErrCustomOperation is the error for streaming event
func ErrCustomOperation(err error) error {
return errors.NewDefault(ErrCustomOperationCode, fmt.Sprintf("Error with custom operation: %s", err.Error()))
}

// ErrCreatingIstioClient is the error for streaming event
func ErrCreatingIstioClient(err error) error {
return errors.NewDefault(ErrCreatingIstioClientCode, fmt.Sprintf("Unable to create a new istio client %s", err.Error()))
}

// ErrIstioVetSync is the error for streaming event
func ErrIstioVetSync(err error) error {
return errors.NewDefault(ErrIstioVetSyncCode, fmt.Sprintf("Failed to sync %s", err.Error()))
}
39 changes: 39 additions & 0 deletions istio/istio.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import (
"github.com/layer5io/meshery-adapter-library/adapter"
"github.com/layer5io/meshery-adapter-library/common"
adapterconfig "github.com/layer5io/meshery-adapter-library/config"
"github.com/layer5io/meshery-adapter-library/meshes"
"github.com/layer5io/meshery-adapter-library/status"
internalconfig "github.com/layer5io/meshery-istio/internal/config"
"github.com/layer5io/meshkit/logger"
)

// Istio represents the istio adapter and embeds adapter.Adapter
type Istio struct {
adapter.Adapter // Type Embedded
}
Expand Down Expand Up @@ -113,6 +115,43 @@ func (istio *Istio) ApplyOperation(ctx context.Context, opReq adapter.OperationR
ee.Details = ""
hh.StreamInfo(e)
}(istio, e)
case internalconfig.PrometheusAddon, internalconfig.GrafanaAddon, internalconfig.KialiAddon, internalconfig.JaegerAddon, internalconfig.ZipkinAddon:
go func(hh *Istio, ee *adapter.Event) {
_, err := hh.InstallAddon(opReq.Namespace, opReq.IsDeleteOperation, opReq.OperationName)
operation := "install"
if opReq.IsDeleteOperation {
operation = "uninstall"
}

if err != nil {
e.Summary = fmt.Sprintf("Error while %sing %s", operation, opReq.OperationName)
e.Details = err.Error()
hh.StreamErr(e, err)
return
}
ee.Summary = fmt.Sprintf("Succesfully %sed %s", operation, opReq.OperationName)
ee.Details = fmt.Sprintf("Succesfully %sed %s from the %s namespace", operation, opReq.OperationName, opReq.Namespace)
hh.StreamInfo(e)
}(istio, e)
case internalconfig.IstioVetOpertation:
go func(hh *Istio, ee *adapter.Event) {
responseChan := make(chan *adapter.Event, 1)

go hh.RunVet(responseChan)

for msg := range responseChan {
switch msg.EType {
case int32(meshes.EventType_ERROR):
istio.StreamErr(msg, fmt.Errorf(msg.Details))
case int32(meshes.EventType_WARN):
istio.StreamWarn(msg, fmt.Errorf(msg.Details))
default:
istio.StreamInfo(msg)
}
}

istio.Log.Info("Done")
}(istio, e)
default:
istio.StreamErr(e, ErrOpInvalid)
}
Expand Down
Loading

0 comments on commit a7ec6c7

Please sign in to comment.