...

Source file src/edge-infra.dev/pkg/sds/ien/topology/info.go

Documentation: edge-infra.dev/pkg/sds/ien/topology

     1  package topology
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strconv"
     7  
     8  	v1 "k8s.io/api/core/v1"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	"k8s.io/apimachinery/pkg/types"
    11  	"sigs.k8s.io/controller-runtime/pkg/client"
    12  	"sigs.k8s.io/controller-runtime/pkg/predicate"
    13  
    14  	"edge-infra.dev/pkg/edge/api/graph/model"
    15  	linkerd "edge-infra.dev/pkg/edge/linkerd"
    16  )
    17  
    18  const (
    19  	// name of topology info ConfigMap
    20  	Name string = "topology-info"
    21  	// namespace for topology info ConfigMap
    22  	Namespace string = "kube-public"
    23  
    24  	downlinkRateKey                   string = "downlink_rate_limit"
    25  	uplinkRateKey                     string = "uplink_rate_limit"
    26  	gatewayEnabledKey                 string = "egress_gateway_enabled"
    27  	gatewayRateLimitEnabledKey        string = "gateway_rate_limiting_enabled"
    28  	thickPosKey                       string = "thick_pos"
    29  	linkerdIdentityCertDurationKey    string = "linkerd_identity_issuer_cert_duration"
    30  	linkerdIdentityCertRenewBeforeKey string = "linkerd_identity_issuer_cert_renew_before"
    31  )
    32  
    33  // Deprecated: linkerd identity cert fields deprecated in https://github.com/ncrvoyix-swt-retail/edge-infra/pull/10353
    34  var (
    35  	// InvalidCertificateDuationErr is thrown when the certificate duration is a a non-positive integer
    36  	ErrInvalidCertificateDurationOrRenewBefore = errors.New("linkerd identity: certificate duration and renew before must be positive")
    37  	// InvalidCertificateRenewBeforeErr is thrown when the certificate renew before is a non-positive integer
    38  	ErrInvalidCertificateRenewBefore = errors.New("linkerd identity: duration must be greater than the certificate renew before")
    39  )
    40  
    41  // Info contains the fields defined in the topology-info ConfigMap.
    42  type Info struct {
    43  	// Download rate limit in bits per second
    44  	DownlinkRateLimit uint64
    45  	// Upload rate limit in bits per second
    46  	UplinkRateLimit uint64
    47  	// Defines if egress gateway is enabled
    48  	EgressGatewayEnabled bool
    49  	// Defines if rate limiting is enabled
    50  	GatewayRateLimitingEnabled bool
    51  	// Defines the store clusters topology.
    52  	// If set to true the store is configured to thick topology.
    53  	// If set to false the store is configured to thin topology.
    54  	ThickPOS bool
    55  	// Linkerd identity certificate duration defines the maximum
    56  	// duration (hours) a store cluster can be in lan-outage for.
    57  	LinkerdIdentityCertDuration int
    58  	// Linkerd identity certificate renew before defines the
    59  	// how many hours before the certificate duration certificate
    60  	// renewal can be attempted.
    61  	LinkerdIdentityCertRenewBefore int
    62  }
    63  
    64  // Instantiates a new topology info with set defaults
    65  func New() *Info {
    66  	return &Info{
    67  		DownlinkRateLimit:              defaultRateLimit,
    68  		UplinkRateLimit:                defaultRateLimit,
    69  		EgressGatewayEnabled:           false,
    70  		GatewayRateLimitingEnabled:     false,
    71  		ThickPOS:                       false,
    72  		LinkerdIdentityCertDuration:    int(linkerd.DefaultThinPosIdentityIssuerCertificateDurationHours),
    73  		LinkerdIdentityCertRenewBefore: int(linkerd.DefaultThinPosIdentityIssuerCertificateRenewBeforeHours),
    74  	}
    75  }
    76  
    77  // FromClient constructs the Info object from a kubernetes client
    78  func (i *Info) FromClient(ctx context.Context, c client.Client) (*Info, error) {
    79  	cm := &v1.ConfigMap{}
    80  	if err := c.Get(ctx, configMapKey(), cm); err != nil {
    81  		return New(), err
    82  	}
    83  	return i.FromConfigMap(cm), nil
    84  }
    85  
    86  // FromConfigMap constructs the Info object from a k8s config map
    87  func (i *Info) FromConfigMap(cm *v1.ConfigMap) *Info {
    88  	i.DownlinkRateLimit = convertRateLimitToBits(cm.Data[downlinkRateKey])
    89  	i.UplinkRateLimit = convertRateLimitToBits(cm.Data[uplinkRateKey])
    90  
    91  	if egressGatewayEnabled, err := strconv.ParseBool(cm.Data[gatewayEnabledKey]); err == nil {
    92  		i.EgressGatewayEnabled = egressGatewayEnabled
    93  	}
    94  
    95  	if gatewayRateLimitingEnabled, err := strconv.ParseBool(cm.Data[gatewayRateLimitEnabledKey]); err == nil {
    96  		i.GatewayRateLimitingEnabled = gatewayRateLimitingEnabled
    97  	}
    98  
    99  	if thickPOS, err := strconv.ParseBool(cm.Data[thickPosKey]); err == nil {
   100  		i.ThickPOS = thickPOS
   101  	}
   102  
   103  	if linkerdIdentityCertDuration, err := strconv.Atoi(cm.Data[linkerdIdentityCertDurationKey]); err == nil {
   104  		i.LinkerdIdentityCertDuration = i.defaultCertDuration(linkerdIdentityCertDuration)
   105  	}
   106  
   107  	if linkerdIdentityCertRenewBefore, err := strconv.Atoi(cm.Data[linkerdIdentityCertRenewBeforeKey]); err == nil {
   108  		i.LinkerdIdentityCertRenewBefore = i.defaultCertRenewBefore(linkerdIdentityCertRenewBefore)
   109  	}
   110  	return i
   111  }
   112  
   113  // ensures default cert duration is not zero
   114  func (i *Info) defaultCertDuration(certDuration int) int {
   115  	if certDuration >= 24 {
   116  		return certDuration
   117  	}
   118  
   119  	if i.ThickPOS {
   120  		return int(linkerd.DefaultThickPosIdentityIssuerCertificateDurationHours)
   121  	}
   122  	return int(linkerd.DefaultThinPosIdentityIssuerCertificateDurationHours)
   123  }
   124  
   125  // ensures default cert renew before is not zero
   126  func (i *Info) defaultCertRenewBefore(certRenewBefore int) int {
   127  	if certRenewBefore >= 18 {
   128  		return certRenewBefore
   129  	}
   130  
   131  	if i.ThickPOS {
   132  		return int(linkerd.DefaultThickPosIdentityIssuerCertificateRenewBeforeHours)
   133  	}
   134  	return int(linkerd.DefaultThinPosIdentityIssuerCertificateRenewBeforeHours)
   135  }
   136  
   137  // FromGraphQLModel constructs Info object from database model
   138  func (i *Info) FromGraphQLModel(cfg model.ClusterConfig) *Info {
   139  	// sets linkerd identity issuer cert values from maximum lan outage duration
   140  	linkerdIdentityIssuerCertDuration := cfg.MaximumLanOutageHours
   141  	linkerdIdentityIssuerCertRenewBefore := linkerdIdentityIssuerCertDuration * 3 / 4
   142  
   143  	tpInfo := &Info{
   144  		ThickPOS:                       cfg.ThickPos,
   145  		GatewayRateLimitingEnabled:     cfg.GatewayRateLimitingEnabled,
   146  		EgressGatewayEnabled:           cfg.EgressGatewayEnabled,
   147  		LinkerdIdentityCertDuration:    linkerdIdentityIssuerCertDuration,
   148  		LinkerdIdentityCertRenewBefore: linkerdIdentityIssuerCertRenewBefore,
   149  		DownlinkRateLimit:              convertRateLimitToBits(cfg.DownlinkRateLimit),
   150  		UplinkRateLimit:                convertRateLimitToBits(cfg.UplinkRateLimit),
   151  	}
   152  	return tpInfo
   153  }
   154  
   155  // Converts the Info struct to a ConfigMap
   156  func (i *Info) ToConfigMap() *v1.ConfigMap {
   157  	return &v1.ConfigMap{
   158  		TypeMeta:   typemeta(),
   159  		ObjectMeta: metadata(),
   160  		Data: map[string]string{
   161  			downlinkRateKey:                   convertBitsToMbits(i.DownlinkRateLimit),
   162  			uplinkRateKey:                     convertBitsToMbits(i.UplinkRateLimit),
   163  			gatewayEnabledKey:                 strconv.FormatBool(i.EgressGatewayEnabled),
   164  			thickPosKey:                       strconv.FormatBool(i.ThickPOS),
   165  			gatewayRateLimitEnabledKey:        strconv.FormatBool(i.GatewayRateLimitingEnabled),
   166  			linkerdIdentityCertDurationKey:    strconv.Itoa(i.LinkerdIdentityCertDuration),
   167  			linkerdIdentityCertRenewBeforeKey: strconv.Itoa(i.LinkerdIdentityCertRenewBefore),
   168  		},
   169  	}
   170  }
   171  
   172  // PredicateFilter returns the predicate function for topology-info configmap
   173  func PredicateFilter() predicate.Funcs {
   174  	return predicate.NewPredicateFuncs(func(object client.Object) bool {
   175  		return object.GetNamespace() == Namespace && object.GetName() == Name
   176  	})
   177  }
   178  
   179  // generates a blank topology info config map
   180  func newTopologyInfoConfigMap() v1.ConfigMap {
   181  	return v1.ConfigMap{
   182  		TypeMeta:   typemeta(),
   183  		ObjectMeta: metadata(),
   184  	}
   185  }
   186  
   187  // topology info config map type meta
   188  func typemeta() metav1.TypeMeta {
   189  	return metav1.TypeMeta{
   190  		Kind:       "ConfigMap",
   191  		APIVersion: v1.SchemeGroupVersion.String(),
   192  	}
   193  }
   194  
   195  // topology info config map meta data
   196  func metadata() metav1.ObjectMeta {
   197  	return metav1.ObjectMeta{
   198  		Name:      Name,
   199  		Namespace: Namespace,
   200  	}
   201  }
   202  
   203  // constructs the object key for topology info
   204  func configMapKey() types.NamespacedName {
   205  	return types.NamespacedName{
   206  		Name:      Name,
   207  		Namespace: Namespace,
   208  	}
   209  }
   210  

View as plain text