Skip to content

Commit

Permalink
Upgrade go-functional to v2
Browse files Browse the repository at this point in the history
  • Loading branch information
BooleanCat committed Jul 20, 2024
1 parent c376fb7 commit da01a16
Show file tree
Hide file tree
Showing 20 changed files with 105 additions and 83 deletions.
8 changes: 5 additions & 3 deletions api/repositories/app_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"slices"
"sort"
"strings"
"time"
Expand All @@ -15,7 +16,8 @@ import (
"code.cloudfoundry.org/korifi/controllers/webhooks/validation"
"code.cloudfoundry.org/korifi/tools/k8s"

"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/google/uuid"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -323,8 +325,8 @@ func (f *AppRepo) ListApps(ctx context.Context, authInfo authorization.Info, mes
apps = append(apps, appList.Items...)
}

filteredApps := iter.Lift(apps).Filter(message.matches)
appRecords := iter.Map(filteredApps, cfAppToAppRecord).Collect()
filteredApps := itx.FromSlice(apps).Filter(message.matches)
appRecords := slices.Collect(it.Map(filteredApps, cfAppToAppRecord))

// By default sort it by App.DisplayName
sort.Sort(byName(appRecords))
Expand Down
10 changes: 6 additions & 4 deletions api/repositories/domain_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ package repositories
import (
"context"
"fmt"
"slices"
"sort"
"time"

"code.cloudfoundry.org/korifi/api/authorization"
apierrors "code.cloudfoundry.org/korifi/api/errors"
korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1"
"code.cloudfoundry.org/korifi/tools/k8s"
"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/google/uuid"

k8serrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -162,10 +164,10 @@ func (r *DomainRepo) ListDomains(ctx context.Context, authInfo authorization.Inf
return []DomainRecord{}, fmt.Errorf("failed to list domains in namespace %s: %w", r.rootNamespace, apierrors.FromK8sError(err, DomainResourceType))
}

domainRecords := iter.Map(
iter.Lift(cfdomainList.Items).Filter(message.matches),
domainRecords := slices.Collect(it.Map(
itx.FromSlice(cfdomainList.Items).Filter(message.matches),
cfDomainToDomainRecord,
).Collect()
))
sort.Slice(domainRecords, func(i, j int) bool {
return domainRecords[i].CreatedAt.Before(domainRecords[j].CreatedAt)
})
Expand Down
7 changes: 4 additions & 3 deletions api/repositories/droplet_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (
"time"

"code.cloudfoundry.org/korifi/tools/k8s"
"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"

"code.cloudfoundry.org/korifi/api/authorization"
apierrors "code.cloudfoundry.org/korifi/api/errors"
Expand Down Expand Up @@ -169,8 +170,8 @@ func (r *DropletRepo) ListDroplets(ctx context.Context, authInfo authorization.I
allBuilds = append(allBuilds, buildList.Items...)
}

filteredBuilds := iter.Lift(allBuilds).Filter(message.matches)
return iter.Map(filteredBuilds, cfBuildToDropletRecord).Collect(), nil
filteredBuilds := itx.FromSlice(allBuilds).Filter(message.matches)
return itx.From(it.Map(filteredBuilds, cfBuildToDropletRecord)).Collect(), nil
}

type UpdateDropletMessage struct {
Expand Down
7 changes: 4 additions & 3 deletions api/repositories/metrics_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package repositories
import (
"context"
"fmt"
"slices"

"code.cloudfoundry.org/korifi/api/authorization"
apierrors "code.cloudfoundry.org/korifi/api/errors"
"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
corev1 "k8s.io/api/core/v1"
metricsv1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -44,9 +45,9 @@ func (r *MetricsRepo) GetMetrics(ctx context.Context, authInfo authorization.Inf
return nil, fmt.Errorf("failed to list pods: %w", apierrors.FromK8sError(err, PodResourceType))
}

return iter.Map(iter.Lift(podList.Items), func(pod corev1.Pod) PodMetrics {
return slices.Collect(it.Map(slices.Values(podList.Items), func(pod corev1.Pod) PodMetrics {
metrics := metricsv1beta1.PodMetrics{}
_ = userClient.Get(ctx, client.ObjectKeyFromObject(&pod), &metrics)
return PodMetrics{Pod: pod, Metrics: metrics}
}).Collect(), nil
})), nil
}
7 changes: 4 additions & 3 deletions api/repositories/org_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1"
"code.cloudfoundry.org/korifi/tools/k8s"

"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/google/uuid"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -132,10 +133,10 @@ func (r *OrgRepo) ListOrgs(ctx context.Context, info authorization.Info, message
return nil, apierrors.FromK8sError(err, OrgResourceType)
}

filteredOrgs := iter.Lift(cfOrgList.Items).Filter(func(org korifiv1alpha1.CFOrg) bool {
filteredOrgs := itx.FromSlice(cfOrgList.Items).Filter(func(org korifiv1alpha1.CFOrg) bool {
return authorizedNamespaces[org.Name] && message.matches(org)
})
return iter.Map(filteredOrgs, cfOrgToOrgRecord).Collect(), nil
return itx.From(it.Map(filteredOrgs, cfOrgToOrgRecord)).Collect(), nil
}

func (r *OrgRepo) GetOrg(ctx context.Context, info authorization.Info, orgGUID string) (OrgRecord, error) {
Expand Down
7 changes: 4 additions & 3 deletions api/repositories/package_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
"code.cloudfoundry.org/korifi/tools/dockercfg"
"code.cloudfoundry.org/korifi/tools/k8s"

"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/uuid"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -334,8 +335,8 @@ func (r *PackageRepo) ListPackages(ctx context.Context, authInfo authorization.I
packages = append(packages, packageList.Items...)
}

filteredPackages := iter.Lift(packages).Filter(message.matches)
return iter.Map(filteredPackages, r.cfPackageToPackageRecord).Collect(), nil
filteredPackages := itx.FromSlice(packages).Filter(message.matches)
return slices.Collect(it.Map(filteredPackages, r.cfPackageToPackageRecord)), nil
}

func (r *PackageRepo) UpdatePackageSource(ctx context.Context, authInfo authorization.Info, message UpdatePackageSourceMessage) (PackageRecord, error) {
Expand Down
19 changes: 11 additions & 8 deletions api/repositories/pod_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"context"
"fmt"
"io"
"iter"
"slices"
"strings"
"time"

Expand All @@ -13,7 +15,8 @@ import (
korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1"
k8sclient "k8s.io/client-go/kubernetes"

"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
labels "k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -63,7 +66,7 @@ func (r *PodRepo) DeletePod(ctx context.Context, authInfo authorization.Info, ap
return fmt.Errorf("failed to list pods: %w", apierrors.FromK8sError(err, PodResourceType))
}

podsToDelete := iter.Lift(podList.Items).Filter(func(pod corev1.Pod) bool {
podsToDelete := itx.FromSlice(podList.Items).Filter(func(pod corev1.Pod) bool {
return strings.HasSuffix(pod.Name, instanceID)
}).Collect()

Expand Down Expand Up @@ -107,24 +110,24 @@ func (r *PodRepo) GetRuntimeLogsForApp(ctx context.Context, logger logr.Logger,
return nil, fmt.Errorf("failed to build user client: %w", err)
}

logRecords := iter.Map(iter.Lift(podList.Items), func(pod corev1.Pod) iter.Iterator[LogRecord] {
logRecords := slices.Collect(it.Map(slices.Values(podList.Items), func(pod corev1.Pod) func(func(LogRecord) bool) {
return r.getPodLogs(ctx, logClient, logger, pod, message.Limit)
}).Collect()
}))

return iter.Chain(logRecords...).Collect(), nil
return slices.Collect(it.Chain(logRecords...)), nil
}

func (r *PodRepo) getPodLogs(ctx context.Context, k8sClient k8sclient.Interface, logger logr.Logger, pod corev1.Pod, limit int64) iter.Iterator[LogRecord] {
func (r *PodRepo) getPodLogs(ctx context.Context, k8sClient k8sclient.Interface, logger logr.Logger, pod corev1.Pod, limit int64) iter.Seq[LogRecord] {
logReadCloser, err := k8sClient.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &corev1.PodLogOptions{Timestamps: true, TailLines: &limit}).Stream(ctx)
if err != nil {
logger.Info("failed to fetch logs", "pod", pod.Name, "reason", err)
return iter.Exhausted[LogRecord]()
return it.Exhausted[LogRecord]()
}

defer logReadCloser.Close()

logLines := readLines(logReadCloser, logger.WithValues("pod", pod.Name))
return iter.Map(iter.Lift(logLines), logLineToLogRecord)
return it.Map(slices.Values(logLines), logLineToLogRecord)
}

func readLines(r io.Reader, logger logr.Logger) []string {
Expand Down
12 changes: 6 additions & 6 deletions api/repositories/process_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ package repositories
import (
"context"
"fmt"
"slices"
"time"

"code.cloudfoundry.org/korifi/api/authorization"
apierrors "code.cloudfoundry.org/korifi/api/errors"
korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1"
"code.cloudfoundry.org/korifi/tools/k8s"
"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"

corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
ProcessResourceType = "Process"
)
const ProcessResourceType = "Process"

func NewProcessRepo(namespaceRetriever NamespaceRetriever, userClientFactory authorization.UserK8sClientFactory, namespacePermissions *authorization.NamespacePermissions) *ProcessRepo {
return &ProcessRepo{
Expand Down Expand Up @@ -167,8 +167,8 @@ func (r *ProcessRepo) ListProcesses(ctx context.Context, authInfo authorization.
processes = append(processes, processList.Items...)
}

filteredProcesses := iter.Lift(processes).Filter(message.matches)
return iter.Map(filteredProcesses, cfProcessToProcessRecord).Collect(), nil
filteredProcesses := itx.FromSlice(processes).Filter(message.matches)
return slices.Collect(it.Map(filteredProcesses, cfProcessToProcessRecord)), nil
}

func (r *ProcessRepo) ScaleProcess(ctx context.Context, authInfo authorization.Info, scaleProcessMessage ScaleProcessMessage) (ProcessRecord, error) {
Expand Down
15 changes: 8 additions & 7 deletions api/repositories/role_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
"context"
"crypto/sha256"
"fmt"
"maps"
"slices"
"strconv"
"time"

"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/google/uuid"
"golang.org/x/exp/maps"
rbacv1 "k8s.io/api/rbac/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -238,7 +239,7 @@ func (r *RoleRepo) ListRoles(ctx context.Context, authInfo authorization.Info) (
return nil, fmt.Errorf("failed to list namespaces for spaces with user role bindings: %w", err)
}

nsList := iter.Chain(authorisedSpaceNamespaces, authorizedOrgNamespaces).Collect()
nsList := authorisedSpaceNamespaces.Chain(authorizedOrgNamespaces).Collect()
roleBindings := []rbacv1.RoleBinding{}
for _, ns := range nsList {
roleBindingsList := &rbacv1.RoleBindingList{}
Expand All @@ -252,8 +253,8 @@ func (r *RoleRepo) ListRoles(ctx context.Context, authInfo authorization.Info) (
roleBindings = append(roleBindings, roleBindingsList.Items...)
}

cfRoleBindings := iter.Lift(roleBindings).Filter(r.isCFRole)
return iter.Map(cfRoleBindings, r.toRoleRecord).Collect(), nil
cfRoleBindings := itx.FromSlice(roleBindings).Filter(r.isCFRole)
return slices.Collect(it.Map(cfRoleBindings, r.toRoleRecord)), nil
}

func (r *RoleRepo) isCFRole(rb rbacv1.RoleBinding) bool {
Expand All @@ -271,9 +272,9 @@ func (r *RoleRepo) getCFRoleName(k8sRoleName string) string {
}

func (r *RoleRepo) getCFRoleNames() []string {
return iter.Map(iter.Lift(maps.Values(r.roleMappings)), func(r config.Role) string {
return slices.Collect(it.Map(maps.Values(r.roleMappings), func(r config.Role) string {
return r.Name
}).Collect()
}))
}

func (r *RoleRepo) toRoleRecord(roleBinding rbacv1.RoleBinding) RoleRecord {
Expand Down
25 changes: 13 additions & 12 deletions api/repositories/route_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1"
"code.cloudfoundry.org/korifi/tools/k8s"

"github.com/BooleanCat/go-functional/iter"
"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
"github.com/google/uuid"
v1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -117,7 +118,7 @@ func (m *ListRoutesMessage) matchesApp(r korifiv1alpha1.CFRoute) bool {
return true
}

return len(iter.Lift(r.Spec.Destinations).Filter(func(d korifiv1alpha1.Destination) bool {
return len(itx.FromSlice(r.Spec.Destinations).Filter(func(d korifiv1alpha1.Destination) bool {
return slices.Contains(m.AppGUIDs, d.AppRef.Name)
}).Collect()) > 0
}
Expand Down Expand Up @@ -207,8 +208,8 @@ func (r *RouteRepo) ListRoutes(ctx context.Context, authInfo authorization.Info,
routes = append(routes, cfRouteList.Items...)
}

filteredRoutes := iter.Lift(routes).Filter(message.matches)
return iter.Map(filteredRoutes, cfRouteToRouteRecord).Collect(), nil
filteredRoutes := itx.FromSlice(routes).Filter(message.matches)
return slices.Collect(it.Map(filteredRoutes, cfRouteToRouteRecord)), nil
}

func cfRouteToRouteRecord(cfRoute korifiv1alpha1.CFRoute) RouteRecord {
Expand All @@ -231,7 +232,7 @@ func cfRouteToRouteRecord(cfRoute korifiv1alpha1.CFRoute) RouteRecord {
}

func cfRouteDestinationsToDestinationRecords(cfRoute korifiv1alpha1.CFRoute) []DestinationRecord {
return iter.Map(iter.Lift(cfRoute.Spec.Destinations), func(specDestination korifiv1alpha1.Destination) DestinationRecord {
return slices.Collect(it.Map(slices.Values(cfRoute.Spec.Destinations), func(specDestination korifiv1alpha1.Destination) DestinationRecord {
record := DestinationRecord{
GUID: specDestination.GUID,
AppGUID: specDestination.AppRef.Name,
Expand All @@ -249,7 +250,7 @@ func cfRouteDestinationsToDestinationRecords(cfRoute korifiv1alpha1.CFRoute) []D
}

return record
}).Collect()
}))
}

func (r *RouteRepo) ListRoutesForApp(ctx context.Context, authInfo authorization.Info, appGUID string, spaceGUID string) ([]RouteRecord, error) {
Expand Down Expand Up @@ -351,7 +352,7 @@ func (r *RouteRepo) RemoveDestinationFromRoute(ctx context.Context, authInfo aut
return RouteRecord{}, fmt.Errorf("failed to get route: %w", apierrors.FromK8sError(err, RouteResourceType))
}

updatedDestinations := iter.Lift(cfRoute.Spec.Destinations).Exclude(message.matches).Collect()
updatedDestinations := itx.FromSlice(cfRoute.Spec.Destinations).Exclude(message.matches).Collect()
if len(updatedDestinations) == len(cfRoute.Spec.Destinations) {
return RouteRecord{}, apierrors.NewUnprocessableEntityError(nil, "Unable to unmap route from destination. Ensure the route has a destination with this guid.")
}
Expand Down Expand Up @@ -393,14 +394,14 @@ func destinationMessageToDestination(m DesiredDestination) korifiv1alpha1.Destin
}

func contains(existingDestinations []korifiv1alpha1.Destination, desired DesiredDestination) bool {
matches := iter.Lift(existingDestinations).Filter(func(dest korifiv1alpha1.Destination) bool {
_, ok := itx.FromSlice(existingDestinations).Find(func(dest korifiv1alpha1.Destination) bool {
return desired.AppGUID == dest.AppRef.Name &&
desired.ProcessType == dest.ProcessType &&
equal(desired.Port, dest.Port) &&
equal(desired.Protocol, dest.Protocol)
}).Collect()
})

return len(matches) > 0
return ok
}

func equal[T comparable](v1, v2 *T) bool {
Expand Down Expand Up @@ -434,7 +435,7 @@ func (r *RouteRepo) fetchRouteByFields(ctx context.Context, authInfo authorizati
}

func destinationRecordsToCFDestinations(destinationRecords []DestinationRecord) []korifiv1alpha1.Destination {
return iter.Map(iter.Lift(destinationRecords), func(destinationRecord DestinationRecord) korifiv1alpha1.Destination {
return slices.Collect(it.Map(slices.Values(destinationRecords), func(destinationRecord DestinationRecord) korifiv1alpha1.Destination {
return korifiv1alpha1.Destination{
GUID: destinationRecord.GUID,
Port: destinationRecord.Port,
Expand All @@ -444,7 +445,7 @@ func destinationRecordsToCFDestinations(destinationRecords []DestinationRecord)
ProcessType: destinationRecord.ProcessType,
Protocol: destinationRecord.Protocol,
}
}).Collect()
}))
}

func (r *RouteRepo) PatchRouteMetadata(ctx context.Context, authInfo authorization.Info, message PatchRouteMetadataMessage) (RouteRecord, error) {
Expand Down
Loading

0 comments on commit da01a16

Please sign in to comment.