summaryrefslogtreecommitdiffstats
path: root/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
blob: c6cfa8288f49d80671243d18a78d9e07f95c1eff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;

import com.yahoo.config.provisioning.FlavorsConfig;

import java.util.Objects;

/**
 * A host or node flavor.
 * *Host* flavors come from a configured set which corresponds to the actual flavors available in a zone.
 * *Node* flavors are simply a wrapper of a NodeResources object.
 *
 * @author bratseth
 */
public class Flavor {

    private boolean configured;
    private final String name;
    private final int cost;
    private final Type type;
    private final double bandwidth;

    /** The hardware resources of this flavor */
    private NodeResources resources;

    /** Creates a *host* flavor from configuration */
    public Flavor(FlavorsConfig.Flavor flavorConfig) {
        this.configured = true;
        this.name = flavorConfig.name();
        this.cost = flavorConfig.cost();
        this.type = Type.valueOf(flavorConfig.environment());
        this.resources = new NodeResources(flavorConfig.minCpuCores(),
                                           flavorConfig.minMainMemoryAvailableGb(),
                                           flavorConfig.minDiskAvailableGb(),
                                           flavorConfig.fastDisk() ? NodeResources.DiskSpeed.fast : NodeResources.DiskSpeed.slow);
        this.bandwidth = flavorConfig.bandwidth();
    }

    /** Creates a *node* flavor from a node resources spec */
    public Flavor(NodeResources resources) {
        Objects.requireNonNull(resources, "Resources cannot be null");
        this.configured = false;
        this.name = resources.toString();
        this.cost = 0;
        this.type = Type.DOCKER_CONTAINER;
        this.bandwidth = 1;
        this.resources = resources;
    }

    /** Returns the unique identity of this flavor if it is configured, or the resource spec string otherwise */
    public String name() { return name; }

    /**
     * Get the monthly cost (total cost of ownership) in USD for this flavor, typically total cost
     * divided by 36 months.
     * 
     * @return monthly cost in USD
     */
    public int cost() { return cost; }
    
    /**
     * True if this is a configured flavor used for hosts,
     * false if it is a virtual flavor created on the fly from node resources
     */
    public boolean isConfigured() { return configured; }

    public NodeResources resources() { return resources; }

    public double getMinMainMemoryAvailableGb() { return resources.memoryGb(); }

    public double getMinDiskAvailableGb() { return resources.diskGb(); }

    public boolean hasFastDisk() { return resources.diskSpeed() == NodeResources.DiskSpeed.fast; }

    public double getBandwidth() { return bandwidth; }

    public double getMinCpuCores() { return resources.vcpu(); }

    public Type getType() { return type; }
    
    /** Convenience, returns getType() == Type.DOCKER_CONTAINER */
    public boolean isDocker() { return type == Type.DOCKER_CONTAINER; }

    // TODO: Remove after August 2019
    public String canonicalName() { return name; }
    
    /**
     * Returns whether this flavor satisfies the requested flavor
     */
    public boolean satisfies(Flavor flavor) {
        return this.equals(flavor);
    }

    @Override
    public int hashCode() { return name.hashCode(); }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if ( ! (o instanceof Flavor)) return false;
        Flavor other = (Flavor)o;
        if (configured)
            return other.name.equals(this.name);
        else
            return this.resources.equals(other.resources);
    }

    @Override
    public String toString() {
        if (isConfigured())
            return "flavor '" + name + "'";
        else
            return name;
    }

    public enum Type {
        undefined, // Default value in config (flavors.def)
        BARE_METAL,
        VIRTUAL_MACHINE,
        DOCKER_CONTAINER
    }

}