Skip to content

Commit

Permalink
Add terraform mapping to k8s provider
Browse files Browse the repository at this point in the history
This returns a basic mapping description for the terraform converter to
map terraform programs using
https://registry.terraform.io/providers/hashicorp/kubernetes to our
kubernetes provider, even though it's not bridged.

I grabbed a list of all terraform kubernetes resources by running
`terraform providers schema -json` in a tiny terraform program that just
defined a kubernetes provider. I've then manually mapped that resource
list best I can to our type tokens.
  • Loading branch information
Frassle committed Jun 14, 2023
1 parent 891740e commit 56caba6
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ sdk/java/.gradle
sdk/java/gradle
sdk/java/gradlew
sdk/java/gradlew.bat

go.work
go.work.sum
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,11 @@ lint::
pushd $$DIR && golangci-lint run -c ../.golangci.yml --timeout 10m && popd ; \
done

install:: install_nodejs_sdk install_dotnet_sdk
install_provider::
cp $(WORKING_DIR)/bin/${PROVIDER} ${GOPATH}/bin

install:: install_nodejs_sdk install_dotnet_sdk install_provider

GO_TEST_FAST := go test -short -v -count=1 -cover -timeout 2h -parallel ${TESTPARALLELISM}
GO_TEST := go test -v -count=1 -cover -timeout 2h -parallel ${TESTPARALLELISM}

Expand Down
131 changes: 129 additions & 2 deletions provider/pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,135 @@ func (k *kubeProvider) Call(ctx context.Context, req *pulumirpc.CallRequest) (*p

// GetMapping fetches the mapping for this resource provider, if any. A provider should return an empty
// response (not an error) if it doesn't have a mapping for the given key.
func (k *kubeProvider) GetMapping(ctx context.Context, req *pulumirpc.GetMappingRequest) (*pulumirpc.GetMappingResponse, error) {
return nil, status.Error(codes.Unimplemented, "GetMapping is not yet implemented")
func (k *kubeProvider) GetMapping(ctx context.Context, request *pulumirpc.GetMappingRequest) (*pulumirpc.GetMappingResponse, error) {
// We only return a mapping for terraform
if request.Key != "terraform" {
// an empty response means no mapping, by design we don't return an error here
return &pulumirpc.GetMappingResponse{}, nil
}

// The terraform converter expects the mapping to be the JSON serialization of it's ProviderInfo
// structure. We can get away with returning a _very_ limited subset of the information here, since the
// converter only cares about a few fields and is tolerant of missing fields.

resourceTokens := map[string]string{
"kubernetes_annotations": "",
"kubernetes_api_service": "kubernetes:apiregistration.k8s.io/v1beta1:APIService",
"kubernetes_api_service_v1": "kubernetes:apiregistration.k8s.io/v1:APIService",
"kubernetes_certificate_signing_request": "kubernetes:certificates.k8s.io/v1beta1:CertificateSigningRequest",
"kubernetes_certificate_signing_request_v1": "kubernetes:certificates.k8s.io/v1:CertificateSigningRequest",
"kubernetes_cluster_role": "kubernetes:rbac.authorization.k8s.io/v1beta1:ClusterRole",
"kubernetes_cluster_role_v1": "kubernetes:rbac.authorization.k8s.io/v1:ClusterRole",
"kubernetes_cluster_role_binding": "kubernetes:rbac.authorization.k8s.io/v1beta1:ClusterRoleBinding",
"kubernetes_cluster_role_binding_v1": "kubernetes:rbac.authorization.k8s.io/v1:ClusterRoleBinding",
"kubernetes_config_map": "kubernetes:core/v1beta1:ConfigMap",
"kubernetes_config_map_v1": "kubernetes:core/v1:ConfigMap",
"kubernetes_config_map_v1_data": "",
"kubernetes_cron_job": "kubernetes:batch/v1beta1:CronJob",
"kubernetes_cron_job_v1": "kubernetes:batch/v1:CronJob",
"kubernetes_csi_driver": "kubernetes:storage.k8s.io/v1beta1:CSIDriver",
"kubernetes_csi_driver_v1": "kubernetes:storage.k8s.io/v1:CSIDriver",
"kubernetes_daemonset": "kubernetes:apps/v1:DaemonSet",
"kubernetes_daemon_set_v1": "kubernetes:apps/v1:DaemonSet",
"kubernetes_default_service_account": "",
"kubernetes_default_service_account_v1": "",
"kubernetes_deployment": "kubernetes:extensions/v1beta1:Deployment",
"kubernetes_deployment_v1": "kubernetes:apps/v1:Deployment",
"kubernetes_endpoints": "",
"kubernetes_endpoints_v1": "kubernetes:core/v1:Endpoints",
"kubernetes_env": "",
"kubernetes_horizontal_pod_autoscaler": "kubernetes:autoscaling/v2beta1:HorizontalPodAutoscaler",
"kubernetes_horizontal_pod_autoscaler_v1": "kubernetes:autoscaling/v1:HorizontalPodAutoscaler",
"kubernetes_horizontal_pod_autoscaler_v2": "kubernetes:autoscaling/v2:HorizontalPodAutoscaler",
"kubernetes_horizontal_pod_autoscaler_v2beta2": "kubernetes:autoscaling/v2beta2:HorizontalPodAutoscaler",
"kubernetes_ingress": "kubernetes:extensions/v1beta1:Ingress",
"kubernetes_ingress_v1": "kubernetes:networking.k8s.io/v1:Ingress",
"kubernetes_ingress_class": "kubernetes:networking.k8s.io/v1beta1:IngressClass",
"kubernetes_ingress_class_v1": "kubernetes:networking.k8s.io/v1:IngressClass",
"kubernetes_job": "kubernetes:batch/v1:Job",
"kubernetes_job_v1": "kubernetes:batch/v1:Job",
"kubernetes_labels": "",
"kubernetes_limit_range": "kubernetes:core/v1:LimitRange",
"kubernetes_limit_range_v1": "kubernetes:core/v1:LimitRange",
"kubernetes_manifest": "",
"kubernetes_mutating_webhook_configuration": "kubernetes:admissionregistration.k8s.io/v1beta1:MutatingWebhookConfiguration",
"kubernetes_mutating_webhook_configuration_v1": "kubernetes:admissionregistration.k8s.io/v1:MutatingWebhookConfiguration",
"kubernetes_namespace": "kubernetes:core/v1:Namespace",
"kubernetes_namespace_v1": "kubernetes:core/v1:Namespace",
"kubernetes_network_policy": "kubernetes:extensions/v1beta1:NetworkPolicy",
"kubernetes_network_policy_v1": "kubernetes:networking.k8s.io/v1:NetworkPolicy",
"kubernetes_node_taint": "",
"kubernetes_persistent_volume": "kubernetes:core/v1:PersistentVolume",
"kubernetes_persistent_volume_v1": "kubernetes:core/v1:PersistentVolume",
"kubernetes_persistent_volume_claim": "kubernetes:core/v1:PersistentVolumeClaim",
"kubernetes_persistent_volume_claim_v1": "kubernetes:core/v1:PersistentVolumeClaim",
"kubernetes_pod": "kubernetes:core/v1:Pod",
"kubernetes_pod_v1": "kubernetes:core/v1:Pod",
"kubernetes_pod_disruption_budget": "kubernetes:policy/v1beta1:PodDisruptionBudget",
"kubernetes_pod_disruption_budget_v1": "kubernetes:policy/v1:PodDisruptionBudget",
"kubernetes_pod_security_policy": "kubernetes:policy/v1beta1:PodSecurityPolicy",
"kubernetes_pod_security_policy_v1beta1": "kubernetes:policy/v1beta1:PodSecurityPolicy",
"kubernetes_priority_class": "kubernetes:scheduling.k8s.io/v1alpha1:PriorityClass",
"kubernetes_priority_class_v1": "kubernetes:scheduling.k8s.io/v1:PriorityClass",
"kubernetes_replication_controller": "kubernetes:core/v1:ReplicationController",
"kubernetes_replication_controller_v1": "kubernetes:core/v1:ReplicationController",
"kubernetes_resource_quota": "kubernetes:core/v1:ResourceQuota",
"kubernetes_resource_quota_v1": "kubernetes:core/v1:ResourceQuota",
"kubernetes_role": "kubernetes:rbac.authorization.k8s.io/v1alpha1:Role",
"kubernetes_role_v1": "kubernetes:rbac.authorization.k8s.io/v1:Role",
"kubernetes_role_binding": "kubernetes:rbac.authorization.k8s.io/v1alpha1:RoleBinding",
"kubernetes_role_binding_v1": "kubernetes:rbac.authorization.k8s.io/v1beta1:RoleBinding",
"kubernetes_runtime_class_v1": "kubernetes:node.k8s.io/v1:RuntimeClass",
"kubernetes_secret": "kubernetes:core/v1:Secret",
"kubernetes_secret_v1": "kubernetes:core/v1:Secret",
"kubernetes_service": "kubernetes:core/v1:Service",
"kubernetes_service_v1": "kubernetes:core/v1:Service",
"kubernetes_service_account": "kubernetes:core/v1:ServiceAccount",
"kubernetes_service_account_v1": "kubernetes:core/v1:ServiceAccount",
"kubernetes_stateful_set": "kubernetes:apps/v1beta2:StatefulSet",
"kubernetes_stateful_set_v1": "kubernetes:apps/v1:StatefulSet",
"kubernetes_storage_class": "kubernetes:storage.k8s.io/v1beta1:StorageClass",
"kubernetes_storage_class_v1": "kubernetes:storage.k8s.io/v1:StorageClass",
"kubernetes_token_request_v1": "kubernetes:authentication.k8s.io/v1:TokenRequest",
"kubernetes_validating_webhook_configuration": "kubernetes:admissionregistration.k8s.io/v1beta1:MutatingWebhookConfiguration",
"kubernetes_validating_webhook_configuration_v1": "kubernetes:admissionregistration.k8s.io/v1:MutatingWebhookConfiguration",
}

resources := make(map[string]interface{})
for tftok, putok := range resourceTokens {
// Skip if the token is empty.
if putok == "" {
continue
}
resources[tftok] = map[string]interface{}{
"tok": putok,
"fields": map[string]interface{}{
"metadata": map[string]interface{}{
"maxItemsOne": true,
},
"spec": map[string]interface{}{
"maxItemsOne": true,
},
},
}
}

info := map[string]interface{}{
"name": "kubernetes",
"provider": map[string]interface{}{},
"resources": resources,
"dataSources": map[string]interface{}{},
}

data, err := json.Marshal(info)
if err != nil {
return nil, err
}

return &pulumirpc.GetMappingResponse{
Provider: "kubernetes",
Data: data,
}, nil
}

// Construct creates a new instance of the provided component resource and returns its state.
Expand Down

0 comments on commit 56caba6

Please sign in to comment.