From a27ffa48f9d939579a13c27b987c7068ae4f0ad2 Mon Sep 17 00:00:00 2001 From: Carlo Goetz Date: Fri, 12 Jun 2026 10:35:40 +0200 Subject: [PATCH 1/3] feat(go): patch iaas/AreaID after generation to fix oneOf regex issue STACKITSDK-226 --- CustomRegionGenerator.java | 198 +++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/CustomRegionGenerator.java b/CustomRegionGenerator.java index 160fda5..8b03089 100644 --- a/CustomRegionGenerator.java +++ b/CustomRegionGenerator.java @@ -5,6 +5,11 @@ import org.openapitools.codegen.CodegenParameter; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.Arrays; import java.util.Set; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; @@ -68,4 +73,197 @@ private boolean isRegionField(String name) { } return name.equalsIgnoreCase("region") || name.equalsIgnoreCase("regionId"); } + private final byte[] IAAS_AREA_ID_HASH = {-73, 66, 84, 86, -60, 99, 59, 46, -116, 10, 97, -23, -85, 59, 87, -98}; + private final String IAAS_AREA_ID_PATCHED = """ +/* +STACKIT IaaS API + +This API allows you to create and modify IaaS resources. + +API version: 2 +Contact: stackit-iaas@mail.schwarz +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package v2api + +import ( + "encoding/json" + "fmt" + "regexp" +) + +// AreaId - The identifier (ID) of an area. +type AreaId struct { + StaticAreaID *StaticAreaID + String *string +} + +// StaticAreaIDAsAreaId is a convenience function that returns StaticAreaID wrapped in AreaId +func StaticAreaIDAsAreaId(v *StaticAreaID) AreaId { + return AreaId{ + StaticAreaID: v, + } +} + +// stringAsAreaId is a convenience function that returns string wrapped in AreaId +func StringAsAreaId(v *string) AreaId { + return AreaId{ + String: v, + } +} + +// Unmarshal JSON data into one of the pointers in the struct +func (dst *AreaId) UnmarshalJSON(data []byte) error { + var err error + match := 0 + // try to unmarshal data into StaticAreaID + err = json.Unmarshal(data, &dst.StaticAreaID) + if err == nil { + jsonStaticAreaID, _ := json.Marshal(dst.StaticAreaID) + if string(jsonStaticAreaID) == "{}" { // empty struct + dst.StaticAreaID = nil + } else { + match++ + } + } else { + dst.StaticAreaID = nil + } + + // try to unmarshal data into String + err = json.Unmarshal(data, &dst.String) + if err == nil { + jsonString, _ := json.Marshal(dst.String) + regex := `/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/` + regex = regexp.MustCompile("^\\\\/|\\\\/$").ReplaceAllString(regex, "$1") // Remove beginning slash and ending slash + regex = regexp.MustCompile("\\\\\\\\(.)").ReplaceAllString(regex, "$1") // Remove duplicate escaping char for dots + rawString := regexp.MustCompile(`^"|"$`).ReplaceAllString(*dstAreaId1.String, "$1") // Remove quotes + isMatched, _ := regexp.MatchString(regex, rawString) + if string(jsonString) != "{}" && isMatched { // empty struct + dst.String = nil + } else { + match++ + } + } else { + dst.String = nil + } + + if match > 1 { // more than 1 match + // reset to nil + dst.StaticAreaID = nil + dst.String = nil + + return fmt.Errorf("data matches more than one schema in oneOf(AreaId)") + } else if match == 1 { + return nil // exactly one match + } else { // no match + return fmt.Errorf("data failed to match schemas in oneOf(AreaId)") + } +} + +// Marshal data from the first non-nil pointers in the struct to JSON +func (src AreaId) MarshalJSON() ([]byte, error) { + if src.StaticAreaID != nil { + return json.Marshal(&src.StaticAreaID) + } + + if src.String != nil { + return json.Marshal(&src.String) + } + + return nil, nil // no data in oneOf schemas +} + +// Get the actual instance +func (obj *AreaId) GetActualInstance() interface{} { + if obj == nil { + return nil + } + if obj.StaticAreaID != nil { + return obj.StaticAreaID + } + + if obj.String != nil { + return obj.String + } + + // all schemas are nil + return nil +} + +// Get the actual instance value +func (obj AreaId) GetActualInstanceValue() interface{} { + if obj.StaticAreaID != nil { + return *obj.StaticAreaID + } + + if obj.String != nil { + return *obj.String + } + + // all schemas are nil + return nil +} + +type NullableAreaId struct { + value *AreaId + isSet bool +} + +func (v NullableAreaId) Get() *AreaId { + return v.value +} + +func (v *NullableAreaId) Set(val *AreaId) { + v.value = val + v.isSet = true +} + +func (v NullableAreaId) IsSet() bool { + return v.isSet +} + +func (v *NullableAreaId) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableAreaId(val *AreaId) *NullableAreaId { + return &NullableAreaId{value: val, isSet: true} +} + +func (v NullableAreaId) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableAreaId) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} +"""; + + @Override + public void postProcessFile(File file, String fileType) { + if (file.getAbsolutePath().endsWith("iaas/v2api/model_area_id.go")) { + try { + var content = Files.readAllBytes(file.toPath()); + var digest = MessageDigest.getInstance("MD5"); + var hash = digest.digest(content); + if (Arrays.equals(hash, IAAS_AREA_ID_HASH)) { + Files.writeString(file.toPath(), IAAS_AREA_ID_PATCHED, StandardOpenOption.TRUNCATE_EXISTING); + } else { + throw new IllegalStateException( + "expected iaas/v2api/model_area_id.go to hash to " + + Arrays.toString(IAAS_AREA_ID_HASH) + " but got " + Arrays.toString(hash) + + "\nedit CustomRegionGenerator.java in the sdk-generator and update IAAS_AREA_ID_HASH" + + "to accept this change" + ); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + super.postProcessFile(file, fileType); + } } From 7956e39ad412a8ada8ea25fb5c31a51e85250095 Mon Sep 17 00:00:00 2001 From: Carlo Goetz Date: Thu, 25 Jun 2026 09:51:36 +0200 Subject: [PATCH 2/3] feat(go): make file overrides configurable, add iaas overrides --- CustomRegionGenerator.java | 237 +++++------------- .../golang/overrides/overrides.properties | 11 + .../golang/overrides/v1api_model_area_id.go | 164 ++++++++++++ .../golang/overrides/v2api_model_area_id.go | 163 ++++++++++++ .../golang/overrides/v2beta_model_area_id.go | 163 ++++++++++++ scripts/generate-sdk/languages/go.sh | 3 +- 6 files changed, 565 insertions(+), 176 deletions(-) create mode 100644 languages/golang/overrides/overrides.properties create mode 100644 languages/golang/overrides/v1api_model_area_id.go create mode 100644 languages/golang/overrides/v2api_model_area_id.go create mode 100644 languages/golang/overrides/v2beta_model_area_id.go diff --git a/CustomRegionGenerator.java b/CustomRegionGenerator.java index 8b03089..932de41 100644 --- a/CustomRegionGenerator.java +++ b/CustomRegionGenerator.java @@ -6,15 +6,27 @@ import org.openapitools.codegen.CodegenParameter; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.security.MessageDigest; -import java.util.Arrays; +import java.util.HashMap; +import java.util.HexFormat; +import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; public class CustomRegionGenerator extends GoClientCodegen { + private final static String NAMESPACE = "cloud/stackit/codegen/"; + private final Map overrides; @Override public String getName() { @@ -25,6 +37,14 @@ public String getName() { public CustomRegionGenerator() { super(); System.out.println("=== CUSTOM GO CLIENT GENERATOR INITIALIZED ==="); + try { + overrides = OverrideConfig.load().stream().collect(Collectors.toMap( + o -> o.path, + Function.identity() + )); + } catch (IOException e) { + throw new RuntimeException(e); + } } @Override @@ -73,189 +93,27 @@ private boolean isRegionField(String name) { } return name.equalsIgnoreCase("region") || name.equalsIgnoreCase("regionId"); } - private final byte[] IAAS_AREA_ID_HASH = {-73, 66, 84, 86, -60, 99, 59, 46, -116, 10, 97, -23, -85, 59, 87, -98}; - private final String IAAS_AREA_ID_PATCHED = """ -/* -STACKIT IaaS API - -This API allows you to create and modify IaaS resources. - -API version: 2 -Contact: stackit-iaas@mail.schwarz -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package v2api - -import ( - "encoding/json" - "fmt" - "regexp" -) - -// AreaId - The identifier (ID) of an area. -type AreaId struct { - StaticAreaID *StaticAreaID - String *string -} - -// StaticAreaIDAsAreaId is a convenience function that returns StaticAreaID wrapped in AreaId -func StaticAreaIDAsAreaId(v *StaticAreaID) AreaId { - return AreaId{ - StaticAreaID: v, - } -} - -// stringAsAreaId is a convenience function that returns string wrapped in AreaId -func StringAsAreaId(v *string) AreaId { - return AreaId{ - String: v, - } -} - -// Unmarshal JSON data into one of the pointers in the struct -func (dst *AreaId) UnmarshalJSON(data []byte) error { - var err error - match := 0 - // try to unmarshal data into StaticAreaID - err = json.Unmarshal(data, &dst.StaticAreaID) - if err == nil { - jsonStaticAreaID, _ := json.Marshal(dst.StaticAreaID) - if string(jsonStaticAreaID) == "{}" { // empty struct - dst.StaticAreaID = nil - } else { - match++ - } - } else { - dst.StaticAreaID = nil - } - - // try to unmarshal data into String - err = json.Unmarshal(data, &dst.String) - if err == nil { - jsonString, _ := json.Marshal(dst.String) - regex := `/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/` - regex = regexp.MustCompile("^\\\\/|\\\\/$").ReplaceAllString(regex, "$1") // Remove beginning slash and ending slash - regex = regexp.MustCompile("\\\\\\\\(.)").ReplaceAllString(regex, "$1") // Remove duplicate escaping char for dots - rawString := regexp.MustCompile(`^"|"$`).ReplaceAllString(*dstAreaId1.String, "$1") // Remove quotes - isMatched, _ := regexp.MatchString(regex, rawString) - if string(jsonString) != "{}" && isMatched { // empty struct - dst.String = nil - } else { - match++ - } - } else { - dst.String = nil - } - - if match > 1 { // more than 1 match - // reset to nil - dst.StaticAreaID = nil - dst.String = nil - - return fmt.Errorf("data matches more than one schema in oneOf(AreaId)") - } else if match == 1 { - return nil // exactly one match - } else { // no match - return fmt.Errorf("data failed to match schemas in oneOf(AreaId)") - } -} - -// Marshal data from the first non-nil pointers in the struct to JSON -func (src AreaId) MarshalJSON() ([]byte, error) { - if src.StaticAreaID != nil { - return json.Marshal(&src.StaticAreaID) - } - - if src.String != nil { - return json.Marshal(&src.String) - } - - return nil, nil // no data in oneOf schemas -} - -// Get the actual instance -func (obj *AreaId) GetActualInstance() interface{} { - if obj == nil { - return nil - } - if obj.StaticAreaID != nil { - return obj.StaticAreaID - } - - if obj.String != nil { - return obj.String - } - - // all schemas are nil - return nil -} - -// Get the actual instance value -func (obj AreaId) GetActualInstanceValue() interface{} { - if obj.StaticAreaID != nil { - return *obj.StaticAreaID - } - - if obj.String != nil { - return *obj.String - } - - // all schemas are nil - return nil -} - -type NullableAreaId struct { - value *AreaId - isSet bool -} - -func (v NullableAreaId) Get() *AreaId { - return v.value -} - -func (v *NullableAreaId) Set(val *AreaId) { - v.value = val - v.isSet = true -} - -func (v NullableAreaId) IsSet() bool { - return v.isSet -} - -func (v *NullableAreaId) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableAreaId(val *AreaId) *NullableAreaId { - return &NullableAreaId{value: val, isSet: true} -} - -func (v NullableAreaId) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableAreaId) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} -"""; @Override public void postProcessFile(File file, String fileType) { - if (file.getAbsolutePath().endsWith("iaas/v2api/model_area_id.go")) { + var path = file.getAbsolutePath(); + var servicesIdx = path.indexOf("/services/"); + var subPath = path.substring(servicesIdx + "/services/".length()); + if (overrides.containsKey(subPath)) { + var override = overrides.get(subPath); try { var content = Files.readAllBytes(file.toPath()); var digest = MessageDigest.getInstance("MD5"); - var hash = digest.digest(content); - if (Arrays.equals(hash, IAAS_AREA_ID_HASH)) { - Files.writeString(file.toPath(), IAAS_AREA_ID_PATCHED, StandardOpenOption.TRUNCATE_EXISTING); + var hex = HexFormat.of(); + var hash = hex.formatHex(digest.digest(content)); + if (hash.equals(override.hash)) { + var replacementPath = Path.of(Thread.currentThread().getContextClassLoader().getResource(NAMESPACE + override.replacementPath).getPath()); + var replacementContent = Files.readAllBytes(replacementPath); + Files.write(file.toPath(), replacementContent, StandardOpenOption.TRUNCATE_EXISTING); } else { throw new IllegalStateException( "expected iaas/v2api/model_area_id.go to hash to " + - Arrays.toString(IAAS_AREA_ID_HASH) + " but got " + Arrays.toString(hash) + + override.hash + " but got " + hash + "\nedit CustomRegionGenerator.java in the sdk-generator and update IAAS_AREA_ID_HASH" + "to accept this change" ); @@ -266,4 +124,33 @@ public void postProcessFile(File file, String fileType) { } super.postProcessFile(file, fileType); } + + private static class OverrideConfig { + public String name; + public String path; + public String replacementPath; + public String hash; + + public static List load() throws IOException { + var path = Thread.currentThread().getContextClassLoader().getResource(NAMESPACE + "overrides.properties").getPath(); + var overrideProps = new Properties(); + overrideProps.load(new FileInputStream(path)); + var byName = new HashMap(); + overrideProps.stringPropertyNames().forEach(key -> { + var prefixLen = key.indexOf('.'); + var prefix = key.substring(0, prefixLen); + var config = byName.computeIfAbsent(prefix, (_) -> new OverrideConfig()); + config.name = prefix; + var suffix = key.substring(prefixLen + 1); + switch (suffix) { + case "path" -> config.path = overrideProps.getProperty(key); + case "replacementPath" -> config.replacementPath = overrideProps.getProperty(key); + case "hash" -> config.hash = overrideProps.getProperty(key); + default -> throw new IllegalStateException("unexpected suffix: " + suffix); + } + }); + return byName.values().stream().toList(); + } + } + } diff --git a/languages/golang/overrides/overrides.properties b/languages/golang/overrides/overrides.properties new file mode 100644 index 0000000..58a7a15 --- /dev/null +++ b/languages/golang/overrides/overrides.properties @@ -0,0 +1,11 @@ +iaasV2ApiAreaId.path=iaas/v2api/model_area_id.go +iaasV2ApiAreaId.replacementPath=v2api_model_area_id.go +iaasV2ApiAreaId.hash=b7425456c4633b2e8c0a61e9ab3b579e + +iaasV1ApiAreaId.path=iaas/v1api/model_area_id.go +iaasV1ApiAreaId.replacementPath=v1api_model_area_id.go +iaasV1ApiAreaId.hash=a9d72364fec0794cab3b51f3680de584 + +iaasV2BetaApiAreaId.path="iaas/v2beta1api/model_area_id.go +iaasV2BetaApiAreaId.replacementPath=v2beta_model_area_id.go +iaasV2BetaApiAreaId.hash=bb5583419348ee95ebbde0b4133a36f0 diff --git a/languages/golang/overrides/v1api_model_area_id.go b/languages/golang/overrides/v1api_model_area_id.go new file mode 100644 index 0000000..7dab3f9 --- /dev/null +++ b/languages/golang/overrides/v1api_model_area_id.go @@ -0,0 +1,164 @@ +/* +STACKIT IaaS API + +This API is deprecated. It will be retired on 01.03.2027. Please use the STACKIT IaaS API V2 instead. + +API version: 1 +Contact: stackit-iaas@mail.schwarz +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package v1api + +import ( + "encoding/json" + "fmt" + "regexp" +) + +// AreaId - The identifier (ID) of an area. +type AreaId struct { + StaticAreaID *StaticAreaID + String *string +} + +// StaticAreaIDAsAreaId is a convenience function that returns StaticAreaID wrapped in AreaId +func StaticAreaIDAsAreaId(v *StaticAreaID) AreaId { + return AreaId{ + StaticAreaID: v, + } +} + +// stringAsAreaId is a convenience function that returns string wrapped in AreaId +func StringAsAreaId(v *string) AreaId { + return AreaId{ + String: v, + } +} + +// Unmarshal JSON data into one of the pointers in the struct +func (dst *AreaId) UnmarshalJSON(data []byte) error { + var err error + match := 0 + // try to unmarshal data into StaticAreaID + err = json.Unmarshal(data, &dst.StaticAreaID) + if err == nil { + jsonStaticAreaID, _ := json.Marshal(dst.StaticAreaID) + if string(jsonStaticAreaID) == "{}" { // empty struct + dst.StaticAreaID = nil + } else { + match++ + } + } else { + dst.StaticAreaID = nil + } + + // try to unmarshal data into String + err = json.Unmarshal(data, &dst.String) + if err == nil { + jsonString, _ := json.Marshal(dst.String) + regex := `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$` + isMatched, _ := regexp.MatchString(regex, *dst.String) + if string(jsonString) != "{}" && isMatched { // empty struct + match++ + } else { + dst.String = nil + } + } else { + dst.String = nil + } + + if match > 1 { // more than 1 match + // reset to nil + dst.StaticAreaID = nil + dst.String = nil + + return fmt.Errorf("data matches more than one schema in oneOf(AreaId)") + } else if match == 1 { + return nil // exactly one match + } else { // no match + return fmt.Errorf("data failed to match schemas in oneOf(AreaId)") + } +} + +// Marshal data from the first non-nil pointers in the struct to JSON +func (src AreaId) MarshalJSON() ([]byte, error) { + if src.StaticAreaID != nil { + return json.Marshal(&src.StaticAreaID) + } + + if src.String != nil { + return json.Marshal(&src.String) + } + + return nil, nil // no data in oneOf schemas +} + +// Get the actual instance +func (obj *AreaId) GetActualInstance() interface{} { + if obj == nil { + return nil + } + if obj.StaticAreaID != nil { + return obj.StaticAreaID + } + + if obj.String != nil { + return obj.String + } + + // all schemas are nil + return nil +} + +// Get the actual instance value +func (obj AreaId) GetActualInstanceValue() interface{} { + if obj.StaticAreaID != nil { + return *obj.StaticAreaID + } + + if obj.String != nil { + return *obj.String + } + + // all schemas are nil + return nil +} + +type NullableAreaId struct { + value *AreaId + isSet bool +} + +func (v NullableAreaId) Get() *AreaId { + return v.value +} + +func (v *NullableAreaId) Set(val *AreaId) { + v.value = val + v.isSet = true +} + +func (v NullableAreaId) IsSet() bool { + return v.isSet +} + +func (v *NullableAreaId) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableAreaId(val *AreaId) *NullableAreaId { + return &NullableAreaId{value: val, isSet: true} +} + +func (v NullableAreaId) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableAreaId) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + diff --git a/languages/golang/overrides/v2api_model_area_id.go b/languages/golang/overrides/v2api_model_area_id.go new file mode 100644 index 0000000..5159f8b --- /dev/null +++ b/languages/golang/overrides/v2api_model_area_id.go @@ -0,0 +1,163 @@ +/* +STACKIT IaaS API + +This API allows you to create and modify IaaS resources. + +API version: 2 +Contact: stackit-iaas@mail.schwarz +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package v2api + +import ( + "encoding/json" + "fmt" + "regexp" +) + +// AreaId - The identifier (ID) of an area. +type AreaId struct { + StaticAreaID *StaticAreaID + String *string +} + +// StaticAreaIDAsAreaId is a convenience function that returns StaticAreaID wrapped in AreaId +func StaticAreaIDAsAreaId(v *StaticAreaID) AreaId { + return AreaId{ + StaticAreaID: v, + } +} + +// stringAsAreaId is a convenience function that returns string wrapped in AreaId +func StringAsAreaId(v *string) AreaId { + return AreaId{ + String: v, + } +} + +// Unmarshal JSON data into one of the pointers in the struct +func (dst *AreaId) UnmarshalJSON(data []byte) error { + var err error + match := 0 + // try to unmarshal data into StaticAreaID + err = json.Unmarshal(data, &dst.StaticAreaID) + if err == nil { + jsonStaticAreaID, _ := json.Marshal(dst.StaticAreaID) + if string(jsonStaticAreaID) == "{}" { // empty struct + dst.StaticAreaID = nil + } else { + match++ + } + } else { + dst.StaticAreaID = nil + } + + // try to unmarshal data into String + err = json.Unmarshal(data, &dst.String) + if err == nil { + jsonString, _ := json.Marshal(dst.String) + regex := `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$` + isMatched, _ := regexp.MatchString(regex, *dst.String) + if string(jsonString) != "{}" && isMatched { // empty struct + match++ + } else { + dst.String = nil + } + } else { + dst.String = nil + } + + if match > 1 { // more than 1 match + // reset to nil + dst.StaticAreaID = nil + dst.String = nil + + return fmt.Errorf("data matches more than one schema in oneOf(AreaId)") + } else if match == 1 { + return nil // exactly one match + } else { // no match + return fmt.Errorf("data failed to match schemas in oneOf(AreaId)") + } +} + +// Marshal data from the first non-nil pointers in the struct to JSON +func (src AreaId) MarshalJSON() ([]byte, error) { + if src.StaticAreaID != nil { + return json.Marshal(&src.StaticAreaID) + } + + if src.String != nil { + return json.Marshal(&src.String) + } + + return nil, nil // no data in oneOf schemas +} + +// Get the actual instance +func (obj *AreaId) GetActualInstance() interface{} { + if obj == nil { + return nil + } + if obj.StaticAreaID != nil { + return obj.StaticAreaID + } + + if obj.String != nil { + return obj.String + } + + // all schemas are nil + return nil +} + +// Get the actual instance value +func (obj AreaId) GetActualInstanceValue() interface{} { + if obj.StaticAreaID != nil { + return *obj.StaticAreaID + } + + if obj.String != nil { + return *obj.String + } + + // all schemas are nil + return nil +} + +type NullableAreaId struct { + value *AreaId + isSet bool +} + +func (v NullableAreaId) Get() *AreaId { + return v.value +} + +func (v *NullableAreaId) Set(val *AreaId) { + v.value = val + v.isSet = true +} + +func (v NullableAreaId) IsSet() bool { + return v.isSet +} + +func (v *NullableAreaId) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableAreaId(val *AreaId) *NullableAreaId { + return &NullableAreaId{value: val, isSet: true} +} + +func (v NullableAreaId) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableAreaId) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/languages/golang/overrides/v2beta_model_area_id.go b/languages/golang/overrides/v2beta_model_area_id.go new file mode 100644 index 0000000..f7bcd61 --- /dev/null +++ b/languages/golang/overrides/v2beta_model_area_id.go @@ -0,0 +1,163 @@ +/* +STACKIT IaaS API + +This API allows you to create and modify IaaS resources. + +API version: 2beta1 +Contact: stackit-iaas@mail.schwarz +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package v2beta1api + +import ( + "encoding/json" + "fmt" + "regexp" +) + +// AreaId - The identifier (ID) of an area. +type AreaId struct { + StaticAreaID *StaticAreaID + String *string +} + +// StaticAreaIDAsAreaId is a convenience function that returns StaticAreaID wrapped in AreaId +func StaticAreaIDAsAreaId(v *StaticAreaID) AreaId { + return AreaId{ + StaticAreaID: v, + } +} + +// stringAsAreaId is a convenience function that returns string wrapped in AreaId +func StringAsAreaId(v *string) AreaId { + return AreaId{ + String: v, + } +} + +// Unmarshal JSON data into one of the pointers in the struct +func (dst *AreaId) UnmarshalJSON(data []byte) error { + var err error + match := 0 + // try to unmarshal data into StaticAreaID + err = json.Unmarshal(data, &dst.StaticAreaID) + if err == nil { + jsonStaticAreaID, _ := json.Marshal(dst.StaticAreaID) + regex := `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$` + isMatched, _ := regexp.MatchString(regex, string(*dst.StaticAreaID)) + if string(jsonStaticAreaID) != "{}" && isMatched { // empty struct + match++ + } else { + dst.StaticAreaID = nil + } + } else { + dst.StaticAreaID = nil + } + + // try to unmarshal data into String + err = json.Unmarshal(data, &dst.String) + if err == nil { + jsonString, _ := json.Marshal(dst.String) + if string(jsonString) == "{}" { // empty struct + dst.String = nil + } else { + match++ + } + } else { + dst.String = nil + } + + if match > 1 { // more than 1 match + // reset to nil + dst.StaticAreaID = nil + dst.String = nil + + return fmt.Errorf("data matches more than one schema in oneOf(AreaId)") + } else if match == 1 { + return nil // exactly one match + } else { // no match + return fmt.Errorf("data failed to match schemas in oneOf(AreaId)") + } +} + +// Marshal data from the first non-nil pointers in the struct to JSON +func (src AreaId) MarshalJSON() ([]byte, error) { + if src.StaticAreaID != nil { + return json.Marshal(&src.StaticAreaID) + } + + if src.String != nil { + return json.Marshal(&src.String) + } + + return nil, nil // no data in oneOf schemas +} + +// Get the actual instance +func (obj *AreaId) GetActualInstance() interface{} { + if obj == nil { + return nil + } + if obj.StaticAreaID != nil { + return obj.StaticAreaID + } + + if obj.String != nil { + return obj.String + } + + // all schemas are nil + return nil +} + +// Get the actual instance value +func (obj AreaId) GetActualInstanceValue() interface{} { + if obj.StaticAreaID != nil { + return *obj.StaticAreaID + } + + if obj.String != nil { + return *obj.String + } + + // all schemas are nil + return nil +} + +type NullableAreaId struct { + value *AreaId + isSet bool +} + +func (v NullableAreaId) Get() *AreaId { + return v.value +} + +func (v *NullableAreaId) Set(val *AreaId) { + v.value = val + v.isSet = true +} + +func (v NullableAreaId) IsSet() bool { + return v.isSet +} + +func (v *NullableAreaId) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableAreaId(val *AreaId) *NullableAreaId { + return &NullableAreaId{value: val, isSet: true} +} + +func (v NullableAreaId) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableAreaId) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/scripts/generate-sdk/languages/go.sh b/scripts/generate-sdk/languages/go.sh index 87036fd..638c42b 100644 --- a/scripts/generate-sdk/languages/go.sh +++ b/scripts/generate-sdk/languages/go.sh @@ -111,7 +111,8 @@ generate_go_sdk() { cd ${ROOT_DIR} mkdir -p custom/cloud/stackit/codegen javac -cp "${GENERATOR_JAR_PATH}" CustomRegionGenerator.java - mv CustomRegionGenerator.class custom/cloud/stackit/codegen/CustomRegionGenerator.class + mv ./*.class custom/cloud/stackit/codegen + cp languages/golang/overrides/* custom/cloud/stackit/codegen warning="" From a9a6f6b322fd7a2de44fb5f39bd8aba5fba498c4 Mon Sep 17 00:00:00 2001 From: Carlo Goetz Date: Thu, 25 Jun 2026 10:14:44 +0200 Subject: [PATCH 3/3] fix(ci): bump java version --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d16065e..198afeb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,7 +4,7 @@ on: [pull_request, workflow_dispatch] env: GO_VERSION_BUILD: "1.25" - JAVA_VERSION: "11" + JAVA_VERSION: "25" jobs: main-go: