What problem are you facing?
We use Terraform schema to generate the type of every field. While Terraform has one big untyped tree of fields to hold all the information, that's not the case in Crossplane. In line with Kubernetes API conventions, we separate fields into spec
and status
fields, status
ones being fields that user cannot ever configure.
In Terraform schema, fields report whether they are Computed
and Optional
. The fields that are both Computed
and Optional
are the ones that have server-side defaults and user-configurable; the ones we late-initialize. So we put those under spec, but fields that are Computed
and not Optional
go to status
.
The problem is that there can be some types that are Computed
and not Optional
but also has nested fields that can go under spec
and vice versa. Right now, when we compute the type for a field, we return a parameters type as well as an observation type, then decide which one to use depending on the properties of the field. If the field goes to spec but there are nested fields that could go to status, they are eliminated. Also, if a field goes to status, all nested fields go to status as well and the parameter types are ignored.
When I did an analysis of how prevalent this problem is in, for example, AWS, I see the following output:
there are 1 fields that could be observation type of .SyntheticsCanary.VpcConfig but ignored since the field is a parameters field
there are 2 fields that could be observation type of .AmplifyDomainAssociation.SubDomain but ignored since the field is a parameters field
there are 1 fields that could be observation type of .StoragegatewayGateway.SmbActiveDirectorySettings but ignored since the field is a parameters field
there are 1 fields that could be observation type of .LexBotAlias.ConversationLogs.LogSettings but ignored since the field is a parameters field
there are 1 fields that could be observation type of .Route53ResolverEndpoint.IpAddress but ignored since the field is a parameters field
there are 1 fields that could be observation type of .LambdaFunction.VpcConfig but ignored since the field is a parameters field
there are 1 fields that could be observation type of .MwaaEnvironment.LoggingConfiguration.DagProcessingLogs but ignored since the field is a parameters field
there are 1 fields that could be observation type of .MwaaEnvironment.LoggingConfiguration.SchedulerLogs but ignored since the field is a parameters field
there are 1 fields that could be observation type of .MwaaEnvironment.LoggingConfiguration.TaskLogs but ignored since the field is a parameters field
there are 1 fields that could be observation type of .MwaaEnvironment.LoggingConfiguration.WebserverLogs but ignored since the field is a parameters field
there are 1 fields that could be observation type of .MwaaEnvironment.LoggingConfiguration.WorkerLogs but ignored since the field is a parameters field
there are 4 fields that could be parameters type of .ElasticBeanstalkEnvironment.AllSettings but ignored since the field is an observation field
there are 2 fields that could be observation type of .EksCluster.VpcConfig but ignored since the field is a parameters field
there are 2 fields that could be observation type of .DirectoryServiceDirectory.ConnectSettings but ignored since the field is a parameters field
there are 1 fields that could be observation type of .DirectoryServiceDirectory.VpcSettings but ignored since the field is a parameters field
there are 3 fields that could be observation type of .EmrCluster.CoreInstanceFleet but ignored since the field is a parameters field
there are 1 fields that could be observation type of .EmrCluster.CoreInstanceGroup but ignored since the field is a parameters field
there are 3 fields that could be observation type of .EmrCluster.MasterInstanceFleet but ignored since the field is a parameters field
there are 1 fields that could be observation type of .EmrCluster.MasterInstanceGroup but ignored since the field is a parameters field
there are 2 fields that could be observation type of .Kinesisanalyticsv2Application.ApplicationConfiguration.SqlApplicationConfiguration.Input but ignored since the field is a parameters field
there are 1 fields that could be observation type of .Kinesisanalyticsv2Application.ApplicationConfiguration.SqlApplicationConfiguration.Output but ignored since the field is a parameters field
there are 1 fields that could be observation type of .Kinesisanalyticsv2Application.ApplicationConfiguration.SqlApplicationConfiguration.ReferenceDataSource but ignored since the field is a parameters field
there are 2 fields that could be observation type of .Kinesisanalyticsv2Application.ApplicationConfiguration.VpcConfiguration but ignored since the field is a parameters field
there are 1 fields that could be observation type of .Kinesisanalyticsv2Application.CloudwatchLoggingOptions but ignored since the field is a parameters field
there are 3 fields that could be observation type of .SecretsmanagerSecret.Replica but ignored since the field is a parameters field
there are 4 fields that could be parameters type of .SsmDocument.Parameter but ignored since the field is an observation field
there are 1 fields that could be observation type of .Alb.SubnetMapping but ignored since the field is a parameters field
there are 1 fields that could be observation type of .SpotInstanceRequest.EbsBlockDevice but ignored since the field is a parameters field
there are 2 fields that could be observation type of .SpotInstanceRequest.RootBlockDevice but ignored since the field is a parameters field
there are 1 fields that could be observation type of .Lb.SubnetMapping but ignored since the field is a parameters field
there are 2 fields that could be observation type of .ElasticsearchDomain.VpcOptions but ignored since the field is a parameters field
there are 2 fields that could be observation type of .Apigatewayv2DomainName.DomainNameConfiguration but ignored since the field is a parameters field
there are 1 fields that could be observation type of .NetworkInterface.Attachment but ignored since the field is a parameters field
there are 1 fields that could be observation type of .Instance.EbsBlockDevice but ignored since the field is a parameters field
there are 2 fields that could be observation type of .Instance.RootBlockDevice but ignored since the field is a parameters field
there are 1 fields that could be observation type of .CodestarnotificationsNotificationRule.Target but ignored since the field is a parameters field
there are 2 fields that could be observation type of .CodeartifactRepository.ExternalConnections but ignored since the field is a parameters field
there are 8 fields that could be observation type of .AmiCopy.EbsBlockDevice but ignored since the field is a parameters field
there are 2 fields that could be observation type of .AmiCopy.EphemeralBlockDevice but ignored since the field is a parameters field
there are 8 fields that could be observation type of .AmiFromInstance.EbsBlockDevice but ignored since the field is a parameters field
there are 2 fields that could be observation type of .AmiFromInstance.EphemeralBlockDevice but ignored since the field is a parameters field
there are 1 fields that could be observation type of .KinesisAnalyticsApplication.CloudwatchLoggingOptions but ignored since the field is a parameters field
there are 1 fields that could be observation type of .KinesisAnalyticsApplication.Inputs.Schema.RecordFormat but ignored since the field is a parameters field
there are 2 fields that could be observation type of .KinesisAnalyticsApplication.Inputs but ignored since the field is a parameters field
there are 1 fields that could be observation type of .KinesisAnalyticsApplication.Outputs but ignored since the field is a parameters field
there are 1 fields that could be observation type of .KinesisAnalyticsApplication.ReferenceDataSources.Schema.RecordFormat but ignored since the field is a parameters field
there are 1 fields that could be observation type of .KinesisAnalyticsApplication.ReferenceDataSources but ignored since the field is a parameters field
there are 1 fields that could be observation type of .KinesisFirehoseDeliveryStream.ElasticsearchConfiguration.VpcConfig but ignored since the field is a parameters field
there are 1 fields that could be observation type of .GlueCatalogTable.PartitionIndex but ignored since the field is a parameters field
Generated 770 resources!
There are thousands of fields generated for 770 resources, so problem is not that big, at least for AWS. We see that almost all ignored ones are the ones that exist under a parameters type but should've gone to observation. So, the problem does not cause much miss in the configuration ability of the users but there is information they'd not be able to see under status.
How could Terrajet help solve your problem?
There can be several solutions. The most basic one is to have the full schema in both status and spec but that'd mean deviation from Crossplane Resource Model even if unused fields will stay empty and it's not really worth doing this for all resources to be correct for minority cases.
The best solution would be the one that would construct the earlier fields and types under status once we encounter an observational type under a parameter type (and vice versa). However, it's not done in the first iteration since the field path wasn't known by the schema builder. With #24 it will know the path.
So, we could possibly have the type map be a more complex tree with some utilities that will allow you to add a certain field to an arbitrary point and construct the path from the root to that leaf by building the necessary types & fields. Right now, it has the list of types for uniqueness purposes but the actual information is recursively saved in the Go type objects. So this solution would mean we'd deviate from the Go types package to store the information and that'd require some refactoring.
I'd propose that we can have a utility that will work on Go types library objects to manipulate the existing type trees to add arbitrary field to a field path. There would be a function that knows the root types and when you give it an arbitrary field information, it'd construct the path in the either of the two root structs (parameters and observation). There are some caveats about naming of those new fields and types but it's doable and lets us still be in the same type system instead of building our own.