diff --git a/README.md b/README.md index 972d668..0d2f873 100644 --- a/README.md +++ b/README.md @@ -1 +1,36 @@ -# kardinal-operator \ No newline at end of file +# Kardinal Operator + +Implementation of [Kardinal](https://github.com/kurtosis-tech/kardinal) as a K8S Operator. + +## Development + +Minikube + K8S manifest deployed. K8S context set to your local cluster. + +The following three commands are commonly used during development: + +``` +make lint (Run golangci linter. Can also be configured inside your IDE.) +make test (Run tests against local cluster) +make run (Run operator against your local cluster) +``` + +Manage custom resources with kubectl: + +```yaml +apiVersion: core.kardinal.dev/v1 +kind: Flow +metadata: + labels: + app.kubernetes.io/name: kardinal + app.kubernetes.io/managed-by: kustomize + name: flow-test + namespace: baseline +spec: + service: frontend + image: kurtosistech/frontend:demo-frontend +``` + +``` +kubectl create -f flow.yaml +kubectl delete -f flow.yaml +``` diff --git a/kardinal/resources/resources.go b/kardinal/resources/resources.go index 1a3a8a7..1b56d7f 100644 --- a/kardinal/resources/resources.go +++ b/kardinal/resources/resources.go @@ -149,8 +149,8 @@ func AddAnnotations(obj *metav1.ObjectMeta, annotations map[string]string) { } } -// TODO: Add create, update and delete global options -// TODO: Refactor the Apply... functions +// OPERATOR-TODO: Add create, update and delete global options +// OPERATOR-TODO: Refactor the Apply... functions func ApplyServiceResources(ctx context.Context, clusterResources *Resources, clusterTopologyResources *Resources, cl client.Client) error { for _, namespace := range clusterResources.Namespaces { @@ -176,6 +176,8 @@ func ApplyServiceResources(ctx context.Context, clusterResources *Resources, clu } } } + // OPERATOR-TODO: Set app and version labels on non-managed service if not already set. + // Those labels are required by Istio. } } } @@ -241,7 +243,7 @@ func ApplyDeploymentResources(ctx context.Context, clusterResources *Resources, /* else { annotationsToAdd := map[string]string{ "sidecar.istio.io/inject": "true", - // TODO: make this a flag to help debugging + // KARDINAL-TODO: make this a flag to help debugging // One can view the logs with: kubeclt logs -f -l app= -n -c istio-proxy "sidecar.istio.io/componentLogLevel": "lua:info", } diff --git a/kardinal/topology/service.go b/kardinal/topology/service.go index 72e4652..e586a01 100644 --- a/kardinal/topology/service.go +++ b/kardinal/topology/service.go @@ -101,7 +101,7 @@ func (service *Service) GetAppsV1Deployment(namespace string) *appsv1.Deployment deployment.Spec.Template.ObjectMeta = metav1.ObjectMeta{ Annotations: map[string]string{ "sidecar.istio.io/inject": trueStr, - // TODO: make this a flag to help debugging + // KARDINAL-TODO: make this a flag to help debugging // One can view the logs with: kubeclt logs -f -l app= -n -c istio-proxy "sidecar.istio.io/componentLogLevel": "lua:info", }, @@ -195,7 +195,7 @@ func (service *Service) GetVirtualService(services []*Service) (*istioclient.Vir destinationRule := service.GetDestinationRule(services) for _, svc := range services { - // TODO: Support for multiple ports + // KARDINAL-TODO: Support for multiple ports servicePort := &svc.ServiceSpec.Ports[0] var flowHost *string @@ -227,7 +227,7 @@ func (service *Service) GetVirtualService(services []*Service) (*istioclient.Vir } func (service *Service) GetDestinationRule(services []*Service) *istioclient.DestinationRule { - // TODO(shared-annotation) - we could store "shared" versions somewhere so that the pointers are the same + // KARDINAL-TODO(shared-annotation) - we could store "shared" versions somewhere so that the pointers are the same // if we do that then the render work around isn't necessary subsets := lo.UniqBy( lo.Map(services, func(svc *Service, _ int) *v1alpha3.Subset { @@ -238,7 +238,7 @@ func (service *Service) GetDestinationRule(services []*Service) *istioclient.Des }, } - // TODO Narrow down this configuration to only subsets created for telepresence intercepts or find a way to enable TLS for telepresence intercepts https://github.com/kurtosis-tech/kardinal-kontrol/issues/14 + // KARDINAL-TODO Narrow down this configuration to only subsets created for telepresence intercepts or find a way to enable TLS for telepresence intercepts https://github.com/kurtosis-tech/kardinal-kontrol/issues/14 // This config is necessary for Kardinal/Telepresence (https://www.telepresence.io/) integration if svc.IsManaged { newTrafficPolicy := &v1alpha3.TrafficPolicy{ diff --git a/kardinal/topology/topology.go b/kardinal/topology/topology.go index 80bee44..d0e4dc1 100644 --- a/kardinal/topology/topology.go +++ b/kardinal/topology/topology.go @@ -108,7 +108,7 @@ func (clusterTopology *ClusterTopology) UpdateWithFlow( clusterTopology.UpdateDependencies(service, modifiedService) // create versioned parents for non http stateful services - // TODO - this should be done for all non http services and not just the stateful ones + // KARDINAL-TODO - this should be done for all non http services and not just the stateful ones // every child should be copied; immediate parent duplicated // if children of non http services support http then our routing will have to be modified // we should treat those http services as non http; a hack could be to remove the appProtocol HTTP marking @@ -178,7 +178,7 @@ func (clusterTopology *ClusterTopology) GetResources() (*resources.Resources, er }) for _, services := range groupedServices { if len(services) > 0 { - // TODO: this assumes service specs didn't change. May we need a new version to ClusterTopology data structure + // KARDINAL-TODO: this assumes service specs didn't change. May we need a new version to ClusterTopology data structure // ServiceSpec is nil for external services - don't process anything bc theres nothing to add to the cluster if services[0].ServiceSpec == nil { @@ -190,7 +190,7 @@ func (clusterTopology *ClusterTopology) GetResources() (*resources.Resources, er resourceNamespace.VirtualServices = append(resourceNamespace.VirtualServices, virtualService) resourceNamespace.DestinationRules = append(resourceNamespace.DestinationRules, destinationRule) - // TODO: Add authz policies + // OPERATOR-TODO: Add authz policies } } @@ -239,7 +239,7 @@ func (clusterTopology *ClusterTopology) ApplyResources(ctx context.Context, clus return stacktrace.Propagate(err, "An error occurred applying the virtual service resources") } - // TODO: Apply ingress resources + // OPERATOR-TODO: Apply ingress resources /* err = resources.ApplyIngressResources(ctx, clusterResources, clusterTopologyResources, cl) if err != nil { return stacktrace.Propagate(err, "An error occurred applying the ingress resources") @@ -319,9 +319,7 @@ func (clusterTopology *ClusterTopology) Merge(clusterTopologies []*ClusterTopolo mergedClusterTopology.Ingress.ActiveFlowIDs = lo.Uniq(mergedClusterTopology.Ingress.ActiveFlowIDs) logrus.Infof("Services length: %d", len(mergedClusterTopology.Services)) - // TODO improve the filtering method, we could implement the `Service.Equal` method to compare and filter the services - // TODO and inside this method we could use the k8s service marshall method (https://pkg.go.dev/k8s.io/api/core/v1#Service.Marsha) and also the same for other k8s fields - // TODO it should be faster + // KARDINAL-TODO improve the filtering method, we could implement the `Service.Equal` method to compare and filter the services and inside this method we could use the k8s service marshall method (https://pkg.go.dev/k8s.io/api/core/v1#Service.Marsha) and also the same for other k8s fields it should be faster mergedClusterTopology.Services = lo.UniqBy(mergedClusterTopology.Services, func(service *Service) ServiceVersion { serviceVersion := ServiceVersion{ ServiceID: service.ServiceID, @@ -473,7 +471,7 @@ func processServices(services []*corev1.Service, deployments []*appsv1.Deploymen clusterTopologyServices = append(clusterTopologyServices, clusterTopologyService) } - // TODO: Use the dependency CRs instead + // OPERATOR-TODO: Use the dependency CRs instead for _, svcWithDependenciesAnnotation := range serviceWithDependencies { serviceAndPorts := strings.Split(svcWithDependenciesAnnotation.dependenciesAnnotation, ",")