Skip to content

Commit

Permalink
Adding linkerd sidecar reporting to discovered intents resolution data
Browse files Browse the repository at this point in the history
  • Loading branch information
evyatarmeged committed Jan 23, 2025
1 parent ed6fe54 commit 5a0fd44
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 41 deletions.
1 change: 0 additions & 1 deletion src/mapper/pkg/cloudclient/cloud_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ func NewClient(ctx context.Context) (*CloudClientImpl, bool, error) {

func (c *CloudClientImpl) ReportDiscoveredIntents(ctx context.Context, intents []*DiscoveredIntentInput) error {
logrus.Debug("Uploading intents to cloud, count: ", len(intents))

_, err := ReportDiscoveredIntents(ctx, c.client, intents)
if err != nil {
return errors.Wrap(err)
Expand Down
48 changes: 44 additions & 4 deletions src/mapper/pkg/cloudclient/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,13 @@ input ClientIPConfig {
timeoutSeconds: Int
}

type ClientIntentAccessStatus {
total: Int!
allowed: Int!
blocked: Int!
wouldBeBlocked: Int!
}

type ClientIntentEvent {
firstTimestamp: Time
lastTimestamp: Time
Expand Down Expand Up @@ -359,6 +366,7 @@ input ClientIntentStatusInput {

type ClientIntentsFileRepresentation {
fileName: String!
namespacedFileName: String!
service: Service!
rows: [ClientIntentsRow!]!
content: String!
Expand Down Expand Up @@ -505,6 +513,11 @@ type DashboardData {
nonCompliantControls: Fraction!
}

type DashboardV2 {
dashboard: DashboardData!
findings: [FindingSummaryV2!]!
}

type DatabaseConfig {
dbname: String!
table: String!
Expand Down Expand Up @@ -712,6 +725,9 @@ type FeatureFlags {
isCloudServicesDetectionEnabled: Boolean
isCloudSecurityEnabled: Boolean
useClientIntentsV2: Boolean
enableFindingsV2: Boolean
useTypedIntentsCTE: Boolean
enableInternetIntentsSuggestions: Boolean
}

type Finding {
Expand All @@ -726,6 +742,7 @@ type Finding {
status: FindingStatus!
ignoredReason: String
type: FindingType!
controlId: RegulationCode!
}

enum FindingStatus {
Expand Down Expand Up @@ -768,11 +785,10 @@ type FindingSummaryV2 {
validationDescription: String
status: FindingStatus!
ignoredReason: String
serviceTotalCount: Int!
serviceOpenCount: Int!
clusterTotalCount: Int!
clusterOpenCount: Int!
workloadFindingsStatus: StatusSummary!
clusterFindingStatus: StatusSummary!
requirements: [FindingSummaryV2!]
wasOpen: Boolean!
}

"""NEW findings"""
Expand Down Expand Up @@ -981,6 +997,9 @@ input InputFeatureFlags {
isCloudServicesDetectionEnabled: Boolean
isCloudSecurityEnabled: Boolean
useClientIntentsV2: Boolean
enableFindingsV2: Boolean
useTypedIntentsCTE: Boolean
enableInternetIntentsSuggestions: Boolean
}

""" Findings filter """
Expand Down Expand Up @@ -1118,6 +1137,7 @@ enum IntegrationState {
FAILURE
PENDING
WARNING
DISABLED
}

type IntegrationStatus {
Expand Down Expand Up @@ -1627,6 +1647,7 @@ type Mutation {
ignored: Boolean!
reason: String
): Boolean!
createFindingsForOrg: Boolean!
"""Create a new generic integration"""
createGenericIntegration(
name: String!
Expand Down Expand Up @@ -1929,6 +1950,7 @@ input NetworkPolicySpecInput {
type Organization {
id: ID!
name: String!
uniqueName: String!
imageURL: String
settings: OrganizationSettings!
created: Time!
Expand Down Expand Up @@ -2002,6 +2024,11 @@ type Query {
clusterIds: [ID!]
featureFlags: InputFeatureFlags
): [ClientIntentsFileRepresentation!]!
""" Get service incoming internet connections """
serviceIncomingInternetConnections(
targetServiceId: ID!
lastSeenAfter: Time!
): [String!]!
"""Get access log"""
accessLog(
filter: InputAccessLogFilter
Expand Down Expand Up @@ -2052,6 +2079,9 @@ type Query {
findingSummaryStatusHistory(
leafControlIDs: [RegulationCode!]!
): [FindingStatusHistory!]!
dashboardV2(
filter: InputFindingFilter
): DashboardV2!
"""List integrations"""
integrations(
name: String
Expand Down Expand Up @@ -2343,6 +2373,8 @@ input ServiceBackendPortInput {
type ServiceClientIntents {
asClient: ClientIntentsFiles
asServer: ClientIntentsFiles
asClientStatus: ClientIntentAccessStatus
asServerStatus: ClientIntentAccessStatus
appliedIntentStatus: ClientIntentStatus
appliedIntentEvents: [ClientIntentEvent!]
}
Expand Down Expand Up @@ -2453,6 +2485,14 @@ input StackFrame {
package: String!
}

type StatusSummary {
openCount: Int!
resolvedCount: Int!
ignoredCount: Int!
totalCount: Int!
status: FindingStatus!
}

"""The `String`scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."""
scalar String

Expand Down
70 changes: 62 additions & 8 deletions src/mapper/pkg/graph/generated/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions src/mapper/pkg/graph/model/models_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 17 additions & 5 deletions src/mapper/pkg/resolvers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"time"
)

const LinkerdSidecarContainerName = "linkerd-proxy"

var SourceIsHostNetworkPodError = errors.NewSentinelError("source is a host network pod, ignoring")

func (r *Resolver) discoverInternalSrcIdentity(ctx context.Context, src *model.RecordedDestinationsForSrc) (model.OtterizeServiceIdentity, error) {
Expand Down Expand Up @@ -89,11 +91,12 @@ func (r *Resolver) resolveInClusterIdentity(ctx context.Context, pod *corev1.Pod
Namespace: pod.Namespace,
Labels: kubefinder.PodLabelsToOtterizeLabels(pod),
ResolutionData: &model.IdentityResolutionData{
Host: lo.ToPtr(pod.Status.PodIP),
PodHostname: lo.ToPtr(pod.Name),
IsService: lo.ToPtr(false),
ExtraInfo: lo.ToPtr("resolveInClusterIdentity"),
Uptime: lo.ToPtr(time.Since(pod.CreationTimestamp.Time).String()),
Host: lo.ToPtr(pod.Status.PodIP),
PodHostname: lo.ToPtr(pod.Name),
IsService: lo.ToPtr(false),
ExtraInfo: lo.ToPtr("resolveInClusterIdentity"),
Uptime: lo.ToPtr(time.Since(pod.CreationTimestamp.Time).String()),
HasLinkerdSidecar: lo.ToPtr(hasLinkerdSidecar(pod)),
},
}
if svcIdentity.OwnerObject != nil {
Expand All @@ -102,3 +105,12 @@ func (r *Resolver) resolveInClusterIdentity(ctx context.Context, pod *corev1.Pod

return modelSvcIdentity, nil
}

func hasLinkerdSidecar(pod *corev1.Pod) bool {
for _, container := range pod.Spec.Containers {
if container.Name == LinkerdSidecarContainerName {
return true
}
}
return false
}
32 changes: 17 additions & 15 deletions src/mapper/pkg/resolvers/schema.helpers.resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,14 @@ func (r *Resolver) resolveDestIdentity(ctx context.Context, dest model.Destinati
Namespace: destPod.Namespace,
Labels: kubefinder.PodLabelsToOtterizeLabels(destPod),
ResolutionData: &model.IdentityResolutionData{
Host: lo.ToPtr(dest.Destination),
PodHostname: lo.ToPtr(destPod.Name),
Port: dest.DestinationPort,
IsService: lo.ToPtr(false),
ExtraInfo: lo.ToPtr("resolveDestIdentity"),
LastSeen: lo.ToPtr(dest.LastSeen.String()),
Uptime: lo.ToPtr(time.Since(destPod.CreationTimestamp.Time).String()),
Host: lo.ToPtr(dest.Destination),
PodHostname: lo.ToPtr(destPod.Name),
Port: dest.DestinationPort,
IsService: lo.ToPtr(false),
ExtraInfo: lo.ToPtr("resolveDestIdentity"),
LastSeen: lo.ToPtr(dest.LastSeen.String()),
Uptime: lo.ToPtr(time.Since(destPod.CreationTimestamp.Time).String()),
HasLinkerdSidecar: lo.ToPtr(hasLinkerdSidecar(destPod)),
},
}
if dstService.OwnerObject != nil {
Expand Down Expand Up @@ -187,13 +188,14 @@ func (r *Resolver) addSocketScanPodIntent(ctx context.Context, srcSvcIdentity mo
Namespace: destPod.Namespace,
Labels: kubefinder.PodLabelsToOtterizeLabels(destPod),
ResolutionData: &model.IdentityResolutionData{
Host: lo.ToPtr(dest.Destination),
PodHostname: lo.ToPtr(destPod.Name),
Port: dest.DestinationPort,
IsService: lo.ToPtr(false),
ExtraInfo: lo.ToPtr("addSocketScanPodIntent"),
LastSeen: lo.ToPtr(dest.LastSeen.String()),
Uptime: lo.ToPtr(time.Since(destPod.CreationTimestamp.Time).String()),
Host: lo.ToPtr(dest.Destination),
PodHostname: lo.ToPtr(destPod.Name),
Port: dest.DestinationPort,
IsService: lo.ToPtr(false),
ExtraInfo: lo.ToPtr("addSocketScanPodIntent"),
LastSeen: lo.ToPtr(dest.LastSeen.String()),
Uptime: lo.ToPtr(time.Since(destPod.CreationTimestamp.Time).String()),
HasLinkerdSidecar: lo.ToPtr(hasLinkerdSidecar(destPod)),
},
}
if dstService.OwnerObject != nil {
Expand Down Expand Up @@ -374,7 +376,7 @@ func (r *Resolver) resolveOtterizeIdentityForDestinationAddress(ctx context.Cont

resolutionData.PodHostname = lo.ToPtr(destPod.Name)
resolutionData.Uptime = lo.ToPtr(time.Since(destPod.CreationTimestamp.Time).String())

resolutionData.HasLinkerdSidecar = lo.ToPtr(hasLinkerdSidecar(destPod))
dstService, err := r.serviceIdResolver.ResolvePodToServiceIdentity(ctx, destPod)
if err != nil {
logrus.WithError(err).Debugf("Could not resolve pod %s to identity", destPod.Name)
Expand Down
1 change: 1 addition & 0 deletions src/mappergraphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type IdentityResolutionData {
uptime: String
lastSeen: String
extraInfo: String
hasLinkerdSidecar: Boolean
}

type OtterizeServiceIdentity {
Expand Down

0 comments on commit 5a0fd44

Please sign in to comment.