diff --git a/bootcfg/http/ignition.go b/bootcfg/http/ignition.go index ab9af261..28a9047f 100644 --- a/bootcfg/http/ignition.go +++ b/bootcfg/http/ignition.go @@ -87,8 +87,14 @@ func ignitionHandler(srv server.Server) ContextHandler { // Ignition v2 Config struct. func parseToV2(data []byte) (cfg ignitionTypes.Config, err error) { // parse JSON v2 to Ignition - return ignition.ParseFromLatest(data) - // TODO(dghubble) Allow YAML unmarshaling + cfg, err = ignition.ParseFromLatest(data) + if err == nil { + return cfg, nil + } + if majorVersion(data) == 2 { + err = yaml.Unmarshal(data, &cfg) + } + return cfg, err } // parseToV1 parses raw JSON or YAML in Ignition v1 format and returns the @@ -103,3 +109,22 @@ func parseToV1(data []byte) (cfg ignitionV1Types.Config, err error) { err = yaml.Unmarshal(data, &cfg) return cfg, err } + +func majorVersion(data []byte) int64 { + var composite struct { + Version *int `json:"ignitionVersion" yaml:"ignition_version"` + Ignition struct { + Version *string `json:"version" yaml:"version"` + } `json:"ignition" yaml:"ignition"` + } + if yaml.Unmarshal(data, &composite) != nil { + return 0 + } + var major int64 + if composite.Ignition.Version != nil && *composite.Ignition.Version == "2.0.0" { + major = 2 + } else if composite.Version != nil { + major = int64(*composite.Version) + } + return major +} diff --git a/bootcfg/http/ignition_test.go b/bootcfg/http/ignition_test.go index e9063d28..27e8b228 100644 --- a/bootcfg/http/ignition_test.go +++ b/bootcfg/http/ignition_test.go @@ -60,7 +60,37 @@ func TestIgnitionHandler_V1JSON(t *testing.T) { assert.Equal(t, expectedIgnitionV1, w.Body.String()) } -func TestIgnitionHandler_YAMLIgnition(t *testing.T) { +func TestIgnitionHandler_V2YAML(t *testing.T) { + content := ` +ignition: + version: 2.0.0 +systemd: + units: + - name: {{.service_name}}.service + enable: true + - name: {{.uuid}}.service + enable: true +` + store := &fake.FixedStore{ + Profiles: map[string]*storagepb.Profile{fake.Group.Profile: testProfileIgnitionYAML}, + IgnitionConfigs: map[string]string{testProfileIgnitionYAML.IgnitionId: content}, + } + srv := server.NewServer(&server.Config{Store: store}) + h := ignitionHandler(srv) + ctx := withGroup(context.Background(), fake.Group) + w := httptest.NewRecorder() + req, _ := http.NewRequest("GET", "/", nil) + h.ServeHTTP(ctx, w, req) + // assert that: + // - Ignition template is rendered with Group metadata and selectors + // - Rendered Ignition template is parsed as YAML + // - Ignition Config served as JSON + assert.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, jsonContentType, w.HeaderMap.Get(contentType)) + assert.Equal(t, expectedIgnitionV2, w.Body.String()) +} + +func TestIgnitionHandler_V1YAML(t *testing.T) { content := ` ignition_version: 1 systemd: @@ -82,7 +112,7 @@ systemd: h.ServeHTTP(ctx, w, req) // assert that: // - Ignition template is rendered with Group metadata and selectors - // - Rendered Ignition template ending in .yaml is parsed as YAML + // - Rendered Ignition template is parsed as YAML // - Ignition Config served as JSON assert.Equal(t, http.StatusOK, w.Code) assert.Equal(t, jsonContentType, w.HeaderMap.Get(contentType)) diff --git a/examples/ignition/ssh.yaml b/examples/ignition/ssh.yaml index 08b80367..1bac8cca 100644 --- a/examples/ignition/ssh.yaml +++ b/examples/ignition/ssh.yaml @@ -1,5 +1,6 @@ --- -ignition_version: 1 +ignition: + version: 2.0.0 {{ if .ssh_authorized_keys }} passwd: users: