Skip to content

Instantly share code, notes, and snippets.

@xeviknal
Created February 26, 2019 13:29
Show Gist options
  • Save xeviknal/12afd27e27546a5fe8ef261dcd32d4fa to your computer and use it in GitHub Desktop.
Save xeviknal/12afd27e27546a5fe8ef261dcd32d4fa to your computer and use it in GitHub Desktop.
Shall we move some logic to "models"?
package models
import (
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/kiali/kiali/config"
"github.com/kiali/kiali/kubernetes"
)
// DestinationRules destinationRules
//
// This is used for returning an array of DestinationRules
//
// swagger:model destinationRules
// An array of destinationRule
// swagger:allOf
type DestinationRules struct {
Permissions ResourcePermissions `json:"permissions"`
Items []DestinationRule `json:"items"`
}
// DestinationRule destinationRule
//
// This is used for returning a DestinationRule
//
// swagger:model destinationRule
type DestinationRule struct {
Metadata meta_v1.ObjectMeta `json:"metadata"`
Spec struct {
Host interface{} `json:"host"`
TrafficPolicy interface{} `json:"trafficPolicy"`
Subsets interface{} `json:"subsets"`
} `json:"spec"`
}
func (dRules *DestinationRules) Parse(destinationRules []kubernetes.IstioObject) {
dRules.Items = []DestinationRule{}
for _, dr := range destinationRules {
destinationRule := DestinationRule{}
destinationRule.Parse(dr)
dRules.Items = append(dRules.Items, destinationRule)
}
}
func (dRule *DestinationRule) Parse(destinationRule kubernetes.IstioObject) {
dRule.Metadata = destinationRule.GetObjectMeta()
dRule.Spec.Host = destinationRule.GetSpec()["host"]
dRule.Spec.TrafficPolicy = destinationRule.GetSpec()["trafficPolicy"]
dRule.Spec.Subsets = destinationRule.GetSpec()["subsets"]
}
func (dRule *DestinationRule) HasMeshWideMTLSEnabled() bool {
// Following the suggested procedure to enable mesh-wide mTLS, host might be '*.local':
// https://istio.io/docs/tasks/security/authn-policy/#globally-enabling-istio-mutual-tls
if dRule.Spec.Host == nil || dRule.Spec.Host != "*.local" {
return false
}
if dRule.Spec.TrafficPolicy != nil {
if trafficCasted, ok := dRule.Spec.TrafficPolicy.(map[string]interface{}); ok {
if tls, found := trafficCasted["tls"]; found {
if tlsCasted, ok := tls.(map[string]interface{}); ok {
if mode, found := tlsCasted["mode"]; found {
if modeCasted, ok := mode.(string); ok {
if modeCasted == "ISTIO_MUTUAL" {
return true
}
}
}
}
}
}
}
return false
}
package models
import (
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/kiali/kiali/kubernetes"
)
type MeshPolicies []MeshPolicy
type MeshPolicy struct {
Metadata meta_v1.ObjectMeta `json:"metadata"`
Spec struct {
Targets interface{} `json:"targets"`
Peers interface{} `json:"peers"`
PeerIsOptional interface{} `json:"peerIsOptional"`
Origins interface{} `json:"origins"`
OriginIsOptional interface{} `json:"originIsOptional"`
PrincipalBinding interface{} `json:"principalBinding"`
} `json:"spec"`
}
func (mps *MeshPolicies) Parse(meshPolicies []kubernetes.IstioObject) {
for _, qs := range meshPolicies {
meshPolicy := MeshPolicy{}
meshPolicy.Parse(qs)
*mps = append(*mps, meshPolicy)
}
}
func (mp *MeshPolicy) Parse(meshPolicy kubernetes.IstioObject) {
mp.Metadata = meshPolicy.GetObjectMeta()
mp.Spec.Targets = meshPolicy.GetSpec()["targets"]
mp.Spec.Peers = meshPolicy.GetSpec()["peers"]
mp.Spec.PeerIsOptional = meshPolicy.GetSpec()["peersIsOptional"]
mp.Spec.Origins = meshPolicy.GetSpec()["origins"]
mp.Spec.OriginIsOptional = meshPolicy.GetSpec()["originIsOptinal"]
mp.Spec.PrincipalBinding = meshPolicy.GetSpec()["principalBinding"]
}
func (mp MeshPolicy) HasMTLSEnabled() bool {
// It is mandatory to have default as a name
if mp.Metadata.Name != "default" {
return false
}
// It is no globally enabled when has targets
specificTarget := mp.Spec.Targets != nil && len(mp.Spec.Targets.([]interface{})) > 0
if specificTarget {
return false
}
// It is globally enabled when a peer has mtls enabled
if mp.Spec.Peers == nil {
return false
}
for _, peer := range mp.Spec.Peers.([]interface{}) {
peerMap := peer.(map[string]interface{})
if mtls, present := peerMap["mtls"]; present {
if mtlsMap, ok := mtls.(map[string]interface{}); ok {
// mTLS enabled in case there is an empty mode or mode is STRICT
if mode, found := mtlsMap["mode"]; !found || mode == "STRICT" {
return true
}
} else {
// mTLS enabled in case mtls object is empty
return true
}
}
}
return false
}
package meshpolicies
import (
"github.com/kiali/kiali/kubernetes"
"github.com/kiali/kiali/models"
)
const MeshPolicyCheckerType = "meshpolicy"
type MtlsChecker struct {
MeshPolicy kubernetes.IstioObject
MTLSDetails kubernetes.MTLSDetails
}
func (t MtlsChecker) Check() models.IstioValidations {
validations := models.IstioValidations{}
meshPolicy := models.MeshPolicy{}
meshPolicy.Parse(t.MeshPolicy)
// if MeshPolicy doesn't enables mTLS, stop validation with any check.
if !meshPolicy.HasMTLSEnabled() {
return validations
}
// otherwise, check among Destination Rules for a rule enabling mTLS mesh-wide.
for _, dr := range t.MTLSDetails.DestinationRules {
destinationRule := models.DestinationRule{}
destinationRule.Parse(dr)
if destinationRule.HasMeshWideMTLSEnabled() {
return validations
}
}
check := models.Build("meshpolicies.mtls.destinationrulemissing", "")
key := models.BuildKey(MeshPolicyCheckerType, meshPolicy.Metadata.Name)
validations[key] = &models.IstioValidation{
Name: t.MeshPolicy.GetObjectMeta().Name,
ObjectType: MeshPolicyCheckerType,
Valid: false,
Checks: []*models.IstioCheck{
&check,
},
}
return validations
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment