1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 06:46:36 +01:00

*: Drop the Tectonic license

Red Hat no longer requires a Tectonic license now that this installer
is being used to launch OpenShift clusters.
This commit is contained in:
W. Trevor King
2018-08-01 09:47:44 -07:00
parent 4a32f5298b
commit 1489bf5557
28 changed files with 14 additions and 248 deletions

1
.gitignore vendored
View File

@@ -9,7 +9,6 @@ id_rsa*
pull-secret.json
ssh-key.pem
tectonic-*.tar.gz
tectonic-license.txt
config.yaml
bin/

View File

@@ -53,9 +53,6 @@ type InstallConfig struct {
// perform the installation.
Platform `json:"platform"`
// License is an OpenShift license needed to install a cluster.
License string `json:"license"`
// PullSecret is the secret to use when pulling images.
PullSecret string `json:"pullSecret"`
}

View File

@@ -18,7 +18,6 @@ strict digraph resource {
node [shape=rectangle,style=filled,color=gainsboro];
base_domain [label="base domain"];
cluster_name [label="cluster name"];
license [label="license"];
pull_secret [label="pull secret"];
platform [label="platform"];
email_address [label="email address"];
@@ -93,7 +92,6 @@ strict digraph resource {
platform -> install_config;
email_address -> install_config;
pull_secret -> install_config;
license -> install_config;
cluster_name -> install_config;
base_domain -> install_config;

View File

@@ -40,8 +40,8 @@ Because of the greater disk requirements of OpenShift, you'll need to expand the
qemu-img resize coreos_production_qemu_image.img +8G
```
#### 1.4 Get a Tectonic License
Go to https://account.coreos.com/ and obtain a Tectonic license. Save the *pull secret* and *license path* somewhere.
#### 1.4 Get a pull secret
Go to https://account.coreos.com/ and obtain a Tectonic *pull secret*.
#### 1.5 Make sure you have permisions for `qemu:///system`
You may want to grant yourself permissions to use libvirt as a non-root user. You could allow all users in the wheel group by doing the following:
@@ -62,7 +62,6 @@ EOF
1. Set a `baseDomain` (to `tt.testing`)
1. Set the `sshKey` in the `admin` section to the **contents** of an ssh key (e.g. `ssh-rsa AAAA...`)
1. Set the `imagePath` to the **absolute** path of the operating system image you downloaded
1. Set the `licensePath` to the **absolute** path of your downloaded license file.
1. Set the `name` (e.g. test1)
1. Look at the `podCIDR` and `serviceCIDR` fields in the `networking` section. Make sure they don't conflict with anything important.
1. Set the `pullSecretPath` to the **absolute** path of your downloaded pull secret file.

1
Jenkinsfile vendored
View File

@@ -1,7 +1,6 @@
#!/usr/bin/env groovy
commonCreds = [
file(credentialsId: 'tectonic-license', variable: 'LICENSE_PATH'),
file(credentialsId: 'tectonic-pull', variable: 'PULL_SECRET_PATH'),
[
$class: 'StringBinding',

View File

@@ -192,18 +192,6 @@ You can download the pull secret from your Account overview page at [3].
EOF
}
variable "tectonic_license_path" {
type = "string"
default = ""
description = <<EOF
The path to the tectonic licence file.
You can download the Tectonic license file from your Account overview page at [1].
[1] https://account.coreos.com/overview
EOF
}
variable "tectonic_container_linux_channel" {
type = "string"

View File

@@ -182,12 +182,6 @@ iscsi:
# (optional) Start iscsid.service to enable iscsi volume attachment.
# enabled: false
# The path to the tectonic licence file.
# You can download the Tectonic license file from your Account overview page at [1].
#
# [1] https://account.coreos.com/overview
licensePath:
master:
# The name of the node pool(s) to use for master nodes
nodePools:

View File

@@ -51,12 +51,6 @@ iscsi:
# (optional) Start iscsid.service to enable iscsi volume attachment.
# enabled: false
# The path to the tectonic licence file.
# You can download the Tectonic license file from your Account overview page at [1].
#
# [1] https://account.coreos.com/overview
licensePath:
master:
nodePools:
- master

View File

@@ -13,7 +13,6 @@ worker:
nodePools:
- worker
pullSecretPath: /path/config.json
licensePath: /path/tectonic-license.txt
containerLinux:
channel: stable
version: latest

View File

@@ -83,7 +83,6 @@ type Cluster struct {
IgnitionWorker string `json:"tectonic_ignition_worker,omitempty" yaml:"-"`
Internal `json:",inline" yaml:"-"`
libvirt.Libvirt `json:",inline" yaml:"libvirt,omitempty"`
LicensePath string `json:"tectonic_license_path,omitempty" yaml:"licensePath,omitempty"`
Master `json:",inline" yaml:"master,omitempty"`
Name string `json:"tectonic_cluster_name,omitempty" yaml:"name,omitempty"`
Networking `json:",inline" yaml:"networking,omitempty"`

View File

@@ -285,9 +285,6 @@ func (c *Cluster) validateTectonicFiles() []error {
if err := validate.JSONFile(c.PullSecretPath); err != nil {
errs = append(errs, err)
}
if err := validate.License(c.LicensePath); err != nil {
errs = append(errs, err)
}
return errs
}

View File

@@ -13,10 +13,7 @@ import (
"regexp"
"strconv"
"strings"
"time"
"unicode/utf8"
"github.com/dgrijalva/jwt-go"
)
func isMatch(re string, v string) bool {
@@ -50,25 +47,6 @@ func FileExists(path string) error {
return err
}
// License validates that the file at the given path is a valid license.
func License(path string) error {
licenseBytes, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("cannot read license file at %q: %v", path, err)
}
c := struct {
ExpirationDate time.Time `json:"expirationDate"`
jwt.StandardClaims
}{}
if _, _, err := (&jwt.Parser{}).ParseUnverified(string(licenseBytes), &c); err != nil {
return fmt.Errorf("invalid JWT in license: %v; %q", err, string(licenseBytes))
}
if time.Now().After(c.ExpirationDate) {
return fmt.Errorf("expired license %v", c.ExpirationDate)
}
return nil
}
// NonEmpty checks if the given string contains at least one non-whitespace character and returns an error if not.
func NonEmpty(v string) error {
if utf8.RuneCountInString(strings.TrimSpace(v)) == 0 {

View File

@@ -1,22 +1,16 @@
package validate
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"fmt"
"io/ioutil"
"net"
"os"
"strings"
"testing"
"time"
"github.com/openshift/installer/pkg/asset/tls"
jose "gopkg.in/square/go-jose.v2"
)
const caseMsg = "must be lower case"
@@ -660,83 +654,6 @@ func TestFileExists(t *testing.T) {
}
}
func generateLicense(name string, expiration time.Time) (*os.File, error) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, fmt.Errorf("failed to create RSA key pair: %v", err)
}
s, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.RS256, Key: key}, nil)
if err != nil {
return nil, fmt.Errorf("failed to create license signer: %v", err)
}
buf, err := json.Marshal(struct {
ExpirationDate time.Time `json:"expirationDate"`
}{expiration})
if err != nil {
return nil, fmt.Errorf("failed to marshal license: %v", err)
}
jws, err := s.Sign(buf)
if err != nil {
return nil, fmt.Errorf("failed to sign license: %v", err)
}
l, err := jws.CompactSerialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize license: %v", err)
}
f, err := ioutil.TempFile("", name)
if err != nil {
return nil, fmt.Errorf("failed to create valid license file: %v", err)
}
if _, err := f.WriteString(l); err != nil {
return nil, fmt.Errorf("failed to write valid license file: %v", err)
}
f.Close()
return f, nil
}
func TestLicense(t *testing.T) {
vFile, err := generateLicense("valid", time.Now().AddDate(1, 0, 0))
if err != nil {
t.Fatalf("failed to generate valid license: %v", err)
}
defer os.Remove(vFile.Name())
iFile, err := generateLicense("invalid", time.Now().AddDate(-1, 0, 0))
if err != nil {
t.Fatalf("failed to generate invalid license: %v", err)
}
defer os.Remove(iFile.Name())
cases := []struct {
path string
err bool
}{
{
path: "./fixtures/doesnotexist",
err: true,
},
{
path: "./fixtures/exists",
err: true,
},
{
path: iFile.Name(),
err: true,
},
{
path: vFile.Name(),
err: false,
},
}
for i, c := range cases {
if err := License(c.path); (err != nil) != c.err {
no := "no"
if c.err {
no = "an"
}
t.Errorf("test case %d: expected %s error, got %v", i, no, err)
}
}
}
func TestFileHeader(t *testing.T) {
cases := []struct {
actual []byte

View File

@@ -17,7 +17,6 @@ aws:
baseDomain: tectonic-ci.de
containerLinux:
channel: beta
licensePath:
master:
nodePools:
- master

View File

@@ -1,8 +1,6 @@
package workflow
import (
"crypto/rand"
"crypto/rsa"
"encoding/json"
"errors"
"fmt"
@@ -11,68 +9,33 @@ import (
"path/filepath"
"regexp"
"testing"
"time"
jose "gopkg.in/square/go-jose.v2"
"github.com/openshift/installer/installer/pkg/config"
)
func generatePullSecretAndLicense(name string, expiration time.Time) (*os.File, *os.File, error) {
func generatePullSecret(name string) (*os.File, error) {
pullBytes, err := json.Marshal(&struct{}{})
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal pull secret: %v", err)
return nil, fmt.Errorf("failed to marshal pull secret: %v", err)
}
p, err := ioutil.TempFile("", fmt.Sprintf("%s_pull_secret", name))
if err != nil {
return nil, nil, fmt.Errorf("failed to create pull secret file: %v", err)
return nil, fmt.Errorf("failed to create pull secret file: %v", err)
}
if _, err := p.Write(pullBytes); err != nil {
return nil, nil, fmt.Errorf("failed to write pull secret file: %v", err)
return nil, fmt.Errorf("failed to write pull secret file: %v", err)
}
p.Close()
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, nil, fmt.Errorf("failed to create RSA key pair: %v", err)
}
s, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.RS256, Key: key}, nil)
if err != nil {
return nil, nil, fmt.Errorf("failed to create license signer: %v", err)
}
buf, err := json.Marshal(struct {
ExpirationDate time.Time `json:"expirationDate"`
}{expiration})
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal license: %v", err)
}
jws, err := s.Sign(buf)
if err != nil {
return nil, nil, fmt.Errorf("failed to sign license: %v", err)
}
license, err := jws.CompactSerialize()
if err != nil {
return nil, nil, fmt.Errorf("failed to serialize license: %v", err)
}
l, err := ioutil.TempFile("", fmt.Sprintf("%s_license", name))
if err != nil {
return nil, nil, fmt.Errorf("failed to create license file: %v", err)
}
if _, err := l.WriteString(license); err != nil {
return nil, nil, fmt.Errorf("failed to write license file: %v", err)
}
l.Close()
return p, l, nil
return p, nil
}
func initTestCluster(cfg, pullSecret, license string) (*config.Cluster, error) {
func initTestCluster(cfg, pullSecret string) (*config.Cluster, error) {
testConfig, err := config.ParseConfigFile(cfg)
if err != nil {
return nil, fmt.Errorf("failed to parse test config: %v", err)
}
testConfig.PullSecretPath = pullSecret
testConfig.LicensePath = license
if len(testConfig.Validate()) != 0 {
return nil, errors.New("failed to validate test conifg")
}
@@ -91,20 +54,18 @@ func TestGenerateTerraformVariablesStep(t *testing.T) {
}
}()
ps, lic, err := generatePullSecretAndLicense("init_workflow", time.Now().AddDate(1, 0, 0))
ps, err := generatePullSecret("init_workflow")
if err != nil {
t.Fatalf("failed to generate pull secret and license: %v", err)
t.Fatalf("failed to generate pull secret: %v", err)
}
defer os.Remove(ps.Name())
defer os.Remove(lic.Name())
cluster, err := initTestCluster("./fixtures/aws.basic.yaml", ps.Name(), lic.Name())
cluster, err := initTestCluster("./fixtures/aws.basic.yaml", ps.Name())
if err != nil {
t.Fatalf("failed to init cluster: %v", err)
}
// Remove auto-generated license and pull secret for comparison.
cluster.LicensePath = ""
// Remove auto-generated pull secret for comparison.
cluster.PullSecretPath = ""
m := &metadata{

View File

@@ -13,7 +13,6 @@ variable "manifest_names" {
"rbac/role-user.yaml",
"secrets/ca-cert.yaml",
"secrets/ingress-tls.yaml",
"secrets/license.json",
"secrets/pull.json",
"security/priviledged-scc-tectonic.yaml",
"updater/app-version-kind.yaml",
@@ -57,7 +56,6 @@ data "template_file" "manifest_file_list" {
tectonic_version = "${var.versions["tectonic"]}"
tectonic_alm_operator_version = "${var.versions["alm"]}"
license = "${base64encode(file(var.license_path))}"
pull_secret = "${base64encode(file(var.pull_secret_path))}"
update_server = "${var.update_server}"

View File

@@ -1,11 +0,0 @@
{
"apiVersion": "v1",
"kind": "Secret",
"metadata": {
"namespace": "tectonic-system",
"name": "tectonic-license-secret"
},
"data": {
"license": "${license}"
}
}

View File

@@ -142,7 +142,6 @@ kubectl create -f ingress/cluster-config.yaml
echo "Creating Tectonic Secrets"
kubectl create -f secrets/pull.json
kubectl create -f secrets/license.json
kubectl create -f secrets/ingress-tls.yaml
kubectl create -f secrets/ca-cert.yaml
kubectl create -f ingress/pull.json

View File

@@ -23,12 +23,6 @@ variable "ingress_kind" {
type = "string"
}
variable "license_path" {
description = "Path on disk to your Tectonic license. Obtain this from your Tectonic Account: https://account.coreos.com."
type = "string"
default = "/Users/coreos/Desktop/tectonic-license.txt"
}
variable "pull_secret_path" {
type = "string"
description = "Path on disk to your Tectonic pull secret. Obtain this from your Tectonic Account: https://account.coreos.com."

View File

@@ -30,7 +30,6 @@ func (a *installConfig) Dependencies() []asset.Asset {
a.assetStock.SSHKey(),
a.assetStock.BaseDomain(),
a.assetStock.ClusterName(),
a.assetStock.License(),
a.assetStock.PullSecret(),
a.assetStock.Platform(),
}
@@ -44,7 +43,6 @@ func (a *installConfig) Generate(dependencies map[asset.Asset]*asset.State) (*as
sshKey := string(dependencies[a.assetStock.SSHKey()].Contents[0].Data)
baseDomain := string(dependencies[a.assetStock.BaseDomain()].Contents[0].Data)
clusterName := string(dependencies[a.assetStock.ClusterName()].Contents[0].Data)
license := string(dependencies[a.assetStock.License()].Contents[0].Data)
pullSecret := string(dependencies[a.assetStock.PullSecret()].Contents[0].Data)
installConfig := types.InstallConfig{
@@ -58,7 +56,6 @@ func (a *installConfig) Generate(dependencies map[asset.Asset]*asset.State) (*as
SSHKey: sshKey,
},
BaseDomain: baseDomain,
License: license,
PullSecret: pullSecret,
}

View File

@@ -32,7 +32,6 @@ func TestInstallConfigDependencies(t *testing.T) {
sshKey: &testAsset{name: "test-sshkey"},
baseDomain: &testAsset{name: "test-domain"},
clusterName: &testAsset{name: "test-cluster"},
license: &testAsset{name: "test-license"},
pullSecret: &testAsset{name: "test-pull-secret"},
platform: &testAsset{name: "test-platform"},
}
@@ -46,7 +45,6 @@ func TestInstallConfigDependencies(t *testing.T) {
"test-sshkey",
"test-domain",
"test-cluster",
"test-license",
"test-pull-secret",
"test-platform",
}
@@ -102,7 +100,6 @@ func TestInstallConfigGenerate(t *testing.T) {
sshKey: &testAsset{},
baseDomain: &testAsset{},
clusterName: &testAsset{},
license: &testAsset{},
pullSecret: &testAsset{},
platform: &testAsset{},
}
@@ -137,9 +134,6 @@ func TestInstallConfigGenerate(t *testing.T) {
stock.clusterName: {
Contents: []asset.Content{{Data: []byte("test-cluster-name")}},
},
stock.license: {
Contents: []asset.Content{{Data: []byte("test-license")}},
},
stock.pullSecret: {
Contents: []asset.Content{{Data: []byte("test-pull-secret")}},
},
@@ -167,7 +161,6 @@ func TestInstallConfigGenerate(t *testing.T) {
sshKey: test-sshkey
baseDomain: test-domain
clusterID: test-cluster-id
license: test-license
machines: null
metadata:
creationTimestamp: null

View File

@@ -23,8 +23,6 @@ type Stock interface {
BaseDomain() asset.Asset
// ClusterName is the asset that queries the user for the name of the cluster.
ClusterName() asset.Asset
// License is the asset that queries the user for the OpenShift license.
License() asset.Asset
// PullSecret is the asset that queries the user for the pull secret.
PullSecret() asset.Asset
// Platform is the asset that queries the user for the platform on which
@@ -41,7 +39,6 @@ type StockImpl struct {
sshKey asset.Asset
baseDomain asset.Asset
clusterName asset.Asset
license asset.Asset
pullSecret asset.Asset
platform asset.Asset
}
@@ -73,10 +70,6 @@ func (s *StockImpl) EstablishStock(directory string, inputReader *bufio.Reader)
Prompt: "Cluster Name:",
InputReader: inputReader,
}
s.license = &asset.UserProvided{
Prompt: "License:",
InputReader: inputReader,
}
s.pullSecret = &asset.UserProvided{
Prompt: "Pull Secret:",
InputReader: inputReader,
@@ -120,11 +113,6 @@ func (s *StockImpl) ClusterName() asset.Asset {
return s.clusterName
}
// License is the asset that queries the user for the OpenShift license.
func (s *StockImpl) License() asset.Asset {
return s.license
}
// PullSecret is the asset that queries the user for the pull secret.
func (s *StockImpl) PullSecret() asset.Asset {
return s.pullSecret

View File

@@ -32,9 +32,6 @@ type InstallConfig struct {
// perform the installation.
Platform `json:"platform"`
// License is an OpenShift license needed to install a cluster.
License string `json:"license"`
// PullSecret is the secret to use when pulling images.
PullSecret string `json:"pullSecret"`
}

View File

@@ -16,7 +16,6 @@ module assets_base {
tectonic_container_linux_version = "${var.tectonic_container_linux_version}"
tectonic_image_re = "${var.tectonic_image_re}"
tectonic_kubelet_debug_config = "${var.tectonic_kubelet_debug_config}"
tectonic_license_path = "${var.tectonic_license_path}"
tectonic_networking = "${var.tectonic_networking}"
tectonic_platform = "${var.tectonic_platform}"
tectonic_pull_secret_path = "${var.tectonic_pull_secret_path}"

View File

@@ -62,7 +62,6 @@ module "tectonic" {
container_base_images = "${var.tectonic_container_base_images}"
versions = "${var.tectonic_versions}"
license_path = "${pathexpand(var.tectonic_license_path)}"
pull_secret_path = "${pathexpand(var.tectonic_pull_secret_path)}"
update_channel = "${var.tectonic_update_channel}"

View File

@@ -16,7 +16,6 @@ module assets_base {
tectonic_container_linux_version = "${var.tectonic_container_linux_version}"
tectonic_image_re = "${var.tectonic_image_re}"
tectonic_kubelet_debug_config = "${var.tectonic_kubelet_debug_config}"
tectonic_license_path = "${var.tectonic_license_path}"
tectonic_networking = "${var.tectonic_networking}"
tectonic_platform = "${var.tectonic_platform}"
tectonic_pull_secret_path = "${var.tectonic_pull_secret_path}"

View File

@@ -65,7 +65,6 @@ environment variables:
``` bash
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
LICENSE_PATH
PULL_SECRET_PATH
```

View File

@@ -4,14 +4,12 @@
set -e
# This should be executed from top-level directory not from `tests` directory
# Script needs two variables to be set before execution
# 1) LICENSE_PATH - path to tectonic license file
# 2) PULL_SECRET_PATH - path to pull secret file
# Script needs one variable to be set before execution
# 1) PULL_SECRET_PATH - path to pull secret file
set -eo pipefail
SMOKE_TEST_OUTPUT="Never executed. Problem with one of previous stages"
[ -z ${LICENSE_PATH+x} ] && (echo "Please set LICENSE_PATH"; exit 1)
[ -z ${PULL_SECRET_PATH+x} ] && (echo "Please set PULL_SECRET_PATH"; exit 1)
[ -z ${DOMAIN+x} ] && DOMAIN="tectonic-ci.de"
[ -z ${AWS_REGION+x} ] && AWS_REGION="eu-west-1"
@@ -50,7 +48,6 @@ python <<-EOF >"${CLUSTER_NAME}.yaml"
config = yaml.load(f)
config['name'] = '${CLUSTER_NAME}'
config['baseDomain'] = '${DOMAIN}'
config['licensePath'] = '${LICENSE_PATH}'
config['pullSecretPath'] = '${PULL_SECRET_PATH}'
config['aws']['region'] = '${AWS_REGION}'
config['aws']['master']['iamRoleName'] = 'tf-tectonic-master-node'