github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/provisioner/graphqlizer_test.go (about)

     1  package provisioner
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/kyma-project/control-plane/components/provisioner/pkg/gqlschema"
     7  	"github.com/kyma-project/kyma-environment-broker/internal/ptr"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestKymaConfigToGraphQLAllParametersProvided(t *testing.T) {
    13  	// given
    14  	profile := gqlschema.KymaProfileProduction
    15  	strategy := gqlschema.ConflictStrategyReplace
    16  	fixInput := gqlschema.KymaConfigInput{
    17  		Version:          "966",
    18  		Profile:          &profile,
    19  		ConflictStrategy: &strategy,
    20  		Components: []*gqlschema.ComponentConfigurationInput{
    21  			{
    22  				Component: "pico",
    23  				Namespace: "bello",
    24  			},
    25  			{
    26  				Component:        "custom-component",
    27  				Namespace:        "bello",
    28  				ConflictStrategy: &strategy,
    29  				SourceURL:        ptr.String("github.com/kyma-incubator/custom-component"),
    30  			},
    31  			{
    32  				Component: "hakuna",
    33  				Namespace: "matata",
    34  				Configuration: []*gqlschema.ConfigEntryInput{
    35  					{
    36  						Key:    "testing-secret-key",
    37  						Value:  "testing-secret-value",
    38  						Secret: ptr.Bool(true),
    39  					},
    40  					{
    41  						Key:   "testing-public-key",
    42  						Value: "testing-public-value\nmultiline",
    43  					},
    44  				},
    45  			},
    46  		},
    47  		Configuration: []*gqlschema.ConfigEntryInput{
    48  			{
    49  				Key:   "important-global-override",
    50  				Value: "false",
    51  			},
    52  			{
    53  				Key:    "ultimate.answer",
    54  				Value:  "42",
    55  				Secret: ptr.Bool(true),
    56  			},
    57  		},
    58  	}
    59  	expRender := `{
    60  		version: "966",
    61  		profile: Production,
    62  		conflictStrategy: Replace,
    63  		components: [
    64  			{
    65  				component: "pico",
    66  				namespace: "bello",
    67  			}
    68  			{
    69  				component: "custom-component",
    70  				namespace: "bello",
    71  				sourceURL: "github.com/kyma-incubator/custom-component",
    72  				conflictStrategy: Replace,
    73  			}
    74  			{
    75  				component: "hakuna",
    76  				namespace: "matata",
    77  				configuration: [
    78  					{
    79  						key: "testing-secret-key",
    80  						value: "testing-secret-value",
    81  						secret: true,
    82  					}
    83  					{
    84  						key: "testing-public-key",
    85  						value: "testing-public-value\nmultiline",
    86  					}
    87  				]
    88  			}
    89  		]
    90  		configuration: [
    91  			{
    92  				key: "important-global-override",
    93  				value: "false",
    94  			}
    95  			{
    96  				key: "ultimate.answer",
    97  				value: "42",
    98  				secret: true,
    99  			}
   100  		]
   101  	}`
   102  
   103  	sut := Graphqlizer{}
   104  
   105  	// when
   106  	gotRender, err := sut.KymaConfigToGraphQL(fixInput)
   107  
   108  	// then
   109  	require.NoError(t, err)
   110  
   111  	assert.Equal(t, expRender, gotRender)
   112  }
   113  
   114  func TestKymaConfigToGraphQLOnlyKymaVersionAndProfile(t *testing.T) {
   115  	// given
   116  	profile := gqlschema.KymaProfileEvaluation
   117  	fixInput := gqlschema.KymaConfigInput{
   118  		Version: "966",
   119  		Profile: &profile,
   120  	}
   121  	expRender := `{
   122  		version: "966",
   123  		profile: Evaluation,
   124  	}`
   125  
   126  	sut := Graphqlizer{}
   127  
   128  	// when
   129  	gotRender, err := sut.KymaConfigToGraphQL(fixInput)
   130  
   131  	// then
   132  	require.NoError(t, err)
   133  
   134  	assert.Equal(t, expRender, gotRender)
   135  }
   136  
   137  func Test_GardenerConfigInputToGraphQL(t *testing.T) {
   138  	// given
   139  	sut := Graphqlizer{}
   140  	exp := `{
   141  		name: "c-90a3016",
   142  		kubernetesVersion: "1.18",
   143  		volumeSizeGB: 50,
   144  		machineType: "Standard_D4_v3",
   145  		region: "europe",
   146  		provider: "Azure",
   147  		diskType: "Standard_LRS",
   148  		targetSecret: "scr",
   149  		workerCidr: "10.250.0.0/19",
   150  		autoScalerMin: 2,
   151  		autoScalerMax: 4,
   152  		maxSurge: 4,
   153  		maxUnavailable: 1,
   154  		enableKubernetesVersionAutoUpdate: true,
   155  		enableMachineImageVersionAutoUpdate: true,
   156  		controlPlaneFailureTolerance: "zone",
   157  		euAccess: true,
   158  		shootNetworkingFilterDisabled: true,
   159  	}`
   160  
   161  	// when
   162  	name := "c-90a3016"
   163  	got, err := sut.GardenerConfigInputToGraphQL(gqlschema.GardenerConfigInput{
   164  		Name:                                name,
   165  		Region:                              "europe",
   166  		VolumeSizeGb:                        ptr.Integer(50),
   167  		WorkerCidr:                          "10.250.0.0/19",
   168  		Provider:                            "Azure",
   169  		DiskType:                            ptr.String("Standard_LRS"),
   170  		TargetSecret:                        "scr",
   171  		MachineType:                         "Standard_D4_v3",
   172  		KubernetesVersion:                   "1.18",
   173  		AutoScalerMin:                       2,
   174  		AutoScalerMax:                       4,
   175  		MaxSurge:                            4,
   176  		MaxUnavailable:                      1,
   177  		EnableKubernetesVersionAutoUpdate:   ptr.Bool(true),
   178  		EnableMachineImageVersionAutoUpdate: ptr.Bool(true),
   179  		ControlPlaneFailureTolerance:        ptr.String("zone"),
   180  		EuAccess:                            ptr.Bool(true),
   181  		ShootNetworkingFilterDisabled:       ptr.Bool(true),
   182  	})
   183  
   184  	// then
   185  	require.NoError(t, err)
   186  	assert.Equal(t, exp, got)
   187  }
   188  
   189  func Test_GardenerConfigInputToGraphQLWithOIDC(t *testing.T) {
   190  	// given
   191  	sut := Graphqlizer{}
   192  	exp := `{
   193  		name: "c-90a3016",
   194  		kubernetesVersion: "1.18",
   195  		volumeSizeGB: 50,
   196  		machineType: "Standard_D4_v3",
   197  		region: "europe",
   198  		provider: "Azure",
   199  		diskType: "Standard_LRS",
   200  		targetSecret: "scr",
   201  		workerCidr: "10.250.0.0/19",
   202  		autoScalerMin: 0,
   203  		autoScalerMax: 0,
   204  		maxSurge: 0,
   205  		maxUnavailable: 0,
   206  		oidcConfig: {
   207  			clientID: "client-id",
   208  			issuerURL: "https://issuer.url",
   209  			groupsClaim: "",
   210  			signingAlgs: [],
   211  			usernameClaim: "",
   212  			usernamePrefix: "",
   213  		}
   214  		controlPlaneFailureTolerance: "node",
   215  	}`
   216  
   217  	// when
   218  	name := "c-90a3016"
   219  	got, err := sut.GardenerConfigInputToGraphQL(gqlschema.GardenerConfigInput{
   220  		Name:              name,
   221  		Region:            "europe",
   222  		VolumeSizeGb:      ptr.Integer(50),
   223  		WorkerCidr:        "10.250.0.0/19",
   224  		Provider:          "Azure",
   225  		DiskType:          ptr.String("Standard_LRS"),
   226  		TargetSecret:      "scr",
   227  		MachineType:       "Standard_D4_v3",
   228  		KubernetesVersion: "1.18",
   229  		OidcConfig: &gqlschema.OIDCConfigInput{
   230  			ClientID:       "client-id",
   231  			GroupsClaim:    "",
   232  			IssuerURL:      "https://issuer.url",
   233  			SigningAlgs:    nil,
   234  			UsernameClaim:  "",
   235  			UsernamePrefix: "",
   236  		},
   237  		ControlPlaneFailureTolerance: ptr.String("node"),
   238  	})
   239  
   240  	// then
   241  	require.NoError(t, err)
   242  	assert.Equal(t, exp, got)
   243  }
   244  
   245  func Test_GardenerConfigInputToGraphQLWithDNS(t *testing.T) {
   246  	// given
   247  	sut := Graphqlizer{}
   248  	exp := `{
   249  		name: "c-90a3016",
   250  		kubernetesVersion: "1.18",
   251  		volumeSizeGB: 50,
   252  		machineType: "Standard_D4_v3",
   253  		region: "europe",
   254  		provider: "Azure",
   255  		diskType: "Standard_LRS",
   256  		targetSecret: "scr",
   257  		workerCidr: "10.250.0.0/19",
   258  		autoScalerMin: 0,
   259  		autoScalerMax: 0,
   260  		maxSurge: 0,
   261  		maxUnavailable: 0,
   262  		oidcConfig: {
   263  			clientID: "client-id",
   264  			issuerURL: "https://issuer.url",
   265  			groupsClaim: "",
   266  			signingAlgs: [],
   267  			usernameClaim: "",
   268  			usernamePrefix: "",
   269  		}
   270  		dnsConfig: {
   271  			domain: "c-90a3016.kymatest.ondemand.com",
   272  			providers: [
   273  				{
   274  					domainsInclude: ["kymatest.ondemand.com"],
   275  					primary: true,
   276  					secretName: "aws-secret-for-custom-domain",
   277  					type: "aws-route53",
   278  				}
   279  			]
   280  		}
   281  	}`
   282  
   283  	// when
   284  	name := "c-90a3016"
   285  	got, err := sut.GardenerConfigInputToGraphQL(gqlschema.GardenerConfigInput{
   286  		Name:              name,
   287  		Region:            "europe",
   288  		VolumeSizeGb:      ptr.Integer(50),
   289  		WorkerCidr:        "10.250.0.0/19",
   290  		Provider:          "Azure",
   291  		DiskType:          ptr.String("Standard_LRS"),
   292  		TargetSecret:      "scr",
   293  		MachineType:       "Standard_D4_v3",
   294  		KubernetesVersion: "1.18",
   295  		OidcConfig: &gqlschema.OIDCConfigInput{
   296  			ClientID:       "client-id",
   297  			GroupsClaim:    "",
   298  			IssuerURL:      "https://issuer.url",
   299  			SigningAlgs:    nil,
   300  			UsernameClaim:  "",
   301  			UsernamePrefix: "",
   302  		},
   303  		DNSConfig: &gqlschema.DNSConfigInput{
   304  			Domain: name + ".kymatest.ondemand.com",
   305  			Providers: []*gqlschema.DNSProviderInput{
   306  				&gqlschema.DNSProviderInput{
   307  					DomainsInclude: []string{"kymatest.ondemand.com"},
   308  					Primary:        true,
   309  					SecretName:     "aws-secret-for-custom-domain",
   310  					Type:           "aws-route53",
   311  				},
   312  			},
   313  		},
   314  	})
   315  
   316  	// then
   317  	require.NoError(t, err)
   318  	assert.Equal(t, exp, got)
   319  }
   320  
   321  func Test_GardenerConfigInputToGraphQLWithMachineImage(t *testing.T) {
   322  	// given
   323  	sut := Graphqlizer{}
   324  	exp := `{
   325  		name: "c-90a3016",
   326  		kubernetesVersion: "1.18",
   327  		volumeSizeGB: 50,
   328  		machineType: "Standard_D4_v3",
   329  		machineImage: "coreos",
   330  		machineImageVersion: "255.0",
   331  		region: "europe",
   332  		provider: "Azure",
   333  		diskType: "Standard_LRS",
   334  		targetSecret: "scr",
   335  		workerCidr: "10.250.0.0/19",
   336  		autoScalerMin: 0,
   337  		autoScalerMax: 0,
   338  		maxSurge: 0,
   339  		maxUnavailable: 0,
   340  	}`
   341  
   342  	// when
   343  	name := "c-90a3016"
   344  	got, err := sut.GardenerConfigInputToGraphQL(gqlschema.GardenerConfigInput{
   345  		Name:                name,
   346  		Region:              "europe",
   347  		VolumeSizeGb:        ptr.Integer(50),
   348  		WorkerCidr:          "10.250.0.0/19",
   349  		Provider:            "Azure",
   350  		DiskType:            ptr.String("Standard_LRS"),
   351  		TargetSecret:        "scr",
   352  		MachineType:         "Standard_D4_v3",
   353  		KubernetesVersion:   "1.18",
   354  		MachineImage:        strPrt("coreos"),
   355  		MachineImageVersion: strPrt("255.0"),
   356  	})
   357  
   358  	// then
   359  	require.NoError(t, err)
   360  	assert.Equal(t, exp, got)
   361  }
   362  
   363  func Test_LabelsToGQL(t *testing.T) {
   364  
   365  	sut := Graphqlizer{}
   366  
   367  	for _, testCase := range []struct {
   368  		description string
   369  		input       gqlschema.Labels
   370  		expected    string
   371  	}{
   372  		{
   373  			description: "string labels",
   374  			input: gqlschema.Labels{
   375  				"test": "966",
   376  			},
   377  			expected: `{test:"966",}`,
   378  		},
   379  		{
   380  			description: "string array labels",
   381  			input: gqlschema.Labels{
   382  				"test": []string{"966"},
   383  			},
   384  			expected: `{test:["966"],}`,
   385  		},
   386  		{
   387  			description: "string array labels",
   388  			input: gqlschema.Labels{
   389  				"test": map[string]string{"abcd": "966"},
   390  			},
   391  			expected: `{test:{abcd:"966",},}`,
   392  		},
   393  	} {
   394  		t.Run(testCase.description, func(t *testing.T) {
   395  			// when
   396  			render, err := sut.LabelsToGQL(testCase.input)
   397  
   398  			// then
   399  			require.NoError(t, err)
   400  			assert.Equal(t, testCase.expected, render)
   401  		})
   402  	}
   403  }
   404  
   405  func TestAzureProviderConfigInputToGraphQL(t *testing.T) {
   406  	tests := []struct {
   407  		name       string
   408  		givenInput gqlschema.AzureProviderConfigInput
   409  		expected   string
   410  	}{
   411  		{
   412  			name: "Azure with zones parameter",
   413  			givenInput: gqlschema.AzureProviderConfigInput{
   414  				EnableNatGateway: boolPtr(true),
   415  				VnetCidr:         "8.8.8.8",
   416  				Zones:            []string{"fix-az-zone-1", "fix-az-zone-2"},
   417  			},
   418  			expected: `{
   419  		enableNatGateway: true,
   420  		vnetCidr: "8.8.8.8",
   421  		zones: ["fix-az-zone-1","fix-az-zone-2"],
   422  	}`,
   423  		},
   424  		{
   425  			name: "Azure with no zones passed",
   426  			givenInput: gqlschema.AzureProviderConfigInput{
   427  				VnetCidr: "8.8.8.8",
   428  			},
   429  			expected: `{
   430  		vnetCidr: "8.8.8.8",
   431  	}`,
   432  		},
   433  		{
   434  			name: "Azure with azureZones passed",
   435  			givenInput: gqlschema.AzureProviderConfigInput{
   436  				VnetCidr: "8.8.8.8",
   437  				AzureZones: []*gqlschema.AzureZoneInput{
   438  					{
   439  						Name: 1,
   440  						Cidr: "10.250.0.0/19",
   441  					},
   442  					{
   443  						Name: 2,
   444  						Cidr: "10.250.32.0/19",
   445  					},
   446  				},
   447  			},
   448  			expected: `{
   449  		vnetCidr: "8.8.8.8",
   450  		azureZones: [
   451  			{
   452  				name: 1,
   453  				cidr: "10.250.0.0/19",
   454  			}
   455  			{
   456  				name: 2,
   457  				cidr: "10.250.32.0/19",
   458  			}
   459  		]
   460  	}`,
   461  		},
   462  	}
   463  	for _, tt := range tests {
   464  		t.Run(tt.name, func(t *testing.T) {
   465  			g := &Graphqlizer{}
   466  
   467  			// when
   468  			got, err := g.AzureProviderConfigInputToGraphQL(tt.givenInput)
   469  
   470  			// then
   471  			require.NoError(t, err)
   472  			assert.Equal(t, tt.expected, got)
   473  		})
   474  	}
   475  }
   476  
   477  func TestGCPProviderConfigInputToGraphQL(t *testing.T) {
   478  	// given
   479  	fixInput := gqlschema.GCPProviderConfigInput{
   480  		Zones: []string{"fix-gcp-zone-1", "fix-gcp-zone-2"},
   481  	}
   482  	expected := `{ zones: ["fix-gcp-zone-1","fix-gcp-zone-2"] }`
   483  	g := &Graphqlizer{}
   484  
   485  	// when
   486  	got, err := g.GCPProviderConfigInputToGraphQL(fixInput)
   487  
   488  	// then
   489  	require.NoError(t, err)
   490  	assert.Equal(t, expected, got)
   491  }
   492  
   493  func TestAWSProviderConfigInputToGraphQL(t *testing.T) {
   494  	tests := []struct {
   495  		name       string
   496  		givenInput gqlschema.AWSProviderConfigInput
   497  		expected   string
   498  	}{
   499  		{
   500  			name: "AWS will all parameters",
   501  			givenInput: gqlschema.AWSProviderConfigInput{
   502  				VpcCidr: "10.250.0.0/16",
   503  				AwsZones: []*gqlschema.AWSZoneInput{
   504  					{
   505  						Name:         "eu-central-1a",
   506  						WorkerCidr:   "10.250.0.0/22",
   507  						PublicCidr:   "10.250.20.0/22",
   508  						InternalCidr: "10.250.40.0/22",
   509  					},
   510  					{
   511  						Name:         "eu-central-1b",
   512  						WorkerCidr:   "10.250.4.0/22",
   513  						PublicCidr:   "10.250.24.0/22",
   514  						InternalCidr: "10.250.44.0/22",
   515  					},
   516  				},
   517  			},
   518  			expected: `{
   519  		vpcCidr: "10.250.0.0/16",
   520  		awsZones: [
   521  			{
   522  				name: "eu-central-1a",
   523  				workerCidr: "10.250.0.0/22",
   524  				publicCidr: "10.250.20.0/22",
   525  				internalCidr: "10.250.40.0/22",
   526  			}
   527  			{
   528  				name: "eu-central-1b",
   529  				workerCidr: "10.250.4.0/22",
   530  				publicCidr: "10.250.24.0/22",
   531  				internalCidr: "10.250.44.0/22",
   532  			}
   533  		]
   534  	}`,
   535  		},
   536  		{
   537  			name: "AWS with no zones passed",
   538  			givenInput: gqlschema.AWSProviderConfigInput{
   539  				VpcCidr: "8.8.8.8",
   540  			},
   541  			expected: `{
   542  		vpcCidr: "8.8.8.8",
   543  	}`,
   544  		},
   545  	}
   546  	for _, tt := range tests {
   547  		t.Run(tt.name, func(t *testing.T) {
   548  			g := &Graphqlizer{}
   549  
   550  			// when
   551  			got, err := g.AWSProviderConfigInputToGraphQL(tt.givenInput)
   552  
   553  			// then
   554  			require.NoError(t, err)
   555  			assert.Equal(t, tt.expected, got)
   556  		})
   557  	}
   558  }
   559  
   560  func Test_UpgradeShootInputToGraphQL(t *testing.T) {
   561  	// given
   562  	sut := Graphqlizer{}
   563  	exp := `{
   564  	gardenerConfig: {
   565  		kubernetesVersion: "1.18.0",
   566  		machineType: "m5.xlarge",
   567  		machineImage: "gardenlinux",
   568  		machineImageVersion: "184.0.0",
   569  		autoScalerMin: 2,
   570  		autoScalerMax: 4,
   571  		maxSurge: 4,
   572  		maxUnavailable: 1,
   573  		enableKubernetesVersionAutoUpdate: true,
   574  		enableMachineImageVersionAutoUpdate: false,
   575  		oidcConfig: {
   576  			clientID: "cid",
   577  			issuerURL: "issuer.url",
   578  			groupsClaim: "groups",
   579  			signingAlgs: ["RSA256"],
   580  			usernameClaim: "sub",
   581  			usernamePrefix: "-",
   582  		},
   583          shootNetworkingFilterDisabled: true,
   584  	},
   585  	administrators: ["newAdmin@kyma.cx"],
   586  }`
   587  
   588  	// when
   589  	got, err := sut.UpgradeShootInputToGraphQL(gqlschema.UpgradeShootInput{
   590  		GardenerConfig: &gqlschema.GardenerUpgradeInput{
   591  			KubernetesVersion:                   strPrt("1.18.0"),
   592  			MachineType:                         strPrt("m5.xlarge"),
   593  			MachineImage:                        strPrt("gardenlinux"),
   594  			MachineImageVersion:                 strPrt("184.0.0"),
   595  			EnableKubernetesVersionAutoUpdate:   boolPtr(true),
   596  			EnableMachineImageVersionAutoUpdate: boolPtr(false),
   597  			AutoScalerMin:                       ptr.Integer(2),
   598  			AutoScalerMax:                       ptr.Integer(4),
   599  			MaxSurge:                            ptr.Integer(4),
   600  			MaxUnavailable:                      ptr.Integer(1),
   601  			OidcConfig: &gqlschema.OIDCConfigInput{
   602  				ClientID:       "cid",
   603  				GroupsClaim:    "groups",
   604  				IssuerURL:      "issuer.url",
   605  				SigningAlgs:    []string{"RSA256"},
   606  				UsernameClaim:  "sub",
   607  				UsernamePrefix: "-",
   608  			},
   609  			ShootNetworkingFilterDisabled: boolPtr(true),
   610  		},
   611  		Administrators: []string{"newAdmin@kyma.cx"},
   612  	})
   613  
   614  	// then
   615  	require.NoError(t, err)
   616  	assert.Equal(t, exp, got)
   617  }
   618  
   619  func TestOpenstack(t *testing.T) {
   620  	// given
   621  	input := gqlschema.ProviderSpecificInput{
   622  		OpenStackConfig: &gqlschema.OpenStackProviderConfigInput{
   623  			Zones:                []string{"z1"},
   624  			FloatingPoolName:     "fp",
   625  			CloudProfileName:     "cp",
   626  			LoadBalancerProvider: "lbp",
   627  		},
   628  	}
   629  
   630  	g := &Graphqlizer{}
   631  
   632  	// when
   633  	got, err := g.GardenerConfigInputToGraphQL(gqlschema.GardenerConfigInput{
   634  		ExposureClassName:      ptr.String("converged-cloud-internet"),
   635  		ProviderSpecificConfig: &input,
   636  	})
   637  
   638  	// then
   639  	require.NoError(t, err)
   640  	assert.Equal(t, `{
   641  		kubernetesVersion: "",
   642  		machineType: "",
   643  		region: "",
   644  		provider: "",
   645  		targetSecret: "",
   646  		workerCidr: "",
   647  		autoScalerMin: 0,
   648  		autoScalerMax: 0,
   649  		maxSurge: 0,
   650  		maxUnavailable: 0,
   651  		exposureClassName: "converged-cloud-internet",
   652  		providerSpecificConfig: {
   653  			openStackConfig: {
   654  				zones: ["z1"],
   655  				floatingPoolName: "fp",
   656  				cloudProfileName: "cp",
   657  				loadBalancerProvider: "lbp"
   658  			},
   659  		}
   660  	}`, got)
   661  
   662  }
   663  
   664  func Test_ClusterConfigToGraphQL(t *testing.T) {
   665  	tests := []struct {
   666  		name       string
   667  		givenInput gqlschema.ClusterConfigInput
   668  		expected   string
   669  	}{
   670  		{
   671  			name: "Cluster config with administrators",
   672  			givenInput: gqlschema.ClusterConfigInput{
   673  				Administrators: []string{"test@test.pl"},
   674  			},
   675  			expected: `{
   676  		administrators: ["test@test.pl"],
   677  	}`,
   678  		},
   679  	}
   680  	for _, tt := range tests {
   681  		t.Run(tt.name, func(t *testing.T) {
   682  			g := &Graphqlizer{}
   683  
   684  			// when
   685  			got, err := g.ClusterConfigToGraphQL(tt.givenInput)
   686  
   687  			// then
   688  			require.NoError(t, err)
   689  			assert.Equal(t, tt.expected, got)
   690  		})
   691  	}
   692  }
   693  
   694  func strPrt(s string) *string {
   695  	return &s
   696  }
   697  
   698  func boolPtr(b bool) *bool {
   699  	return &b
   700  }