Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache Ruleset panics when import #1006

Closed
7onn opened this issue Dec 16, 2024 · 8 comments
Closed

Cache Ruleset panics when import #1006

7onn opened this issue Dec 16, 2024 · 8 comments
Assignees
Labels
impact/panic This bug represents a panic or unexpected crash kind/bug Some behavior is incorrect or out of spec p1 A bug severe enough to be the next item assigned to an engineer resolution/fixed This issue was fixed

Comments

@7onn
Copy link

7onn commented Dec 16, 2024

Describe what happened

I'm on a task of covering CloudFlare configuration under IaC using Pulumi, and I have this block of code where I parse the RulesetRule[] out of an input yaml config file which crashes due to panic: runtime error: invalid memory address or nil pointer dereference. This is weird, as I'm imitating the current config values that I got from CloudFlare API and the config properties that I got from the docs:

# get rulesets
$ curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets?per_page=200" -H "Authorization: Bearer <cloudflare-api-token>" -H "Content-Type: application/json" 
...
{
  "result": [
    {
      "description": "",
      "id": "5d85d2e2b1404e0fb6aa9cfd89aabe0d",
      "kind": "zone",
      "last_updated": "2024-12-03T13:29:35.474735Z",
      "name": "default",
      "phase": "http_request_cache_settings",
      "version": "76"
    },
  ]
}
...

# get rules
$ curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets/5d85d2e2b1404e0fb6aa9cfd89aabe0d?per_page=200" -H "Authorization: Bearer <cloudflare-api-token>" -H "Content-Type: application/json" 
...
{
  "result": {
    "description": "",
    "id": "5d85d2e2b1404e0fb6aa9cfd89aabe0d",
    "kind": "zone",
    "last_updated": "2024-12-03T13:29:35.474735Z",
    "name": "default",
    "phase": "http_request_cache_settings",
    "rules": [
      {
        "action": "set_cache_settings",
        "action_parameters": {
          "cache": true,
          "edge_ttl": {
            "mode": "respect_origin",
            "status_code_ttl": [
              {
                "status_code_range": {
                  "from": 400,
                  "to": 599
                },
                "value": -1
              }
            ]
          }
        },
        "description": "Image Proxy CloudFront distribution",
        "enabled": true,
        "expression": "(http.host eq \"edge.example.com\") or (http.host eq \"edge-s.example.com\") or (http.host eq \"cache.example.com\")",
        "id": "5f4b97abd5104bdfbd10ed9803f6c42b",
        "last_updated": "2024-09-05T14:55:34.931444Z",
        "ref": "5f4b97abd5104bdfbd10ed9803f6c42b",
        "version": "43"
      },

This approach worked nicely for WAF rules and DNS records, but for cache rules, the provider panicked for some reason, which I cannot figure out why. I hope some help can come from this issue.

Sample program

A configuration Pulumi.yaml like the following:

name: cloudflare-domains
runtime: nodejs
description: Pulumi typescript code to manage CloudFlare infrastructure resources
config:
  pulumi:tags:
    value:
      pulumi:template: aws-typescript
environment:
  - staging
config:
  cloudflareZoneId: <zone-id>
  cacheRules:
  - description: "Image Proxy CloudFront distribution"
    action: "set_cache_settings"
    expression: (http.host eq "edge.example.com") or (http.host eq "edge-s.example.com") or (http.host eq "cache.example.com")
    actionParameters:
        cache: true
        edgeTtl:
          mode: "respect_origin"
          statusCodeTtls:
          - statusCodeRanges:
            - from: 400
              to: 599
            value: -1

  - description: "API"
    action: "set_cache_settings"
    expression: (http.host wildcard "api.example.com") and (http.request.uri.path contains "/templates/usecase/all" or http.request.uri.path contains "/templates/tags/groups/all")
    actionParameters:
        cache: true
        edgeTtl:
          mode: "respect_origin"
        browserTtl:
          default: 43200
          mode: "override_origin"

  - description: "Next image"
    action: "set_cache_settings"
    expression: (http.host eq "www.example.com" and http.request.uri.path eq "/_next/image") 
    actionParameters:
        cache: true
        serveStale: {}
        edgeTtl:
          default: 604800
          mode: "override_origin"
          statusCodeTtls:
          - statusCodeRanges:
            - from: 400
              to: 599
            value: -1

  - description: "CDN Full"
    action: "set_cache_settings"
    expression: (http.host eq "cdn.example.com") 
    actionParameters:
        cache: true
        edgeTtl:
          mode: "respect_origin"
          statusCodeTtls:
          - statusCodeRanges:
            - from: 400
              to: 599
            value: -1

  - description: "Bypass Cache for Tunnels"
    action: "set_cache_settings"
    expression: (http.host in {"xyz.example.com"})
    actionParameters:
        cache: false

A typescript program to parse the cacheRules property to RulesetRule[] and forward to my cache settings Ruleset.

// ./src/cache.ts

import { Ruleset } from '@pulumi/cloudflare';
import { Config } from '@pulumi/pulumi';
import { cloudflareProvider as provider } from './provider';
import { RulesetRule } from '@pulumi/cloudflare/types/input';

export const createCacheRules = async () => {
  const pulumiConfig = new Config();
  const zoneId = pulumiConfig.require('cloudflareZoneId');
  const rules = pulumiConfig.requireObject('cacheRules') as RulesetRule[]

  new Ruleset(
  `ruleset/http_request_cache_settings`,
  {
    zoneId,
    rules,
    kind: 'zone',
    name: 'default',
    phase: 'http_request_cache_settings',
  },
  { 
    provider,
    import:
      "zone/<my-zone>/5d85d2e2b1404e0fb6aa9cfd89aabe0d"
  }
);

The app Pulumi app src/index.ts

//import { createDnsRecords } from './records'
//import { createWAFRules } from  './waf'
import { createCacheRules } from './cache'

//createDnsRecords()
//createWAFRules()
createCacheRules()

The app package JSON.

{
    "name": "cloudflare-domains",
    "version": "1.0.0",
    "main": "src/index.ts",
    "devDependencies": {
        "@types/node": "^18",
        "typescript": "^5.0.0"
    },
    "dependencies": {
        "@pulumi/cloudflare": "^5.45.0",
        "@pulumi/pulumi": "^3.143.0",
        "lint-staged": "^15.2.2",
        "zod": "^3.24.1"
    }
}

Log output

 panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7409692]
    goroutine 135 [running]:
    github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/rulesets.toRulesetResourceModel({0x8774bd8, 0xc001f24570}, {0x70?, {0xc0024f6d80?, 0xc0024f6d60?}}, {0x20?, {0x0?, 0x0?}}, {{0xc0006ea632, 0x20}, ...})
        /home/runner/work/pulumi-cloudflare/pulumi-cloudflare/upstream/internal/framework/service/rulesets/resource.go:627 +0x3cd2
    github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/rulesets.(*RulesetResource).Read(0xc0010b0210, {0x8774bd8, 0xc001f24570}, {{{{0x8783818, 0xc001f85dd0}, {0x7fef580, 0xc001f84d50}}, {0x878d340, 0xc00118cff0}}, 0xc0010b0220, ...}, ...)
        /home/runner/work/pulumi-cloudflare/pulumi-cloudflare/upstream/internal/framework/service/rulesets/resource.go:206 +0x519
    github.com/hashicorp/terraform-plugin-framework/internal/fwserver.(*Server).ReadResource(0xc0019466c8, {0x8774bd8, 0xc001f24570}, 0xc001f245a0, 0xc001fdb148)
        /home/runner/go/pkg/mod/github.com/hashicorp/[email protected]/internal/fwserver/server_readresource.go:117 +0x84e
    github.com/hashicorp/terraform-plugin-framework/internal/proto6server.(*Server).ReadResource(0xc0019466c8, {0x8774bd8?, 0xc00270cba0?}, 0xc000fc5640)
        /home/runner/go/pkg/mod/github.com/hashicorp/[email protected]/internal/proto6server/server_readresource.go:55 +0x38e
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge.(*provider).readResource(0xc000c26a88, {0x8774bd8, 0xc00270cba0}, 0xc001fdb3d0, 0x0?)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/tfbridge/provider_read.go:151 +0x393
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge.(*provider).importResource(0xc000c26a88, {0x8774bd8, 0xc00270cba0}, 0xc0000673d0, {0xc001d5e1e0, 0x46})
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/tfbridge/provider_read.go:266 +0x230
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge.(*provider).ReadWithContext(0xc000c26a88, {0x8774bd8?, 0xc00270c720?}, {0xc001d60280, 0x79}, {0xc001d5e1e0, 0x46}, 0xc00270c780, 0xc00270c750)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/tfbridge/provider_read.go:68 +0x268
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/internal/plugin.(*providerServer).Read(0xc0017d5b00, {0x8774bd8, 0xc00270c720}, 0xc00149c480)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/internal/plugin/provider_server.go:421 +0x184
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer.(*muxer).Read.func1({0x87982e0?, 0xc0017d5b00?})
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/x/muxer/muxer.go:382 +0x33
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer.resourceMethod[...](0xc0011938c0?, 0x856ab20, 0xc0012836b8?)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/x/muxer/muxer.go:335 +0xb5
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer.(*muxer).Read(0xa01cef0?, {0x8774bd8?, 0xc00270c720?}, 0x7dfc980?)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/x/muxer/muxer.go:381 +0x4a
    github.com/pulumi/pulumi/sdk/v3/proto/go._ResourceProvider_Read_Handler.func1({0x8774bd8?, 0xc00270c720?}, {0x84b8640?, 0xc00149c480?})
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi/sdk/[email protected]/proto/go/provider_grpc.pb.go:833 +0xce
    github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc.OpenTracingServerInterceptor.func1({0x8774bd8, 0xc00270c450}, {0x84b8640, 0xc00149c480}, 0xc0016f44e0, 0xc0016f2750)
        /home/runner/go/pkg/mod/github.com/grpc-ecosystem/[email protected]/go/otgrpc/server.go:57 +0x3c4
    github.com/pulumi/pulumi/sdk/v3/proto/go._ResourceProvider_Read_Handler({0x86beb40, 0xc0011938c0}, {0x8774bd8, 0xc00270c450}, 0xc00149c400, 0xc00108ec80)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi/sdk/[email protected]/proto/go/provider_grpc.pb.go:835 +0x143
    google.golang.org/grpc.(*Server).processUnaryRPC(0xc001033800, {0x8774bd8, 0xc00270c3c0}, {0x8789000, 0xc0000d0b60}, 0xc0016a5440, 0xc0017d5b90, 0xa050950, 0x0)
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1394 +0xe2b
    google.golang.org/grpc.(*Server).handleStream(0xc001033800, {0x8789000, 0xc0000d0b60}, 0xc0016a5440)
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1805 +0xe8b
    google.golang.org/grpc.(*Server).serveStreams.func2.1()
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1029 +0x7f
    created by google.golang.org/grpc.(*Server).serveStreams.func2 in goroutine 43
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1040 +0x125

    error: preview failed

Affected Resource(s)

Cloudflare Cache Ruleset

Output of pulumi about

Here's my env info

$ pulumi about
...
CLI          
Version      3.142.0
Go Version   go1.23.3
Go Compiler  gc

Plugins
KIND      NAME    VERSION
language  nodejs  unknown

Host     
OS       darwin
Version  14.6
Arch     x86_64

This project is written in nodejs: executable='/Users/tom/.nvm/versions/node/v18.20.5/bin/node' version='v18.20.5'

Current Stack: <org>/cloudflare-domains/example-com

TYPE                              URN
pulumi:pulumi:Stack               urn:pulumi:example-com::cloudflare-domains::pulumi:pulumi:Stack::cloudflare-domains-example-com
pulumi:providers:cloudflare       urn:pulumi:example-com::cloudflare-domains::pulumi:providers:cloudflare::cloudflare
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/opensearch-v2-metrics
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-imageproxy
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-preview
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-ses-dkim-2
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-cms-ui
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-objects.api
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-content
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-objects.cms
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-cdn.s
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-web
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-app
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-cdn-s
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-opensearch
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::A/vercel-frontend
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-ses-dkim-3
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/heroku-analytics-app
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-ses-dkim
cloudflare:index/ruleset:Ruleset  urn:pulumi:example-com::cloudflare-domains::cloudflare:index/ruleset:Ruleset::ruleset/http_request_firewall_custom
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-qa
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-image-proxy-s
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::TXT/amazon-ses
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-opensearch-v2-metrics
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-objects.api.development
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::TXT/aws-ses
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::TXT/google-site-verification
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-opensearch-v2
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::MX/smtp-from-amazon
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/opensearch-v2
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::TXT/domain-based-message-auth-reporting-and-conformance
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-qa-assignment
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/vercel-frontend-www
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-cdn
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/opensearch
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record-objects-cms-development
cloudflare:index/record:Record    urn:pulumi:example-com::cloudflare-domains::cloudflare:index/record:Record::CNAME/aws-acm-validation-record


Dependencies:
NAME                              VERSION
@types/node                       18.19.64
@typescript-eslint/eslint-plugin  7.18.0
@typescript-eslint/parser         7.18.0
eslint                            8.57.1
eslint-config-prettier            9.1.0
eslint-plugin-import              2.31.0
eslint-plugin-prettier            5.2.1
husky                             8.0.3
lint-staged                       15.2.10
prettier                          3.4.2
typescript                        5.6.3
typescript-eslint                 7.18.0

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

@7onn 7onn added kind/bug Some behavior is incorrect or out of spec needs-triage Needs attention from the triage team labels Dec 16, 2024
@7onn 7onn changed the title Default Cache Ruleset panics when import Cache Ruleset panics when import Dec 16, 2024
@guineveresaenger guineveresaenger added impact/panic This bug represents a panic or unexpected crash p1 A bug severe enough to be the next item assigned to an engineer and removed needs-triage Needs attention from the triage team p1 A bug severe enough to be the next item assigned to an engineer labels Dec 16, 2024
@guineveresaenger
Copy link
Contributor

guineveresaenger commented Dec 16, 2024

Hi @7onn, thank you for reporting this. You certainly shouldn't be seeing your program panic.

Thank you for supplying code snippets - however, I'm struggling a bit with a repro because you have a bit of configuration setup - specifically, if I'm reading this correctly, an existing Ruleset?

Would it be possible for you to supply us with a fully contained minimal repro? For something with multiple files like this, a repository might be best. Thanks in advance!

@guineveresaenger guineveresaenger added the awaiting-feedback Blocked on input from the author label Dec 16, 2024
@7onn
Copy link
Author

7onn commented Dec 17, 2024

It is hard to provide a fully reproducible environment because that would involve my PAT with privileges over my company's Cloudflare account. But to find the resources I'm trying to import, in Cloudflare, one can navigate to https://dash.cloudflare.com/<cloudflare-account-id>/<cloudflare-zone-name>/caching/cache-rules where we find the rules that belong to the Ruleset of phase "http_request_cache_settings". Then, to find its corresponding ID to use on the import code, the curl below should answer it.

$ curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets?per_page=200" -H "Authorization: Bearer <cloudflare-api-token>" -H "Content-Type: application/json" 
{
  "result": [
    {
      "description": "",
      "id": "5d85d2e2b1404e0fb6aa9cfd89aabe0d",
      "kind": "zone",
      "last_updated": "2024-12-03T13:29:35.474735Z",
      "name": "default",
      "phase": "http_request_cache_settings",
      "version": "76"
    },
  ],
  "success": true,
  "errors": [],
  "messages": []
}

Then, import this Ruleset in a typescript code.

import { Ruleset } from '@pulumi/cloudflare';
import { Config } from '@pulumi/pulumi';
import { cloudflareProvider as provider } from './provider';
import { RulesetRule } from '@pulumi/cloudflare/types/input';

const pulumiConfig = new Config();
const zoneId = pulumiConfig.require('cloudflareZoneId');
const rules = pulumiConfig.requireObject('cacheRules') as RulesetRule[]

new Ruleset(
`ruleset/http_request_cache_settings`,
{
  zoneId,
  rules,
  kind: 'zone',
  name: 'default',
  phase: 'http_request_cache_settings',
},
{ 
  provider,
  import:
    "zone/<my-zone>/5d85d2e2b1404e0fb6aa9cfd89aabe0d"
}
);

And feed it the YAML input provided in the Sample program section of this issue.

@pulumi-bot pulumi-bot added needs-triage Needs attention from the triage team and removed awaiting-feedback Blocked on input from the author labels Dec 17, 2024
@guineveresaenger guineveresaenger removed the needs-triage Needs attention from the triage team label Dec 17, 2024
@7onn
Copy link
Author

7onn commented Dec 18, 2024

I confirmed the same error is happening via CLI pulumi import and via the import property in the Ruleset's code parameters.

❯ pulumi import cloudflare:index/ruleset:Ruleset "ruleset/http_request_cache_settings" zone/<zone-id>/5d85d2e2b1404e0fb6aa9cfd89aabe0d --provider 'urn:pulumi:<stack>::cloudflare-domains::pulumi:providers:cloudflare::cloudflare'
...
Previewing import (<stack>)

     Type                         Name                                    Plan       Info
     pulumi:pulumi:Stack          cloudflare-domains-<stack>             1 error; 39 messages
 =   └─ cloudflare:index:Ruleset  ruleset/http_request_cache_settings     import     1 error

Diagnostics:
  cloudflare:index:Ruleset (ruleset/http_request_cache_settings):
    error: Preview failed: error reading from server: EOF

  pulumi:pulumi:Stack (cloudflare-domains-<stack>):
    error: preview failed

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x3710692]
    goroutine 53 [running]:
    github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/rulesets.toRulesetResourceModel({0x4a7bbd8, 0xc001dd23f0}, {0xf0?, {0xc0011ee0e0?, 0xc001077f80?}}, {0x20?, {0x0?, 0x0?}}, {{0xc001e3e032, 0x20}, ...})
        /home/runner/work/pulumi-cloudflare/pulumi-cloudflare/upstream/internal/framework/service/rulesets/resource.go:627 +0x3cd2
    github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/rulesets.(*RulesetResource).Read(0xc0000949e8, {0x4a7bbd8, 0xc001dd23f0}, {{{{0x4a8a818, 0xc001e09c50}, {0x42f6580, 0xc001e08bd0}}, {0x4a94340, 0xc001cf6820}}, 0xc0000949f8, ...}, ...)
        /home/runner/work/pulumi-cloudflare/pulumi-cloudflare/upstream/internal/framework/service/rulesets/resource.go:206 +0x519
    github.com/hashicorp/terraform-plugin-framework/internal/fwserver.(*Server).ReadResource(0xc0018da488, {0x4a7bbd8, 0xc001dd23f0}, 0xc001dd2420, 0xc001d07148)
        /home/runner/go/pkg/mod/github.com/hashicorp/[email protected]/internal/fwserver/server_readresource.go:117 +0x84e
    github.com/hashicorp/terraform-plugin-framework/internal/proto6server.(*Server).ReadResource(0xc0018da488, {0x4a7bbd8?, 0xc0018c8720?}, 0xc001d10e00)
        /home/runner/go/pkg/mod/github.com/hashicorp/[email protected]/internal/proto6server/server_readresource.go:55 +0x38e
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge.(*provider).readResource(0xc001a6b188, {0x4a7bbd8, 0xc0018c8720}, 0xc001d073d0, 0x0?)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/tfbridge/provider_read.go:151 +0x393
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge.(*provider).importResource(0xc001a6b188, {0x4a7bbd8, 0xc0018c8720}, 0xc001d073d0, {0xc001a48050, 0x46})
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/tfbridge/provider_read.go:266 +0x230
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge.(*provider).ReadWithContext(0xc001a6b188, {0x4a7bbd8?, 0xc0018c8270?}, {0xc001b28280, 0x79}, {0xc001a48050, 0x46}, 0xc0018c8330, 0xc0018c82a0)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/tfbridge/provider_read.go:68 +0x268
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/internal/plugin.(*providerServer).Read(0xc00185cdb0, {0x4a7bbd8, 0xc0018c8270}, 0xc00149fd00)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/pf/internal/plugin/provider_server.go:421 +0x184
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer.(*muxer).Read.func1({0x4a9f2e0?, 0xc00185cdb0?})
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/x/muxer/muxer.go:382 +0x33
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer.resourceMethod[...](0xc0013bf800?, 0x4871b20, 0xc0015cf6b8?)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/x/muxer/muxer.go:335 +0xb5
    github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer.(*muxer).Read(0x6323ef0?, {0x4a7bbd8?, 0xc0018c8270?}, 0x4103980?)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/[email protected]/pkg/x/muxer/muxer.go:381 +0x4a
    github.com/pulumi/pulumi/sdk/v3/proto/go._ResourceProvider_Read_Handler.func1({0x4a7bbd8?, 0xc0018c8270?}, {0x47bf640?, 0xc00149fd00?})
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi/sdk/[email protected]/proto/go/provider_grpc.pb.go:833 +0xce
    github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc.OpenTracingServerInterceptor.func1({0x4a7bbd8, 0xc0018c1e60}, {0x47bf640, 0xc00149fd00}, 0xc001605620, 0xc0015dd6f8)
        /home/runner/go/pkg/mod/github.com/grpc-ecosystem/[email protected]/go/otgrpc/server.go:57 +0x3c4
    github.com/pulumi/pulumi/sdk/v3/proto/go._ResourceProvider_Read_Handler({0x49c5b40, 0xc0013bf800}, {0x4a7bbd8, 0xc0018c1e60}, 0xc00149fc80, 0xc00125cb80)
        /home/runner/go/pkg/mod/github.com/pulumi/pulumi/sdk/[email protected]/proto/go/provider_grpc.pb.go:835 +0x143
    google.golang.org/grpc.(*Server).processUnaryRPC(0xc000e2d000, {0x4a7bbd8, 0xc0018c1dd0}, {0x4a90000, 0xc001998000}, 0xc0013e2000, 0xc00185ce40, 0x6357950, 0x0)
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1394 +0xe2b
    google.golang.org/grpc.(*Server).handleStream(0xc000e2d000, {0x4a90000, 0xc001998000}, 0xc0013e2000)
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1805 +0xe8b
    google.golang.org/grpc.(*Server).serveStreams.func2.1()
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1029 +0x7f
    created by google.golang.org/grpc.(*Server).serveStreams.func2 in goroutine 26
        /home/runner/go/pkg/mod/google.golang.org/[email protected]/server.go:1040 +0x125

@guineveresaenger guineveresaenger added the p1 A bug severe enough to be the next item assigned to an engineer label Dec 18, 2024
@guineveresaenger guineveresaenger self-assigned this Dec 18, 2024
@guineveresaenger
Copy link
Contributor

thank you for the extra context and steps! We'll investigate.

@guineveresaenger
Copy link
Contributor

guineveresaenger commented Dec 20, 2024

Thank you for your patience. I've got a repro.

  1. Create a cache ruleset in the UI, with "Serve stale content while revalidating" enabled.
  2. GET the Ruleset via cURL:
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets/<ruleset-id>" -H "X-Auth-Email: <email>" -H "X-auth-Key: <apiKey>" -H "Content-Type: application/json"

{
  "result": {
    "description": "",
    "id": <ruleset-id>,
    "kind": "zone",
    "last_updated": "2024-12-20T00:03:28.5157Z",
    "name": "default",
    "phase": "http_request_cache_settings",
    "rules": [
      {
        "action": "set_cache_settings",
        "action_parameters": {
          "cache": true,
          "serve_stale": {
            "disable_stale_while_updating": true
          }
        },
        "description": "Test Cache Rule with serve stale enabled",
        "enabled": true,
        "expression": "true",
        "id": "<rule-id>",
        "last_updated": "2024-12-20T00:03:28.5157Z",
        "ref": "<some-ref>",
        "version": "1"
      }
    ],
    "version": "1"
  },
  "success": true,
  "errors": [],
  "messages": []
}
  1. You cannot GET individual cache rules, but you can PATCH them, now that we have the rule ID. Here, we update the Ruleset to have a new Description of "hello" and setting "serve_stale" to an empty object.
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets/<ruleset-id>/rules/<rule-id>" -H "X-Auth-Email: <email>" -H "X-auth-Key: <authKey>" -H "Content-Type: application/json" -d '{"description": "hello", "action": "set_cache_settings", "action_parameters":{"cache": true, "serve_stale": {}}, "expression": "true"}' 
{
  "result": {
    "description": "",
    "id": "c82753edaa9f45da8ddb60426e5f6a84",
    "kind": "zone",
    "last_updated": "2024-12-20T00:40:41.487287Z",
    "name": "default",
    "phase": "http_request_cache_settings",
    "rules": [
      {
        "action": "set_cache_settings",
        "action_parameters": {
          "cache": true,
          "serve_stale": {}
        },
        "description": "hello",
        "enabled": true,
        "expression": "true",
        "id": "<rule-id>",
        "last_updated": "2024-12-20T00:40:41.487287Z",
        "ref": "<some-ref>",
        "version": "2"
      }
    ],
    "version": "2"
  },
  "success": true,
  "errors": [],
  "messages": []
}
  1. Run pulumi import cloudflare:index/ruleset:Ruleset "ruleset/http_request_cache_settings" zone/<zone-id>/<ruleset-id>

This results in the same error.

It looks like one or more of your Rules somehow have an empty/nil serve_stale object, and this causes this line of code to panic.

This should of course not happen - but it is very likely an upstream Terraform bug. It would be interesting to see how your Rule got into this state; I kind of forced the issue using cURL and the API. I'll see if I can repro this using Terraform import and file a bug upstream.

To unblock you for now, I'd recommend using PATCH to set the offending serve_stale field to a valid non-empty value (removing it should work as well if you want to default) and trying again. I could not see my way to setting this value to empty via the Cloudflare UI; this doesn't mean it's impossible. Perhaps, too, during an upgrade this resource got into a wonky state.

Please let us know how it goes, or if our guess here is off!

@7onn
Copy link
Author

7onn commented Dec 20, 2024

I had gone to this line bc of the stack trace, and I even tried to set the serveStale object in all entries of my YAML. But still, that was breaking! Your workaround might fit perfectly for me! I'll try to patch them via curl -X PATCH forcing this property on the payload before importing via Pulumi! Will let you know asap!

Thanks a lot for the explanation <3

update:

After patching all cache rules like

curl -s -X PATCH \
"https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets/5d85d2e2b1404e0fb6aa9cfd89aabe0d/rules/5f4b97abd5104bdfbd10ed9803f6c42b" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '
{
  "id": "5f4b97abd5104bdfbd10ed9803f6c42b",
  "action": "set_cache_settings",
  "description": "Image Proxy CloudFront distribution",
  "expression": "<redacted>",
  "action_parameters":{"serve_stale": {"disable_stale_while_updating": false}}}
'

It did work! I'm able to import my resources in Pulumi now! I hope terraform folks fix that though :) Although I don't understand, this check here was resulting true even with the property missing 🤔 How could it not be nil?

@guineveresaenger
Copy link
Contributor

guineveresaenger commented Dec 20, 2024

I'm so glad to see that the workaround was successful! 😀

I've verified the import fails using Terraform as well and filed cloudflare/terraform-provider-cloudflare#4813 upstream.

Although I don't understand, this check here was resulting true even with the property missing 🤔 How could it not be nil?

Not sure yet! Still working on a fix. A couple options:

  • the serve_stale property is falsely assumed to have the disable_state_while_updating field when it is not nil
  • the serve stale property is not actually nil
  • there's some defaults that are interfering with the correct behavior from the API

@guineveresaenger guineveresaenger added awaiting-upstream The issue cannot be resolved without action in another repository (may be owned by Pulumi). resolution/fixed This issue was fixed and removed awaiting-upstream The issue cannot be resolved without action in another repository (may be owned by Pulumi). labels Dec 30, 2024
@guineveresaenger
Copy link
Contributor

This bug is fixed upstream via cloudflare/terraform-provider-cloudflare#4814 and the correct behavior will be available with the next upstream release/upgrade of this provider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
impact/panic This bug represents a panic or unexpected crash kind/bug Some behavior is incorrect or out of spec p1 A bug severe enough to be the next item assigned to an engineer resolution/fixed This issue was fixed
Projects
None yet
Development

No branches or pull requests

3 participants