Skip to content

Commit

Permalink
sysdump: Detect features from cilium-config ConfigMap
Browse files Browse the repository at this point in the history
- Call FeatureSet.ExtractFromConfigMap to extract features from
  cilium-config.
- Add tasks related to SPIRE server if and only if "mutual-auth-spiffe"
  feature is enabled.

Ref: #1962

Signed-off-by: Michi Mutsuzaki <[email protected]>
  • Loading branch information
michi-covalent committed Oct 6, 2023
1 parent 643f9ff commit a037542
Showing 1 changed file with 130 additions and 109 deletions.
239 changes: 130 additions & 109 deletions sysdump/sysdump.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/cilium/cilium-cli/defaults"
"github.com/cilium/cilium-cli/internal/utils"
"github.com/cilium/cilium-cli/k8s"
"github.com/cilium/cilium-cli/utils/features"
)

const sysdumpLogFile = "cilium-sysdump.log"
Expand Down Expand Up @@ -153,14 +154,17 @@ type Collector struct {
CiliumConfigMap *corev1.ConfigMap
// additionalTasks keeps track of additional tasks added via AddTasks.
additionalTasks []Task
// FeatureSet is a map of enabled / disabled features based on the contents of cilium-config ConfigMap.
FeatureSet features.Set
}

// NewCollector returns a new sysdump collector.
func NewCollector(k KubernetesClient, o Options, startTime time.Time, cliVersion string) (*Collector, error) {
c := Collector{
Client: k,
Options: o,
startTime: startTime,
Client: k,
Options: o,
startTime: startTime,
FeatureSet: features.Set{},
}
tmp, err := os.MkdirTemp("", "*")
if err != nil {
Expand Down Expand Up @@ -263,6 +267,14 @@ func NewCollector(k KubernetesClient, o Options, startTime time.Time, cliVersion
}
c.log("ℹ️ %s ConfigMap not found in %s namespace", ciliumConfigMapName, c.Options.CiliumNamespace)
}
if c.CiliumConfigMap != nil && len(c.CiliumPods) > 0 {
ciliumVersion, err := c.Client.GetCiliumVersion(context.Background(), c.CiliumPods[0])
if err != nil {
return nil, fmt.Errorf("failed to get Cilium version from %s/%s: %w", c.CiliumPods[0].Namespace, c.CiliumPods[0].Name, err)
}
c.FeatureSet.ExtractFromConfigMap(*ciliumVersion, c.CiliumConfigMap)
c.log("🔮 Detected Cilium features: %v", c.FeatureSet)
}
}

return &c, nil
Expand Down Expand Up @@ -1208,112 +1220,7 @@ func (c *Collector) Run() error {
return nil
},
},
{
CreatesSubtasks: true,
Description: "Collecting logs from Cilium SPIRE server pods",
Quick: false,
Task: func(ctx context.Context) error {
p, err := c.Client.ListPods(ctx, c.Options.CiliumSPIRENamespace, metav1.ListOptions{
LabelSelector: c.Options.CiliumSPIREServerLabelSelector,
})
if err != nil {
return fmt.Errorf("failed to get logs from Cilium SPIRE server pods")
}
if err := c.SubmitLogsTasks(FilterPods(p, c.NodeList), c.Options.LogsSinceTime, c.Options.LogsLimitBytes); err != nil {
return fmt.Errorf("failed to collect logs from Cilium SPIRE server pods")
}
return nil
},
},
{
CreatesSubtasks: true,
Description: "Collecting logs from Cilium SPIRE agent pods",
Quick: false,
Task: func(ctx context.Context) error {
p, err := c.Client.ListPods(ctx, c.Options.CiliumSPIRENamespace, metav1.ListOptions{
LabelSelector: c.Options.CiliumSPIREAgentLabelSelector,
})
if err != nil {
return fmt.Errorf("failed to get logs from Cilium SPIRE agent pods")
}
if err := c.SubmitLogsTasks(FilterPods(p, c.NodeList), c.Options.LogsSinceTime, c.Options.LogsLimitBytes); err != nil {
return fmt.Errorf("failed to collect logs from Cilium SPIRE agent pods")
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE server statefulset",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetStatefulSet(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREServerStatefulSetName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("StatefulSet %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREServerStatefulSetName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE server statefulset: %w", err)
}
if err := c.WriteYAML(ciliumSPIREServerStatefulSetFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE server statefulset: %w", err)
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE agent daemonset",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetDaemonSet(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREAgentDaemonSetName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("Daemonset %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREAgentDaemonSetName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE agent daemonset: %w", err)
}
if err := c.WriteYAML(ciliumSPIREAgentDaemonsetFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE agent daemonset: %w", err)
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE agent configuration",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetConfigMap(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREAgentConfigMapName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("ConfigMap %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREAgentConfigMapName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE agent configuration: %w", err)
}
if err := c.WriteYAML(ciliumSPIREAgentConfigMapFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE agent configuration: %w", err)
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE server configuration",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetConfigMap(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREServerConfigMapName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("ConfigMap %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREServerConfigMapName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE server configuration: %w", err)
}
if err := c.WriteYAML(ciliumSPIREServerConfigMapFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE server configuration: %w", err)
}
return nil
},
},

