code: func redactClusters(clusters []*api.Cluster) []*api.Cluster {
  	var redactedClusters []*api.Cluster
  	// Only add public fields to the new clusters
  	for _, cluster := range clusters {
  		// Copy all the mandatory fields
  		// Do not copy secret keys
  		redactedSpec := cluster.Spec.Copy()
  		redactedSpec.CAConfig.SigningCAKey = nil
  		// the cert is not a secret, but if API users get the cluster spec and then update,
  		// then because the cert is included but not the key, the user can get update errors
  		// or unintended consequences (such as telling swarm to forget about the key so long
  		// as there is a corresponding external CA)
  		redactedSpec.CAConfig.SigningCACert = nil
  
  		redactedRootCA := cluster.RootCA.Copy()
  		redactedRootCA.CAKey = nil
  		if r := redactedRootCA.RootRotation; r != nil {
  			r.CAKey = nil
  		}
  		newCluster := &api.Cluster{
  			ID:                      cluster.ID,
  			Meta:                    cluster.Meta,
  			Spec:                    *redactedSpec,
  			RootCA:                  *redactedRootCA,
  			BlacklistedCertificates: cluster.BlacklistedCertificates,
  			DefaultAddressPool:      cluster.DefaultAddressPool,
  			SubnetSize:              cluster.SubnetSize,
  			VXLANUDPPort:            cluster.VXLANUDPPort,
  		}
  		if newCluster.DefaultAddressPool == nil {
  			// This is just for CLI display. Set the inbuilt default pool for
  			// user reference.
  			newCluster.DefaultAddressPool = inbuiltDefaultAddressPool
  			newCluster.SubnetSize = inbuiltSubnetSize
  		}
  		if newCluster.VXLANUDPPort == 0 {
  			newCluster.VXLANUDPPort = defaultVXLANPort
  		}
  		redactedClusters = append(redactedClusters, newCluster)
  	}
  
  	return redactedClusters
  }
docs: // redactClusters is a method that enforces a whitelist of fields that are ok to be
  // returned in the Cluster object. It should filter out all sensitive information.