Implementa suporte a campos bool com default value#22
Conversation
Os campos dentro do validations do bool/v1 são obrigatório. A implementação do bool/v1 espera que eles existam.
| output "schema" { | ||
| value = { | ||
| type = "object" | ||
| version = "v1" |
There was a problem hiding this comment.
Porque você está adicionando versões diferentes para o object se apenas a lógica do bool será alterada nesse PR? Você fez isso para os outros tipos também.
There was a problem hiding this comment.
O que observei foi o seguinte:
A implementação do object/v0 não permite que um campo não exista no var.manifest que está chegando, pois ele faz esse check com o local.missing_properties. Já o object/v1 é mais frouxo nessa validação e permite que alguns campos não existam no manifest, pois sabe que alguins deles terão seus valores preenchidos com um valor padão.
Depois que tivermos todos os tipos de campos podendo ter default values, as duas implementações voltarão a ser iguals e poderemos unificar novamente. Acho inclusive que poderemos remover completamente a lógica do local.missing_properties.
| condition = !( | ||
| local.declared_default_field && try(var.manifest.default, null) == null | ||
| ) |
There was a problem hiding this comment.
Aqui não deveria ser tem declaração do default e o default for diferente de null ou não tem declaração do default (condition = (local.declared_default_field && try(var.manifest.default, null) != null) || !local.declared_default_field ?
There was a problem hiding this comment.
Se colocarmos essa validação (a parte final depois do ||), quando o campo default não for declarado teremos um erro, certo?
Se de fato isso acontecer estaremos tornando a presença do campo default obrigatória, mas declarar ou não um valor default para um campo deveria ser opcional.
A ideia da validação como ela está agora é: "Se um valor default tiver sido declarado, ele não pode ser ``"null".
Faz sentido?
(Posso tentar escrever um teste pra confirmar esse meu pensamento depois)
Outro ponto: Se tirarmos a parte final do "or" nossas expressões são equivalente (eu acho). O que eu geralmente faço, pois acho mais simples de entender, é colocar entre parentes a condição que não podemos ter, e depois faço a negação disso. A negação existe pois o teste falha quando a condition é false e não true.
| #condition = local.has_default_value || var.manifest != null | ||
| condition = !( | ||
| !local.has_default_value && var.manifest == null | ||
| ) |
There was a problem hiding this comment.
Faltou remover o comentário.
Aqui não deveria ser tem o default ou não tem default e o manifest é diferente de null (condition = local.has_default_value || (!local.has_default_value && var.manifest != null)`)?
There was a problem hiding this comment.
Feito. 4eab358
Sobre a condição, elas são equivalentes, apenas uma está negada e outra não. O que faço aqui é, ter entre parenteses, a condição que representa o erro e depois eu faço a negação de tudo. Faço isso para que fique mais claro a condição que não queremos ter, e a negação final existe pela forma como o teste terraform funciona (quebrando quando a condition é false).
| subItem = null | ||
| validations = { | ||
| has_default_value = can(var.manifest.default) ? true : false | ||
| default_value = try(var.manifest.default, null) |
There was a problem hiding this comment.
O schema deveria carregar o campo já em seu valor final. Com isso em mente, a validação se o campo default possui um valor válido, deveria estar aqui.
| default_value = try(var.manifest.default, null) | |
| default_value = try(tobool(var.manifest.default), null) |
There was a problem hiding this comment.
| precondition { | ||
| condition = local.has_compatible_default_value | ||
| error_message = <<-EOT | ||
| Invalid resource manifest! | ||
| The default value of the property "${var.field_path}" must be compatible with type bool. | ||
| Current default value: ${format("%v", var.schema.validations.default_value)} | ||
| (metadata.name: "${var.metadata_name}"; path: "${var.path}") | ||
| EOT | ||
| } |
There was a problem hiding this comment.
Essa validação deveria estar no processamento do CRD e não no processamento do manifesto final.
| locals { | ||
| has_default_value = var.schema.validations.has_default_value | ||
| has_compatible_default_value = can(tobool(var.schema.validations.default_value)) | ||
|
|
||
| default_value = local.has_compatible_default_value ? tobool(var.schema.validations.default_value) : false | ||
|
|
||
| has_valid_value = var.manifest != null && can(tobool(var.manifest)) | ||
| final_default_value = local.has_compatible_default_value ? local.default_value : try(tobool(var.manifest), null) | ||
|
|
||
|
|
||
| } |
There was a problem hiding this comment.
Se o schema vier com o campo default já validado e transformado em seu valor final, essa lógica inteira se faz desnecessária, ficando bem mais simples de saber o valor final.
lukerops
left a comment
There was a problem hiding this comment.
Só ajuste da mensagem de erro. Mas de resto, acho que está OK.
| The default value a bool field can't be null; | ||
| The filed ${var.field_path} has it's default value set to null. |
There was a problem hiding this comment.
| The default value a bool field can't be null; | |
| The filed ${var.field_path} has it's default value set to null. | |
| The default value of a bool field can't be null; | |
| The field "${var.field_path}" has it's default value set to null. |
Implementa suporte a default values para camposs boolean.
ref: #16
Tarefas
default: 42para um campotype: booldefault: nullpara um campotype: bool