{
CreatesSubtasks: true,
Description: "Collecting platform-specific data",
Expand Down Expand Up @@ -1610,6 +1517,9 @@ func (c *Collector) Run() error {
tasks = append(tasks, helmTasks...)
// Append tasks added by AddTasks.
tasks = append(tasks, c.additionalTasks...)
if c.FeatureSet[features.AuthSpiffe].Enabled {
tasks = append(tasks, c.getSPIRETasks()...)
}

// Adjust the worker count to make enough headroom for tasks that submit sub-tasks.
// This is necessary because 'Submit' is blocking.
Expand Down Expand Up @@ -1693,6 +1603,117 @@ func (c *Collector) Run() error {
return nil
}

func (c *Collector) getSPIRETasks() []Task {
return []Task{
{
CreatesSubtasks: true,
Description: "Collecting logs from Cilium SPIRE server pods",
Quick: false,
Task: func(ctx context.Context) error {
p, err := c.Client.ListPods(ctx, c.Options.CiliumSPIRENamespace, metav1.ListOptions{
LabelSelector: c.Options.CiliumSPIREServerLabelSelector,
})
if err != nil {
return fmt.Errorf("failed to get logs from Cilium SPIRE server pods")
}
if err := c.SubmitLogsTasks(FilterPods(p, c.NodeList), c.Options.LogsSinceTime, c.Options.LogsLimitBytes); err != nil {
return fmt.Errorf("failed to collect logs from Cilium SPIRE server pods")
}
return nil
},
},
{
CreatesSubtasks: true,
Description: "Collecting logs from Cilium SPIRE agent pods",
Quick: false,
Task: func(ctx context.Context) error {
p, err := c.Client.ListPods(ctx, c.Options.CiliumSPIRENamespace, metav1.ListOptions{
LabelSelector: c.Options.CiliumSPIREAgentLabelSelector,
})
if err != nil {
return fmt.Errorf("failed to get logs from Cilium SPIRE agent pods")
}
if err := c.SubmitLogsTasks(FilterPods(p, c.NodeList), c.Options.LogsSinceTime, c.Options.LogsLimitBytes); err != nil {
return fmt.Errorf("failed to collect logs from Cilium SPIRE agent pods")
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE server statefulset",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetStatefulSet(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREServerStatefulSetName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("StatefulSet %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREServerStatefulSetName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE server statefulset: %w", err)
}
if err := c.WriteYAML(ciliumSPIREServerStatefulSetFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE server statefulset: %w", err)
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE agent daemonset",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetDaemonSet(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREAgentDaemonSetName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("Daemonset %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREAgentDaemonSetName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE agent daemonset: %w", err)
}
if err := c.WriteYAML(ciliumSPIREAgentDaemonsetFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE agent daemonset: %w", err)
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE agent configuration",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetConfigMap(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREAgentConfigMapName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("ConfigMap %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREAgentConfigMapName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE agent configuration: %w", err)
}
if err := c.WriteYAML(ciliumSPIREAgentConfigMapFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE agent configuration: %w", err)
}
return nil
},
},
{
Description: "Collecting the Cilium SPIRE server configuration",
Quick: true,
Task: func(ctx context.Context) error {
v, err := c.Client.GetConfigMap(ctx, c.Options.CiliumSPIRENamespace, ciliumSPIREServerConfigMapName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
c.logWarn("ConfigMap %q not found in namespace %q - this is expected if SPIRE installation is not enabled", ciliumSPIREServerConfigMapName, c.Options.CiliumSPIRENamespace)
return nil
}
return fmt.Errorf("failed to collect the Cilium SPIRE server configuration: %w", err)
}
if err := c.WriteYAML(ciliumSPIREServerConfigMapFileName, v); err != nil {
return fmt.Errorf("failed to collect the Cilium SPIRE server configuration: %w", err)
}
return nil
},
},
}
}

func (c *Collector) log(msg string, args ...interface{}) {
fmt.Fprintf(c.logWriter, msg+"\n", args...)
}
Expand Down

0 comments on commit a037542

Please sign in to comment.